无关风月
2026-02-04 6de34445e65d3039133d10839c873f12c6e2501e
白名单管理
3个文件已删除
9个文件已添加
17个文件已修改
1284 ■■■■■ 已修改文件
xp-api/src/main/java/com/xiaopeng/api/model/operation/XpWhitelist.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-service/pom.xml 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-service/xp-operation/src/main/java/com/xiaopeng/operation/controller/XpInvitationCodeController.java 289 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-service/xp-operation/src/main/java/com/xiaopeng/operation/controller/XpWhitelistController.java 394 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-service/xp-operation/src/main/java/com/xiaopeng/operation/controller/XpWhitelistOperlogController.java 84 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-service/xp-operation/src/main/java/com/xiaopeng/operation/dto/WhitelistAddDto.java 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-service/xp-operation/src/main/java/com/xiaopeng/operation/exportExcle/XpInvitationCodeExportExcel.java 34 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-service/xp-operation/src/main/java/com/xiaopeng/operation/exportExcle/XpWhitelistExportExcel.java 56 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-service/xp-operation/src/main/java/com/xiaopeng/operation/exportExcle/XpWhitelistLogExportExcel.java 50 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-service/xp-operation/src/main/java/com/xiaopeng/operation/importExcel/InvitationCodeImportExcel.java 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-service/xp-operation/src/main/java/com/xiaopeng/operation/importExcel/WhitelistImportExcel.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-service/xp-operation/src/main/java/com/xiaopeng/operation/mapper/XpInvitationCodeMapper.java 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-service/xp-operation/src/main/java/com/xiaopeng/operation/mapper/XpWhitelistMapper.java 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-service/xp-operation/src/main/java/com/xiaopeng/operation/mapper/XpWhitelistOperlogMapper.java 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-service/xp-operation/src/main/java/com/xiaopeng/operation/query/InvitationPageListQuery.java 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-service/xp-operation/src/main/java/com/xiaopeng/operation/query/WhitelistLogPageListQuery.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-service/xp-operation/src/main/java/com/xiaopeng/operation/query/WhitelistPageListQuery.java 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-service/xp-operation/src/main/java/com/xiaopeng/operation/service/IXpInvitationCodeService.java 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-service/xp-operation/src/main/java/com/xiaopeng/operation/service/IXpWhitelistOperlogService.java 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-service/xp-operation/src/main/java/com/xiaopeng/operation/service/IXpWhitelistService.java 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-service/xp-operation/src/main/java/com/xiaopeng/operation/service/XpInvitationCodeService.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-service/xp-operation/src/main/java/com/xiaopeng/operation/service/XpWhitelistOperlogService.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-service/xp-operation/src/main/java/com/xiaopeng/operation/service/XpWhitelistService.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-service/xp-operation/src/main/java/com/xiaopeng/operation/service/impl/XpInvitationCodeServiceImpl.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-service/xp-operation/src/main/java/com/xiaopeng/operation/service/impl/XpWhitelistOperlogServiceImpl.java 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-service/xp-operation/src/main/java/com/xiaopeng/operation/service/impl/XpWhitelistServiceImpl.java 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-service/xp-operation/src/main/resources/mapper/operation/XpInvitationCodeMapper.xml 32 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-service/xp-operation/src/main/resources/mapper/operation/XpWhitelistMapper.xml 34 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-service/xp-operation/src/main/resources/mapper/operation/XpWhitelistOperlogMapper.xml 32 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-api/src/main/java/com/xiaopeng/api/model/operation/XpWhitelist.java
@@ -47,6 +47,6 @@
    private Boolean isPriorityDispatch;
    @ApiModelProperty(value = "来源 1=添加 2=邀请码")
    private Integer source;
    private Integer whitelistSource;
}
xp-service/pom.xml
@@ -30,7 +30,22 @@
    </description>
    <dependencies>
        <!-- easypoi -->
        <dependency>
            <groupId>cn.afterturn</groupId>
            <artifactId>easypoi-base</artifactId>
            <version>4.4.0</version>
        </dependency>
        <dependency>
            <groupId>cn.afterturn</groupId>
            <artifactId>easypoi-web</artifactId>
            <version>4.4.0</version>
        </dependency>
        <dependency>
            <groupId>cn.afterturn</groupId>
            <artifactId>easypoi-annotation</artifactId>
            <version>4.4.0</version>
        </dependency>
        <!--lombok-->
        <dependency>
            <groupId>org.projectlombok</groupId>
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();
    }
}
xp-service/xp-operation/src/main/java/com/xiaopeng/operation/controller/XpWhitelistController.java
@@ -1,9 +1,63 @@
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.api.model.operation.XpWhitelistOperlog;
import com.xiaopeng.common.core.constant.TokenConstants;
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.utils.ip.IpUtils;
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.common.security.service.TokenService;
import com.xiaopeng.operation.dto.WhitelistAddDto;
import com.xiaopeng.operation.exportExcle.XpWhitelistExportExcel;
import com.xiaopeng.operation.importExcel.InvitationCodeImportExcel;
import com.xiaopeng.operation.importExcel.WhitelistImportExcel;
import com.xiaopeng.operation.query.InvitationPageListQuery;
import com.xiaopeng.operation.query.WhitelistPageListQuery;
import com.xiaopeng.operation.service.IXpInvitationCodeService;
import com.xiaopeng.operation.service.IXpWhitelistOperlogService;
import com.xiaopeng.operation.service.IXpWhitelistService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
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.stereotype.Controller;
import org.springframework.web.multipart.MultipartFile;
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.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
 * <p>
@@ -13,8 +67,342 @@
 * @author mitao
 * @since 2026-02-03
 */
@Controller
@RequestMapping("/xp-whitelist")
@RequestMapping("/api/v1/whitelist")
@RestController
@Api(tags = "白名单管理")
@Slf4j
public class XpWhitelistController {
    @Resource
    private IXpWhitelistService xpWhitelistService;
    @Resource
    private IXpWhitelistOperlogService xpWhitelistOperlogService;
    @ResponseBody
    private TokenService tokenService;
    @ApiOperation(value = "白名单管理分页列表", response = XpWhitelist.class)
    @PostMapping("/pageList")
    public AjaxResult<PageInfo<XpWhitelist>> pageList(@RequestBody WhitelistPageListQuery query) {
        PageInfo<XpWhitelist> pageList = xpWhitelistService.pageList(query);
        return AjaxResult.ok(pageList);
    }
    /**
     * 新增白名单
     */
    @PostMapping("/add")
    @ResponseBody
    @ApiOperation(value = "新增白名单")
    @Transactional
    public AjaxResult add(@RequestBody WhitelistAddDto dto) {
        if (!StringUtils.hasLength(dto.getAccount())) {
            return AjaxResult.error("请输入账号");
        }
        List<XpWhitelist> addList = new ArrayList<>();
        List<String> accounts = Arrays.asList(dto.getAccount().split(","));
        SysUser sysUser = tokenService.getLoginUser().getSysUser();
        StringBuilder operationContent = new StringBuilder("新增账号:");
        StringBuilder accountBuilder = new StringBuilder();
        for (String account : accounts) {
            XpWhitelist xpWhitelist = new XpWhitelist();
            xpWhitelist.setAccount(account);
            xpWhitelist.setStatus(true);
            xpWhitelist.setIsPriorityDispatch(dto.getIsPriorityDispatch());
            xpWhitelist.setWhitelistSource(1);
            addList.add(xpWhitelist);
            accountBuilder.append("\"").append(account).append("\"").append(",");
        }
        XpWhitelistOperlog xpWhitelistOperlog = new XpWhitelistOperlog();
        xpWhitelistOperlog.setOperationName(sysUser.getNickName());
        xpWhitelistOperlog.setOperationAccount(sysUser.getPhoneNumber());
        xpWhitelistOperlog.setOperationType(1);
        xpWhitelistOperlog.setOperationIp(IpUtils.getIpAddr());
        xpWhitelistOperlog.setOperationAccountId(sysUser.getId());
        StringBuilder content = operationContent.append(accountBuilder.substring(0, accountBuilder.length() - 1));
        xpWhitelistOperlog.setOperationContent(content.toString());
        xpWhitelistOperlogService.save(xpWhitelistOperlog);
        xpWhitelistService.saveBatch(addList);
        return AjaxResult.success();
    }
    /**
     * 编辑白名单
     */
    @PostMapping("/edit")
    @ResponseBody
    @ApiOperation(value = "编辑白名单")
    @Transactional
    public AjaxResult edit(@RequestBody XpWhitelist dto) {
        XpWhitelist whitelist = xpWhitelistService.getById(dto.getId());
        SysUser sysUser = tokenService.getLoginUser().getSysUser();
        StringBuilder operationContent = new StringBuilder("编辑账号:");
        StringBuilder accountBuilder = new StringBuilder();
        if (!whitelist.getAccount().equals(dto.getAccount())) {
            accountBuilder.append("白名单账号" + "\"" + whitelist.getAccount() + "\"" + "为" + "\"" + dto.getAccount() + "\"");
        }
        if (StringUtils.hasLength(whitelist.getNickName()) || StringUtils.hasLength(dto.getNickName())) {
            if (!StringUtils.hasLength(whitelist.getNickName())) {
                if (!whitelist.getNickName().equals(dto.getNickName())) {
                    accountBuilder.append("用户名称" + "\"" + whitelist.getNickName() + "\"" + "为" + "\"" + dto.getNickName() + "\"");
                }
            } else {
                if (!whitelist.getNickName().equals(dto.getNickName())) {
                    accountBuilder.append("用户名称" + "\"" + "为" + "\"" + dto.getNickName() + "\"");
                }
            }
        }
        if (whitelist.getStatus() != dto.getStatus()) {
            accountBuilder.append("状态" + "\"" + (whitelist.getIsPriorityDispatch() ? "正常" : "冻结") + "\"" + "为" + "\"" + (dto.getIsPriorityDispatch() ? "正常" : "冻结") + "\"");
        }
        if (whitelist.getIsPriorityDispatch() != dto.getIsPriorityDispatch()) {
            accountBuilder.append("优先派单" + "\"" + (whitelist.getIsPriorityDispatch() ? "是" : "否") + "\"" + "为" + "\"" + (dto.getIsPriorityDispatch() ? "是" : "否") + "\"");
        }
        XpWhitelistOperlog xpWhitelistOperlog = new XpWhitelistOperlog();
        xpWhitelistOperlog.setOperationName(sysUser.getNickName());
        xpWhitelistOperlog.setOperationAccount(sysUser.getPhoneNumber());
        xpWhitelistOperlog.setOperationType(2);
        xpWhitelistOperlog.setOperationIp(IpUtils.getIpAddr());
        xpWhitelistOperlog.setOperationAccountId(sysUser.getId());
        accountBuilder.append("\"").append(dto.getAccount()).append("\"");
        StringBuilder content = operationContent.append(accountBuilder);
        xpWhitelistOperlog.setOperationContent(content.toString());
        xpWhitelistOperlogService.save(xpWhitelistOperlog);
        whitelist.setNickName(dto.getNickName());
        whitelist.setIsPriorityDispatch(dto.getIsPriorityDispatch());
        whitelist.setAccount(dto.getAccount());
        whitelist.setStatus(dto.getStatus());
        xpWhitelistService.updateById(whitelist);
        return AjaxResult.success();
    }
    /**
     * 冻结解冻
     */
    @GetMapping("/freezeUnfreeze")
    @ResponseBody
    @ApiOperation(value = "冻结解冻")
    @Transactional
    public AjaxResult freezeUnfreeze(@RequestParam("id") Long id) {
        XpWhitelist whitelist = xpWhitelistService.getById(id);
        SysUser sysUser = tokenService.getLoginUser().getSysUser();
        StringBuilder operationContent = new StringBuilder("编辑账号:"+"\""+whitelist.getAccount()+"\"");
        StringBuilder accountBuilder = new StringBuilder();
        accountBuilder.append("状态" + "\"" + (whitelist.getIsPriorityDispatch() ? "正常" : "冻结") + "\"" + "为" + "\"" + (!whitelist.getIsPriorityDispatch() ? "正常" : "冻结") + "\"");
        XpWhitelistOperlog xpWhitelistOperlog = new XpWhitelistOperlog();
        xpWhitelistOperlog.setOperationName(sysUser.getNickName());
        xpWhitelistOperlog.setOperationAccount(sysUser.getPhoneNumber());
        xpWhitelistOperlog.setOperationType(2);
        xpWhitelistOperlog.setOperationIp(IpUtils.getIpAddr());
        xpWhitelistOperlog.setOperationAccountId(sysUser.getId());
        StringBuilder content = operationContent.append(accountBuilder);
        xpWhitelistOperlog.setOperationContent(content.toString());
        xpWhitelistOperlogService.save(xpWhitelistOperlog);
        whitelist.setStatus(!whitelist.getStatus());
        xpWhitelistService.updateById(whitelist);
        return AjaxResult.success();
    }
    /**
     * 批量删除
     */
    @PutMapping("/deleteByIds")
    @ResponseBody
    @ApiOperation(value = "批量删除")
    public AjaxResult deleteByIds(List<Long> ids) {
        List<String> accounts = xpWhitelistService.lambdaQuery().in(XpWhitelist::getId, ids).list()
                .stream().map(XpWhitelist::getAccount).collect(Collectors.toList());
        xpWhitelistService.removeBatchByIds(ids);
        SysUser sysUser = tokenService.getLoginUser().getSysUser();
        StringBuilder operationContent = new StringBuilder("删除账号:");
        StringBuilder accountBuilder = new StringBuilder();
        for (String account : accounts) {
            accountBuilder.append("\"" + account + "\""+",");
        }
        XpWhitelistOperlog xpWhitelistOperlog = new XpWhitelistOperlog();
        xpWhitelistOperlog.setOperationName(sysUser.getNickName());
        xpWhitelistOperlog.setOperationAccount(sysUser.getPhoneNumber());
        xpWhitelistOperlog.setOperationType(3);
        xpWhitelistOperlog.setOperationIp(IpUtils.getIpAddr());
        xpWhitelistOperlog.setOperationAccountId(sysUser.getId());
        StringBuilder content = operationContent.append(accountBuilder.substring(0, accountBuilder.length() - 1));
        xpWhitelistOperlog.setOperationContent(content.toString());
        xpWhitelistOperlogService.save(xpWhitelistOperlog);
        return AjaxResult.success();
    }
    /**
     * 批量冻结
     */
    @PutMapping("/freezeByIds")
    @ResponseBody
    @ApiOperation(value = "批量冻结")
    public AjaxResult freezeByIds(List<Long> ids) {
        List<XpWhitelist> list = xpWhitelistService.lambdaQuery().in(XpWhitelist::getId, ids).list();
        for (XpWhitelist xpWhitelist : list) {
            xpWhitelist.setStatus(false);
        }
        xpWhitelistService.updateBatchById(list);
        SysUser sysUser = tokenService.getLoginUser().getSysUser();
        StringBuilder operationContent = new StringBuilder("共计冻结"+ids+"条数据");
        XpWhitelistOperlog xpWhitelistOperlog = new XpWhitelistOperlog();
        xpWhitelistOperlog.setOperationName(sysUser.getNickName());
        xpWhitelistOperlog.setOperationAccount(sysUser.getPhoneNumber());
        xpWhitelistOperlog.setOperationType(6);
        xpWhitelistOperlog.setOperationIp(IpUtils.getIpAddr());
        xpWhitelistOperlog.setOperationAccountId(sysUser.getId());
        xpWhitelistOperlog.setOperationContent(operationContent.toString());
        xpWhitelistOperlogService.save(xpWhitelistOperlog);
        return AjaxResult.success();
    }
    @ApiOperation(value = "白名单导入模板下载")
    @GetMapping("/import-template")
    public void importTemplate() {
        List<WhitelistImportExcel> whitelistImportExcels = new ArrayList<>();
        WhitelistImportExcel whitelistImportExcel = new WhitelistImportExcel();
        whitelistImportExcels.add(whitelistImportExcel);
        Workbook workbook = ExcelExportUtil.exportExcel(new ExportParams(), WhitelistImportExcel.class, whitelistImportExcels);
        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<WhitelistImportExcel> whitelistImportExcels;
        try {
            inputStream = file.getInputStream();
            whitelistImportExcels = ExcelImportUtil.importExcel(inputStream,
                    WhitelistImportExcel.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(whitelistImportExcels)) {
            throw new ServiceException("白名单数据为空!");
        }
        // 校验手机号白名单是否有重复的
        long count = whitelistImportExcels.stream().map(WhitelistImportExcel::getAccount)
                .distinct().count();
        if (count != whitelistImportExcels.size()) {
            return AjaxResult.error("白名单手机号存在重复!");
        }
        Map<String, Long> codeMap = xpWhitelistService.list().stream()
                .collect(Collectors.toMap(XpWhitelist::getAccount, XpWhitelist::getId));
        JSONObject result = new JSONObject();
        List<XpWhitelist> addList = new ArrayList<>();
        for (WhitelistImportExcel whitelistImportExcel : whitelistImportExcels) {
            Long id = codeMap.get(whitelistImportExcel.getAccount());
            if (id != null) {
                result.append("白名单:[", whitelistImportExcel.getAccount() + "]已存在");
            }
            XpWhitelist xpWhitelist = new XpWhitelist();
            xpWhitelist.setNickName(whitelistImportExcel.getNickName());
            xpWhitelist.setAccount(whitelistImportExcel.getAccount());
            xpWhitelist.setStatus(true);
            xpWhitelist.setIsPriorityDispatch(true);
            xpWhitelist.setWhitelistSource(1);
            addList.add(xpWhitelist);
        }
        if (!result.isEmpty()) {
            return AjaxResult.success(result.toString());
        }
        xpWhitelistService.saveBatch(addList);
        SysUser sysUser = tokenService.getLoginUser().getSysUser();
        StringBuilder operationContent = new StringBuilder("共计导入"+addList.size()+"条数据");
        XpWhitelistOperlog xpWhitelistOperlog = new XpWhitelistOperlog();
        xpWhitelistOperlog.setOperationName(sysUser.getNickName());
        xpWhitelistOperlog.setOperationAccount(sysUser.getPhoneNumber());
        xpWhitelistOperlog.setOperationType(4);
        xpWhitelistOperlog.setOperationIp(IpUtils.getIpAddr());
        xpWhitelistOperlog.setOperationAccountId(sysUser.getId());
        xpWhitelistOperlog.setOperationContent(operationContent.toString());
        xpWhitelistOperlogService.save(xpWhitelistOperlog);
        return AjaxResult.success();
    }
    @ApiOperation(value = "白名单导出")
    @PostMapping(value = "/exportExcel")
    public void exportExcel(@RequestBody WhitelistPageListQuery query) {
        List<XpWhitelist> exportList = xpWhitelistService.exportList(query);
        List<XpWhitelistExportExcel> xpWhitelistExportExcels = new ArrayList<>();
        for (XpWhitelist xpWhitelist : exportList) {
            XpWhitelistExportExcel xpWhitelistExportExcel = new XpWhitelistExportExcel();
            xpWhitelistExportExcel.setId(xpWhitelist.getId());
            xpWhitelistExportExcel.setAccount(xpWhitelist.getAccount());
            xpWhitelistExportExcel.setNickName(xpWhitelist.getNickName());
            xpWhitelistExportExcel.setStatus(xpWhitelist.getStatus());
            xpWhitelistExportExcel.setIsPriorityDispatch(xpWhitelist.getIsPriorityDispatch());
            xpWhitelistExportExcel.setCreateBy(xpWhitelist.getCreateBy());
            LocalDateTime createTime = xpWhitelist.getCreateTime();
            // 将LocalDateTime转化为yyyy-MM-dd HH:mm:ss格式字符串
            xpWhitelistExportExcel.setCreateTime(createTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
            xpWhitelistExportExcels.add(xpWhitelistExportExcel);
        }
        SysUser sysUser = tokenService.getLoginUser().getSysUser();
        StringBuilder operationContent = new StringBuilder("共计导出"+exportList.size()+"条数据");
        XpWhitelistOperlog xpWhitelistOperlog = new XpWhitelistOperlog();
        xpWhitelistOperlog.setOperationName(sysUser.getNickName());
        xpWhitelistOperlog.setOperationAccount(sysUser.getPhoneNumber());
        xpWhitelistOperlog.setOperationType(5);
        xpWhitelistOperlog.setOperationIp(IpUtils.getIpAddr());
        xpWhitelistOperlog.setOperationAccountId(sysUser.getId());
        xpWhitelistOperlog.setOperationContent(operationContent.toString());
        xpWhitelistOperlogService.save(xpWhitelistOperlog);
        //1.获取excel模板
        Workbook workbook = ExcelExportUtil.exportExcel(new ExportParams(), XpWhitelistExportExcel.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();
            }
        }
    }
}
xp-service/xp-operation/src/main/java/com/xiaopeng/operation/controller/XpWhitelistOperlogController.java
@@ -1,9 +1,39 @@
package com.xiaopeng.operation.controller;
import cn.afterturn.easypoi.excel.ExcelExportUtil;
import cn.afterturn.easypoi.excel.entity.ExportParams;
import com.xiaopeng.api.model.operation.XpWhitelist;
import com.xiaopeng.api.model.operation.XpWhitelistOperlog;
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.operation.exportExcle.XpWhitelistExportExcel;
import com.xiaopeng.operation.exportExcle.XpWhitelistLogExportExcel;
import com.xiaopeng.operation.query.WhitelistLogPageListQuery;
import com.xiaopeng.operation.query.WhitelistPageListQuery;
import com.xiaopeng.operation.service.IXpWhitelistOperlogService;
import com.xiaopeng.operation.service.IXpWhitelistService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URLEncoder;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
/**
 * <p>
@@ -13,8 +43,58 @@
 * @author mitao
 * @since 2026-02-03
 */
@Controller
@RequestMapping("/xp-whitelist-operlog")
@RequestMapping("/api/v1/whitelistLog")
@RestController
@Api(tags = "白名单管理")
@Slf4j
public class XpWhitelistOperlogController {
    @Resource
    private IXpWhitelistOperlogService xpWhitelistOperlogService;
    @ApiOperation(value = "白名单管理分页列表",response = XpWhitelist.class)
    @PostMapping("/pageList")
    public AjaxResult<PageInfo<XpWhitelistOperlog>> pageList(@RequestBody WhitelistLogPageListQuery query) {
        PageInfo<XpWhitelistOperlog> pageList = xpWhitelistOperlogService.pageList(query);
        return AjaxResult.ok(pageList);
    }
    @ApiOperation(value = "白名单日志导出")
    @PostMapping(value = "/exportExcel")
    public void exportExcel(@RequestBody WhitelistLogPageListQuery query) {
        List<XpWhitelistOperlog> list = xpWhitelistOperlogService.exportList(query);
        List<XpWhitelistLogExportExcel> xpWhitelistLogExportExcels = new ArrayList<>();
        for (XpWhitelistOperlog xpWhitelistOperlog : list) {
            XpWhitelistLogExportExcel xpWhitelistExportExcel = new XpWhitelistLogExportExcel();
            xpWhitelistExportExcel.setId(xpWhitelistOperlog.getId());
            xpWhitelistExportExcel.setOperationAccount(xpWhitelistOperlog.getOperationAccount());
            xpWhitelistExportExcel.setOperationName(xpWhitelistOperlog.getOperationName());
            xpWhitelistExportExcel.setOperationContent(xpWhitelistOperlog.getOperationContent());
            xpWhitelistExportExcel.setOperationIp(xpWhitelistOperlog.getOperationIp());
            xpWhitelistExportExcel.setOperationType(xpWhitelistOperlog.getOperationType());
            LocalDateTime createTime = xpWhitelistOperlog.getCreateTime();
            // 将LocalDateTime转化为yyyy-MM-dd HH:mm:ss格式字符串
            xpWhitelistExportExcel.setCreateTime(createTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
            xpWhitelistLogExportExcels.add(xpWhitelistExportExcel);
        }
        //1.获取excel模板
        Workbook workbook = ExcelExportUtil.exportExcel(new ExportParams(), XpWhitelistLogExportExcel.class, xpWhitelistLogExportExcels);
        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();
            }
        }
    }
}
xp-service/xp-operation/src/main/java/com/xiaopeng/operation/dto/WhitelistAddDto.java
New file
@@ -0,0 +1,18 @@
package com.xiaopeng.operation.dto;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.validation.constraints.NotNull;
@Data
@ApiModel(value = "白名单新增DTO")
public class WhitelistAddDto {
    @ApiModelProperty(value = "账号 多个逗号隔开")
    private String account;
    @ApiModelProperty(value = "优先派单 1=是 0=否")
    private Boolean isPriorityDispatch;
}
xp-service/xp-operation/src/main/java/com/xiaopeng/operation/exportExcle/XpInvitationCodeExportExcel.java
New file
@@ -0,0 +1,34 @@
package com.xiaopeng.operation.exportExcle;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
/**
 * <p>
 * 邀请码导出
 * </p>
 *
 * @author mitao
 * @since 2026-02-03
 */
@Data
@ApiModel(value="邀请码导出")
public class XpInvitationCodeExportExcel {
    @ApiModelProperty(value = "序号")
    @cn.afterturn.easypoi.excel.annotation.Excel(name = "序号",width = 20)
    private Long id;
    @ApiModelProperty(value = "邀请码")
    @cn.afterturn.easypoi.excel.annotation.Excel(name = "用户名称",width = 20)
    private String invitationCode;
    @ApiModelProperty(value = "绑定账号")
    @cn.afterturn.easypoi.excel.annotation.Excel(name = "绑定账号",width = 20)
    private String bind_account;
    @ApiModelProperty(value = "创建时间,前端忽略")
    @cn.afterturn.easypoi.excel.annotation.Excel(name = "创建时间",width = 30)
    private String createTime;
    @ApiModelProperty(value = "创建时间,前端忽略")
    @cn.afterturn.easypoi.excel.annotation.Excel(name = "绑定时间",width = 30)
    private String bindTime;
}
xp-service/xp-operation/src/main/java/com/xiaopeng/operation/exportExcle/XpWhitelistExportExcel.java
New file
@@ -0,0 +1,56 @@
package com.xiaopeng.operation.exportExcle;
import com.xiaopeng.common.core.annotation.Excel;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
/**
 * <p>
 * 白名单导出
 * </p>
 *
 * @author mitao
 * @since 2026-02-03
 */
@Data
@ApiModel(value="白名单导出")
public class XpWhitelistExportExcel {
    @ApiModelProperty(value = "序号")
    @cn.afterturn.easypoi.excel.annotation.Excel(name = "序号",width = 20)
    private Long id;
    @ApiModelProperty(value = "用户名称")
    @cn.afterturn.easypoi.excel.annotation.Excel(name = "用户名称",width = 20)
    private String nickName;
    @ApiModelProperty(value = "白名单账号")
    @cn.afterturn.easypoi.excel.annotation.Excel(name = "白名单账号",width = 20)
    private String account;
    @ApiModelProperty(value = "状态 0=冻结 1=正常")
    @cn.afterturn.easypoi.excel.annotation.Excel(name = "状态",width = 20,replace = {"true_正常","false_冻结"})
    private Boolean status;
    @ApiModelProperty(value = "优先派单 1=是 0=否")
    @cn.afterturn.easypoi.excel.annotation.Excel(name = "优先派单",width = 20,replace = {"true_是","false_否"})
    private Boolean isPriorityDispatch;
    @ApiModelProperty(value = "记录创建人,前端忽略")
    @cn.afterturn.easypoi.excel.annotation.Excel(name = "创建人",width = 20)
    private String createBy;
    @ApiModelProperty(value = "记录创建时间,前端忽略")
    @cn.afterturn.easypoi.excel.annotation.Excel(name = "创建时间",width = 30)
    private String createTime;
}
xp-service/xp-operation/src/main/java/com/xiaopeng/operation/exportExcle/XpWhitelistLogExportExcel.java
New file
@@ -0,0 +1,50 @@
package com.xiaopeng.operation.exportExcle;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
/**
 * <p>
 * 白名单日志导出
 * </p>
 *
 * @author mitao
 * @since 2026-02-03
 */
@Data
@ApiModel(value="白名单日志导出")
public class XpWhitelistLogExportExcel {
    @ApiModelProperty(value = "序号")
    @cn.afterturn.easypoi.excel.annotation.Excel(name = "序号",width = 20)
    private Long id;
    @ApiModelProperty(value = "操作人")
    @cn.afterturn.easypoi.excel.annotation.Excel(name = "操作人",width = 20)
    private String operationName;
    @ApiModelProperty(value = "操作账号")
    @cn.afterturn.easypoi.excel.annotation.Excel(name = "操作账号",width = 20)
    private String operationAccount;
    @ApiModelProperty(value =" 操作类型 1=新增 2=编辑 3=删除 4=导入 5=导出 6=批量冻结")
    @cn.afterturn.easypoi.excel.annotation.Excel(name = "操作类型",width = 20,replace = {"1_新增","2_编辑","3_删除","4_导入","5_导出","6_批量冻结"})
    private Integer operationType;
    @ApiModelProperty(value = "操作内容")
    @cn.afterturn.easypoi.excel.annotation.Excel(name = "操作内容",width = 20)
    private String operationContent;
    @ApiModelProperty(value = "操作ip")
    @cn.afterturn.easypoi.excel.annotation.Excel(name = "操作ip",width = 20)
    private String operationIp;
    @ApiModelProperty(value = "操作时间")
    @cn.afterturn.easypoi.excel.annotation.Excel(name = "操作时间",width = 30)
    private String createTime;
}
xp-service/xp-operation/src/main/java/com/xiaopeng/operation/importExcel/InvitationCodeImportExcel.java
New file
@@ -0,0 +1,18 @@
package com.xiaopeng.operation.importExcel;
import cn.afterturn.easypoi.excel.annotation.Excel;
import io.swagger.annotations.ApiModel;
import lombok.Data;
import java.io.Serializable;
@Data
@ApiModel(value = "邀请码导入excel")
public class InvitationCodeImportExcel implements Serializable {
    @Excel(name = "邀请码",width = 20)
    private String invitationCode;
    @Excel(name = "绑定账号",width = 20)
    private String bindAccount;
    @Excel(name = "绑定时间",width = 30)
    private String bindTime;
}
xp-service/xp-operation/src/main/java/com/xiaopeng/operation/importExcel/WhitelistImportExcel.java
New file
@@ -0,0 +1,16 @@
package com.xiaopeng.operation.importExcel;
import cn.afterturn.easypoi.excel.annotation.Excel;
import io.swagger.annotations.ApiModel;
import lombok.Data;
import java.io.Serializable;
@Data
@ApiModel(value = "白名单导入excel")
public class WhitelistImportExcel implements Serializable {
    @Excel(name = "用户名称",width = 20)
    private String nickName;
    @Excel(name = "白名单账号",width = 20)
    private String account;
}
xp-service/xp-operation/src/main/java/com/xiaopeng/operation/mapper/XpInvitationCodeMapper.java
@@ -2,6 +2,11 @@
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.xiaopeng.api.model.operation.XpInvitationCode;
import com.xiaopeng.common.core.web.page.PageInfo;
import com.xiaopeng.operation.query.InvitationPageListQuery;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
 * <p>
@@ -13,4 +18,7 @@
 */
public interface XpInvitationCodeMapper extends BaseMapper<XpInvitationCode> {
    List<XpInvitationCode> pageList(@Param("pageInfo") PageInfo<XpInvitationCode> pageInfo, @Param("query") InvitationPageListQuery query);
    List<XpInvitationCode> exportList(@Param("query")InvitationPageListQuery query);
}
xp-service/xp-operation/src/main/java/com/xiaopeng/operation/mapper/XpWhitelistMapper.java
@@ -2,6 +2,11 @@
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.xiaopeng.api.model.operation.XpWhitelist;
import com.xiaopeng.common.core.web.page.PageInfo;
import com.xiaopeng.operation.query.WhitelistPageListQuery;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
 * <p>
@@ -13,4 +18,7 @@
 */
public interface XpWhitelistMapper extends BaseMapper<XpWhitelist> {
    List<XpWhitelist> pageList(@Param("pageInfo") PageInfo<XpWhitelist> pageInfo, @Param("query")WhitelistPageListQuery query);
    List<XpWhitelist> exportList(@Param("query")WhitelistPageListQuery query);
}
xp-service/xp-operation/src/main/java/com/xiaopeng/operation/mapper/XpWhitelistOperlogMapper.java
@@ -2,6 +2,11 @@
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.xiaopeng.api.model.operation.XpWhitelistOperlog;
import com.xiaopeng.common.core.web.page.PageInfo;
import com.xiaopeng.operation.query.WhitelistLogPageListQuery;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
 * <p>
@@ -13,4 +18,7 @@
 */
public interface XpWhitelistOperlogMapper extends BaseMapper<XpWhitelistOperlog> {
    List<XpWhitelistOperlog> pageList(@Param("pageInfo") PageInfo<XpWhitelistOperlog> pageInfo, @Param("query")WhitelistLogPageListQuery query);
    List<XpWhitelistOperlog> exportList(@Param("query")WhitelistLogPageListQuery query);
}
xp-service/xp-operation/src/main/java/com/xiaopeng/operation/query/InvitationPageListQuery.java
New file
@@ -0,0 +1,18 @@
package com.xiaopeng.operation.query;
import com.xiaopeng.common.core.web.page.BasePage;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@Data
@ApiModel(value = "邀请码管理列表查询query")
public class InvitationPageListQuery extends BasePage {
    @ApiModelProperty(value = "邀请码")
    private String invitationCode;
    @ApiModelProperty(value = "状态 1=未绑定 2=已绑定 3=已解绑")
    private String status;
    @ApiModelProperty(value = "绑定账号")
    private String bindAccount;
}
xp-service/xp-operation/src/main/java/com/xiaopeng/operation/query/WhitelistLogPageListQuery.java
New file
@@ -0,0 +1,20 @@
package com.xiaopeng.operation.query;
import com.xiaopeng.common.core.web.page.BasePage;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@Data
@ApiModel(value = "白名单日志列表查询query")
public class WhitelistLogPageListQuery extends BasePage {
    @ApiModelProperty(value = "操作人")
    private String operationName;
    @ApiModelProperty(value = "操作类型 1=新增 2=编辑 3=删除 4=导入 5=导出 6=批量冻结")
    private Integer operationType;
    @ApiModelProperty(value = "开始时间 yyyy-MM-dd HH:mm:ss")
    private String startTime;
    @ApiModelProperty(value = "结束时间 yyyy-MM-dd HH:mm:ss")
    private String endTime;
}
xp-service/xp-operation/src/main/java/com/xiaopeng/operation/query/WhitelistPageListQuery.java
New file
@@ -0,0 +1,18 @@
package com.xiaopeng.operation.query;
import com.xiaopeng.common.core.web.page.BasePage;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@Data
@ApiModel(value = "白名单管理列表查询query")
public class WhitelistPageListQuery extends BasePage {
    @ApiModelProperty(value = "白名单账号")
    private String account;
    @ApiModelProperty(value = "状态 0=冻结 1=正常")
    private Boolean status;
    @ApiModelProperty(value = "来源 1=添加 2=邀请码")
    private Integer whitelistSource;
}
xp-service/xp-operation/src/main/java/com/xiaopeng/operation/service/IXpInvitationCodeService.java
@@ -2,6 +2,11 @@
import com.baomidou.mybatisplus.extension.service.IService;
import com.xiaopeng.api.model.operation.XpInvitationCode;
import com.xiaopeng.api.model.operation.XpWhitelist;
import com.xiaopeng.common.core.web.page.PageInfo;
import com.xiaopeng.operation.query.InvitationPageListQuery;
import java.util.List;
/**
 * <p>
@@ -13,4 +18,7 @@
 */
public interface IXpInvitationCodeService extends IService<XpInvitationCode> {
    PageInfo<XpInvitationCode> pageList(InvitationPageListQuery query);
    List<XpInvitationCode> exportList(InvitationPageListQuery query);
}
xp-service/xp-operation/src/main/java/com/xiaopeng/operation/service/IXpWhitelistOperlogService.java
@@ -2,6 +2,10 @@
import com.baomidou.mybatisplus.extension.service.IService;
import com.xiaopeng.api.model.operation.XpWhitelistOperlog;
import com.xiaopeng.common.core.web.page.PageInfo;
import com.xiaopeng.operation.query.WhitelistLogPageListQuery;
import java.util.List;
/**
 * <p>
@@ -13,4 +17,7 @@
 */
public interface IXpWhitelistOperlogService extends IService<XpWhitelistOperlog> {
    PageInfo<XpWhitelistOperlog> pageList(WhitelistLogPageListQuery query);
    List<XpWhitelistOperlog> exportList(WhitelistLogPageListQuery query);
}
xp-service/xp-operation/src/main/java/com/xiaopeng/operation/service/IXpWhitelistService.java
@@ -2,6 +2,10 @@
import com.baomidou.mybatisplus.extension.service.IService;
import com.xiaopeng.api.model.operation.XpWhitelist;
import com.xiaopeng.common.core.web.page.PageInfo;
import com.xiaopeng.operation.query.WhitelistPageListQuery;
import java.util.List;
/**
 * <p>
@@ -13,4 +17,7 @@
 */
public interface IXpWhitelistService extends IService<XpWhitelist> {
    PageInfo<XpWhitelist> pageList(WhitelistPageListQuery query);
    List<XpWhitelist> exportList(WhitelistPageListQuery query);
}
xp-service/xp-operation/src/main/java/com/xiaopeng/operation/service/XpInvitationCodeService.java
File was deleted
xp-service/xp-operation/src/main/java/com/xiaopeng/operation/service/XpWhitelistOperlogService.java
File was deleted
xp-service/xp-operation/src/main/java/com/xiaopeng/operation/service/XpWhitelistService.java
File was deleted
xp-service/xp-operation/src/main/java/com/xiaopeng/operation/service/impl/XpInvitationCodeServiceImpl.java
@@ -1,10 +1,16 @@
package com.xiaopeng.operation.service.impl;
import com.xiaopeng.api.model.operation.XpInvitationCode;
import com.xiaopeng.api.model.operation.XpPoint;
import com.xiaopeng.api.model.operation.XpWhitelist;
import com.xiaopeng.common.core.web.page.PageInfo;
import com.xiaopeng.operation.mapper.XpInvitationCodeMapper;
import com.xiaopeng.operation.query.InvitationPageListQuery;
import com.xiaopeng.operation.service.IXpInvitationCodeService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
import java.util.List;
/**
 * <p>
@@ -17,4 +23,18 @@
@Service
public class XpInvitationCodeServiceImpl extends ServiceImpl<XpInvitationCodeMapper, XpInvitationCode> implements IXpInvitationCodeService {
    @Override
    public PageInfo<XpInvitationCode> pageList(InvitationPageListQuery query) {
        PageInfo<XpInvitationCode> pageInfo = new PageInfo<>(query.getPageCurr(),query.getPageSize());
        List<XpInvitationCode> list = this.baseMapper.pageList(pageInfo,query);
        pageInfo.setRecords(list);
        return pageInfo;
    }
    @Override
    public List<XpInvitationCode> exportList(InvitationPageListQuery query) {
        List<XpInvitationCode> list = this.baseMapper.exportList(query);
        return list;
    }
}
xp-service/xp-operation/src/main/java/com/xiaopeng/operation/service/impl/XpWhitelistOperlogServiceImpl.java
@@ -1,10 +1,15 @@
package com.xiaopeng.operation.service.impl;
import com.xiaopeng.api.model.operation.XpInvitationCode;
import com.xiaopeng.api.model.operation.XpWhitelistOperlog;
import com.xiaopeng.common.core.web.page.PageInfo;
import com.xiaopeng.operation.mapper.XpWhitelistOperlogMapper;
import com.xiaopeng.operation.query.WhitelistLogPageListQuery;
import com.xiaopeng.operation.service.IXpWhitelistOperlogService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
import java.util.List;
/**
 * <p>
@@ -17,4 +22,18 @@
@Service
public class XpWhitelistOperlogServiceImpl extends ServiceImpl<XpWhitelistOperlogMapper, XpWhitelistOperlog> implements IXpWhitelistOperlogService {
    @Override
    public PageInfo<XpWhitelistOperlog> pageList(WhitelistLogPageListQuery query) {
        PageInfo<XpWhitelistOperlog> pageInfo = new PageInfo<>(query.getPageCurr(),query.getPageSize());
        List<XpWhitelistOperlog> list = this.baseMapper.pageList(pageInfo,query);
        pageInfo.setRecords(list);
        return pageInfo;
    }
    @Override
    public List<XpWhitelistOperlog> exportList(WhitelistLogPageListQuery query) {
        List<XpWhitelistOperlog> list = this.baseMapper.exportList(query);
        return list;
    }
}
xp-service/xp-operation/src/main/java/com/xiaopeng/operation/service/impl/XpWhitelistServiceImpl.java
@@ -1,10 +1,15 @@
package com.xiaopeng.operation.service.impl;
import com.xiaopeng.api.model.operation.XpInvitationCode;
import com.xiaopeng.api.model.operation.XpWhitelist;
import com.xiaopeng.common.core.web.page.PageInfo;
import com.xiaopeng.operation.mapper.XpWhitelistMapper;
import com.xiaopeng.operation.query.WhitelistPageListQuery;
import com.xiaopeng.operation.service.IXpWhitelistService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
import java.util.List;
/**
 * <p>
@@ -17,4 +22,18 @@
@Service
public class XpWhitelistServiceImpl extends ServiceImpl<XpWhitelistMapper, XpWhitelist> implements IXpWhitelistService {
    @Override
    public PageInfo<XpWhitelist> pageList(WhitelistPageListQuery query) {
        PageInfo<XpWhitelist> pageInfo = new PageInfo<>(query.getPageCurr(),query.getPageSize());
        List<XpWhitelist> list = this.baseMapper.pageList(pageInfo,query);
        pageInfo.setRecords(list);
        return pageInfo;
    }
    @Override
    public List<XpWhitelist> exportList(WhitelistPageListQuery query) {
        List<XpWhitelist> list = this.baseMapper.exportList(query);
        return list;
    }
}
xp-service/xp-operation/src/main/resources/mapper/operation/XpInvitationCodeMapper.xml
@@ -6,5 +6,37 @@
    <sql id="Base_Column_List">
        id, invitation_code, bind_account, bind_time, status, is_deleted, create_time, update_time, create_by, update_by
    </sql>
    <select id="pageList" resultType="com.xiaopeng.api.model.operation.XpInvitationCode">
        select  id,invitation_code as invitationCode,bind_account as bindAccount,bind_time as bindTime,status,is_deleted as deleted,create_time as createTime
        from xp_invitation_code
        where is_deleted = 0
        <if test="query.invitationCode != null and query.invitationCode != ''">
            and invitation_code like concat('%',#{query.invitationCode},'%')
        </if>
        <if test="query.status != null and query.status != ''">
            and status = #{query.status}
        </if>
        <if test="query.bindAccount != null and query.bindAccount != ''">
            and bind_account like concat('%',#{query.bindAccount},'%')
        </if>
        ORDER BY create_time DESC
    </select>
    <select id="exportList" resultType="com.xiaopeng.api.model.operation.XpInvitationCode">
        select  id,invitation_code as invitationCode,bind_account as bindAccount,bind_time as bindTime,status,is_deleted as deleted,create_time as createTime
        from xp_invitation_code
        where is_deleted = 0
        <if test="query.invitationCode != null and query.invitationCode != ''">
            and invitation_code like concat('%',#{query.invitationCode},'%')
        </if>
        <if test="query.status != null and query.status != ''">
            and status = #{query.status}
        </if>
        <if test="query.bindAccount != null and query.bindAccount != ''">
            and bind_account like concat('%',#{query.bindAccount},'%')
        </if>
        ORDER BY create_time DESC
    </select>
</mapper>
xp-service/xp-operation/src/main/resources/mapper/operation/XpWhitelistMapper.xml
@@ -4,7 +4,39 @@
    <!-- 通用查询结果列 -->
    <sql id="Base_Column_List">
        id, nick_name, account, status, is_priority_dispatch, source, is_deleted, create_time, update_time, create_by, update_by
        id, nick_name, account, status, is_priority_dispatch, whitelist_source, is_deleted, create_time, update_time, create_by, update_by
    </sql>
    <select id="pageList" resultType="com.xiaopeng.api.model.operation.XpWhitelist">
        select id,nick_name as nickName,account,status,is_priority_dispatch as isPriorityDispatch,whitelist_source as whitelistSource
        ,create_time as createTime,update_time as updateTime,create_by as createBy,update_by as updateBy
        from xp_whitelist
        where is_deleted = 0
        <if test="query.account != null and query.account != ''">
            and account like concat('%',#{query.account},'%')
        </if>
        <if test="query.status != null">
            and status = #{query.status}
        </if>
        <if test="query.whitelistSource != null">
            and whitelist_source = #{query.source}
        </if>
        order by create_time desc
    </select>
    <select id="exportList" resultType="com.xiaopeng.api.model.operation.XpWhitelist">
        select id,nick_name as nickName,account,status,is_priority_dispatch as isPriorityDispatch,whitelist_source as whitelistSource
        ,create_time as createTime,update_time as updateTime,create_by as createBy,update_by as updateBy
        from xp_whitelist
        where is_deleted = 0
        <if test="query.account != null and query.account != ''">
            and account like concat('%',#{query.account},'%')
        </if>
        <if test="query.status != null">
            and status = #{query.status}
        </if>
        <if test="query.whitelistSource != null">
            and whitelist_source = #{query.source}
        </if>
        order by create_time desc
    </select>
</mapper>
xp-service/xp-operation/src/main/resources/mapper/operation/XpWhitelistOperlogMapper.xml
@@ -6,5 +6,37 @@
    <sql id="Base_Column_List">
        id, operation_name, operation_account, operation_type, operation_content, operation_ip, operation_account_id, is_deleted, create_time, update_time, create_by, update_by
    </sql>
    <select id="pageList" resultType="com.xiaopeng.api.model.operation.XpWhitelistOperlog">
        SELECT
        id,operation_name as operationName, operation_account as operationAccount, operation_type as operationType, operation_content as operationContent, operation_ip as operationIp, operation_account_id as operationAccountId, is_deleted as deleted, create_time as createTime, update_time as updateTime
            FROM xp_whitelist_operlog
        WHERE is_deleted = 0
        <if test="account != null and account != ''">
            AND operation_account LIKE CONCAT('%',#{account},'%')
        </if>
        <if test="operationName != null and operationName != ''">
            AND operation_name LIKE CONCAT('%',#{operationName},'%')
        </if>
        <if test="operationType != null">
            AND operation_type = #{operationType}
        </if>
        order by create_time desc
    </select>
    <select id="exportList" resultType="com.xiaopeng.api.model.operation.XpWhitelistOperlog">
        SELECT
        id,operation_name as operationName, operation_account as operationAccount, operation_type as operationType, operation_content as operationContent, operation_ip as operationIp, operation_account_id as operationAccountId, is_deleted as deleted, create_time as createTime, update_time as updateTime
        FROM xp_whitelist_operlog
        WHERE is_deleted = 0
        <if test="account != null and account != ''">
            AND operation_account LIKE CONCAT('%',#{account},'%')
        </if>
        <if test="operationName != null and operationName != ''">
            AND operation_name LIKE CONCAT('%',#{operationName},'%')
        </if>
        <if test="operationType != null">
            AND operation_type = #{operationType}
        </if>
        order by create_time desc
    </select>
</mapper>