ruoyi-api/ruoyi-api-account/src/main/java/com/ruoyi/account/api/dto/AppUserWhitelistImportDTO.java
New file @@ -0,0 +1,26 @@ package com.ruoyi.account.api.dto; import com.ruoyi.common.core.annotation.Excel; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Data; /** * 白名单用户导入行 */ @Data @ApiModel(value = "AppUserWhitelistImportDTO", description = "白名单用户导入行") public class AppUserWhitelistImportDTO { @Excel(name = "用户手机号", prompt = "填写11位手机号,如:13800138000") @ApiModelProperty(value = "用户手机号") private String phone; @Excel(name = "享受权益", prompt = "1=全部免费,2=免电费,3=免服务费", combo = {"1", "2", "3"}) @ApiModelProperty(value = "享受权益") private String benefitType; @Excel(name = "白名单电站", prompt = "填写all表示全部电站;指定电站填写平台站点编号,多个用英文逗号分隔,如:ST001,ST002") @ApiModelProperty(value = "白名单电站") private String whitelistSite; } ruoyi-api/ruoyi-api-account/src/main/java/com/ruoyi/account/api/dto/AppUserWhitelistQueryDTO.java
New file @@ -0,0 +1,19 @@ package com.ruoyi.account.api.dto; import com.ruoyi.common.core.web.page.BasePage; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Data; import lombok.EqualsAndHashCode; /** * 白名单用户分页查询 */ @Data @EqualsAndHashCode(callSuper = true) @ApiModel(value = "AppUserWhitelistQueryDTO", description = "白名单用户分页查询") public class AppUserWhitelistQueryDTO extends BasePage { @ApiModelProperty(value = "用户手机号") private String phone; } ruoyi-api/ruoyi-api-account/src/main/java/com/ruoyi/account/api/dto/AppUserWhitelistSaveDTO.java
New file @@ -0,0 +1,36 @@ package com.ruoyi.account.api.dto; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Data; import java.util.List; /** * 白名单用户保存参数 */ @Data @ApiModel(value = "AppUserWhitelistSaveDTO", description = "白名单用户保存参数") public class AppUserWhitelistSaveDTO { @ApiModelProperty(value = "主键") private Long id; @ApiModelProperty(value = "用户手机号") private String phone; @ApiModelProperty(value = "享受权益:1=全部免费,2=免电费,3=免服务费") private Integer benefitType; @ApiModelProperty(value = "白名单电站范围:1=全部电站,2=指定站点,3=指定合作商") private Integer scopeType; @ApiModelProperty(value = "合作商ID") private Integer partnerId; @ApiModelProperty(value = "站点ID列表") private List<Integer> siteIds; @ApiModelProperty(value = "备注") private String remark; } ruoyi-api/ruoyi-api-account/src/main/java/com/ruoyi/account/api/model/TAppUserWhitelist.java
New file @@ -0,0 +1,89 @@ package com.ruoyi.account.api.model; import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; import com.fasterxml.jackson.databind.annotation.JsonSerialize; import com.fasterxml.jackson.databind.ser.std.ToStringSerializer; import com.ruoyi.common.core.web.domain.BasePojo; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Data; import lombok.EqualsAndHashCode; import java.util.List; /** * 白名单用户 */ @Data @EqualsAndHashCode(callSuper = false) @TableName("t_app_user_whitelist") @ApiModel(value = "TAppUserWhitelist对象", description = "白名单用户") public class TAppUserWhitelist extends BasePojo { @ApiModelProperty(value = "主键") @TableId("id") @JsonSerialize(using = ToStringSerializer.class) private Long id; @ApiModelProperty(value = "APP用户ID") @TableField("app_user_id") private Long appUserId; @ApiModelProperty(value = "用户手机号") @TableField("phone") private String phone; @ApiModelProperty(value = "享受权益:1=全部免费,2=免电费,3=免服务费") @TableField("benefit_type") private Integer benefitType; @ApiModelProperty(value = "白名单电站范围:1=全部电站,2=指定站点,3=指定合作商") @TableField("scope_type") private Integer scopeType; @ApiModelProperty(value = "合作商ID,scope_type=3时有效") @TableField("partner_id") private Integer partnerId; @ApiModelProperty(value = "状态:1=启用,2=停用") @TableField("status") private Integer status; @ApiModelProperty(value = "创建人") @TableField("create_by") private String createBy; @ApiModelProperty(value = "更新人") @TableField("update_by") private String updateBy; @ApiModelProperty(value = "备注") @TableField("remark") private String remark; @ApiModelProperty(value = "主键字符串") @TableField(exist = false) private String uid; @ApiModelProperty(value = "享受权益名称") @TableField(exist = false) private String benefitName; @ApiModelProperty(value = "白名单电站范围名称") @TableField(exist = false) private String scopeName; @ApiModelProperty(value = "合作商名称") @TableField(exist = false) private String partnerName; @ApiModelProperty(value = "站点ID列表") @TableField(exist = false) private List<Integer> siteIds; @ApiModelProperty(value = "站点展示列表") @TableField(exist = false) private List<TAppUserWhitelistSite> siteList; } ruoyi-api/ruoyi-api-account/src/main/java/com/ruoyi/account/api/model/TAppUserWhitelistSite.java
New file @@ -0,0 +1,60 @@ package com.ruoyi.account.api.model; import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; import com.fasterxml.jackson.databind.annotation.JsonSerialize; import com.fasterxml.jackson.databind.ser.std.ToStringSerializer; import com.ruoyi.common.core.web.domain.BasePojo; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Data; import lombok.EqualsAndHashCode; /** * 白名单用户指定站点 */ @Data @EqualsAndHashCode(callSuper = false) @TableName("t_app_user_whitelist_site") @ApiModel(value = "TAppUserWhitelistSite对象", description = "白名单用户指定站点") public class TAppUserWhitelistSite extends BasePojo { @ApiModelProperty(value = "主键") @TableId("id") @JsonSerialize(using = ToStringSerializer.class) private Long id; @ApiModelProperty(value = "白名单用户ID") @TableField("whitelist_id") @JsonSerialize(using = ToStringSerializer.class) private Long whitelistId; @ApiModelProperty(value = "站点ID") @TableField("site_id") private Integer siteId; @ApiModelProperty(value = "平台站点编号") @TableField(exist = false) private String siteCode; @ApiModelProperty(value = "站点名称") @TableField(exist = false) private String siteName; @ApiModelProperty(value = "归属合作商") @TableField(exist = false) private String partnerName; @ApiModelProperty(value = "站点类型") @TableField(exist = false) private Integer siteType; @ApiModelProperty(value = "经营类别") @TableField(exist = false) private Integer businessCategory; @ApiModelProperty(value = "站点状态") @TableField(exist = false) private Integer status; } ruoyi-api/ruoyi-api-account/src/main/java/com/ruoyi/account/api/vo/AppUserWhitelistImportErrorVO.java
New file @@ -0,0 +1,26 @@ package com.ruoyi.account.api.vo; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; /** * 白名单导入错误明细 */ @Data @NoArgsConstructor @AllArgsConstructor @ApiModel(value = "AppUserWhitelistImportErrorVO", description = "白名单导入错误明细") public class AppUserWhitelistImportErrorVO { @ApiModelProperty(value = "Excel行号") private Integer rowNum; @ApiModelProperty(value = "用户手机号") private String phone; @ApiModelProperty(value = "失败原因") private String reason; } ruoyi-api/ruoyi-api-account/src/main/java/com/ruoyi/account/api/vo/AppUserWhitelistImportResultVO.java
New file @@ -0,0 +1,27 @@ package com.ruoyi.account.api.vo; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Data; import java.util.List; /** * 白名单导入结果 */ @Data @ApiModel(value = "AppUserWhitelistImportResultVO", description = "白名单导入结果") public class AppUserWhitelistImportResultVO { @ApiModelProperty(value = "总行数") private Integer totalCount; @ApiModelProperty(value = "错误行数") private Integer errorCount; @ApiModelProperty(value = "成功行数") private Integer successCount; @ApiModelProperty(value = "错误明细") private List<AppUserWhitelistImportErrorVO> errorMessage; } ruoyi-api/ruoyi-api-chargingPile/src/main/java/com/ruoyi/chargingPile/api/query/GetSiteList.java
@@ -4,7 +4,8 @@ import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Data; import lombok.Value; import java.util.List; /** * @author zhibing.pu @@ -17,6 +18,8 @@ private String name; @ApiModelProperty(value = "合作商名称") private String partnerName; @ApiModelProperty(value = "合作商id集合") private List<Integer> partnerIds; @ApiModelProperty(value = "站点类型(0=其他,1=公共,2=个人,3=公交(专业),4=环卫(专用),5=物流(专用),6=出租车(专用))") private Integer siteType; @ApiModelProperty(value = "经营类型(1=直营,2=非直营)") ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/controller/TAppUserWhitelistController.java
New file @@ -0,0 +1,95 @@ package com.ruoyi.account.controller; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.ruoyi.account.api.dto.AppUserWhitelistImportDTO; import com.ruoyi.account.api.dto.AppUserWhitelistQueryDTO; import com.ruoyi.account.api.dto.AppUserWhitelistSaveDTO; import com.ruoyi.account.api.model.TAppUserWhitelist; import com.ruoyi.account.api.vo.AppUserWhitelistImportResultVO; import com.ruoyi.account.service.TAppUserWhitelistService; import com.ruoyi.common.core.domain.R; import com.ruoyi.common.core.utils.poi.ExcelUtil; import com.ruoyi.common.log.annotation.Log; import com.ruoyi.common.log.enums.BusinessType; import com.ruoyi.common.log.enums.OperatorType; import com.ruoyi.common.security.annotation.Logical; import com.ruoyi.common.security.annotation.RequiresPermissions; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import org.springframework.web.bind.annotation.DeleteMapping; 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; /** * 白名单用户管理 */ @Api(tags = "白名单用户管理") @RestController @RequestMapping("/t-app-user-whitelist") public class TAppUserWhitelistController { @Resource private TAppUserWhitelistService whitelistService; @ApiOperation("分页查询白名单用户") @RequiresPermissions(value = {"/appUserWhitelist/list"}, logical = Logical.OR) @PostMapping("/page") public R<Page<TAppUserWhitelist>> page(@RequestBody AppUserWhitelistQueryDTO queryDTO) { return R.ok(whitelistService.pageList(queryDTO)); } @ApiOperation("查询白名单用户详情") @RequiresPermissions(value = {"/appUserWhitelist/select"}, logical = Logical.OR) @GetMapping("/detail/{id}") public R<TAppUserWhitelist> detail(@PathVariable("id") Long id) { return R.ok(whitelistService.detail(id)); } @ApiOperation("新增或修改白名单用户") @RequiresPermissions(value = {"/appUserWhitelist/add", "/appUserWhitelist/update"}, logical = Logical.OR) @Log(title = "【白名单用户】新增或修改", businessType = BusinessType.INSERT, operatorType = OperatorType.MANAGE) @PostMapping("/addOrUpdate") public R<Void> addOrUpdate(@RequestBody AppUserWhitelistSaveDTO saveDTO) { whitelistService.saveWhitelist(saveDTO); return R.ok(); } @ApiOperation("删除白名单用户") @RequiresPermissions(value = {"/appUserWhitelist/del"}, logical = Logical.OR) @Log(title = "【白名单用户】删除", businessType = BusinessType.DELETE, operatorType = OperatorType.MANAGE) @DeleteMapping("/delete") public R<Void> delete(@RequestParam("ids") String ids) { whitelistService.deleteByIds(ids); return R.ok(); } @ApiOperation("下载白名单用户导入模板") @RequiresPermissions(value = {"/appUserWhitelist/import"}, logical = Logical.OR) @GetMapping("/importTemplate") public void importTemplate(HttpServletResponse response) { ExcelUtil<AppUserWhitelistImportDTO> util = new ExcelUtil<>(AppUserWhitelistImportDTO.class); util.importTemplateExcel(response, "白名单用户导入模板", "填写说明:用户手机号填写11位手机号;享受权益填写 1=全部免费、2=免电费、3=免服务费;白名单电站填写 all 表示全部电站,指定电站填写平台站点编号,多个用英文逗号分隔,如 ST001,ST002。"); } @ApiOperation("导入白名单用户") @RequiresPermissions(value = {"/appUserWhitelist/import"}, logical = Logical.OR) @Log(title = "【白名单用户】导入", businessType = BusinessType.IMPORT, operatorType = OperatorType.MANAGE) @PostMapping("/import") public R<AppUserWhitelistImportResultVO> importData(@RequestParam("file") MultipartFile file) throws Exception { AppUserWhitelistImportResultVO result = whitelistService.importWhitelist(file); if (result.getErrorCount() != null && result.getErrorCount() > 0) { return R.fail(result, "导入失败,请检查错误数据"); } return R.ok(result, "导入成功"); } } ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/mapper/TAppUserWhitelistMapper.java
New file @@ -0,0 +1,14 @@ package com.ruoyi.account.mapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.ruoyi.account.api.model.TAppUserWhitelist; /** * 白名单用户 Mapper */ public interface TAppUserWhitelistMapper extends BaseMapper<TAppUserWhitelist> { TAppUserWhitelist selectByPhoneIgnoreLogic(String phone); int updateByIdIgnoreLogic(TAppUserWhitelist whitelist); } ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/mapper/TAppUserWhitelistSiteMapper.java
New file @@ -0,0 +1,12 @@ package com.ruoyi.account.mapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.ruoyi.account.api.model.TAppUserWhitelistSite; /** * 白名单用户指定站点 Mapper */ public interface TAppUserWhitelistSiteMapper extends BaseMapper<TAppUserWhitelistSite> { int deleteByWhitelistId(Long whitelistId); } ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/service/TAppUserWhitelistService.java
New file @@ -0,0 +1,25 @@ package com.ruoyi.account.service; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.IService; import com.ruoyi.account.api.dto.AppUserWhitelistQueryDTO; import com.ruoyi.account.api.dto.AppUserWhitelistSaveDTO; import com.ruoyi.account.api.model.TAppUserWhitelist; import com.ruoyi.account.api.vo.AppUserWhitelistImportResultVO; import org.springframework.web.multipart.MultipartFile; /** * 白名单用户服务 */ public interface TAppUserWhitelistService extends IService<TAppUserWhitelist> { Page<TAppUserWhitelist> pageList(AppUserWhitelistQueryDTO queryDTO); TAppUserWhitelist detail(Long id); void saveWhitelist(AppUserWhitelistSaveDTO saveDTO); void deleteByIds(String ids); AppUserWhitelistImportResultVO importWhitelist(MultipartFile file) throws Exception; } ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/service/TAppUserWhitelistSiteService.java
New file @@ -0,0 +1,12 @@ package com.ruoyi.account.service; import com.baomidou.mybatisplus.extension.service.IService; import com.ruoyi.account.api.model.TAppUserWhitelistSite; /** * 白名单用户指定站点服务 */ public interface TAppUserWhitelistSiteService extends IService<TAppUserWhitelistSite> { void deleteByWhitelistId(Long whitelistId); } ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/service/impl/TAppUserWhitelistServiceImpl.java
New file @@ -0,0 +1,544 @@ package com.ruoyi.account.service.impl; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.ruoyi.account.api.dto.AppUserWhitelistImportDTO; import com.ruoyi.account.api.dto.AppUserWhitelistQueryDTO; import com.ruoyi.account.api.dto.AppUserWhitelistSaveDTO; import com.ruoyi.account.api.model.TAppUser; import com.ruoyi.account.api.model.TAppUserWhitelist; import com.ruoyi.account.api.model.TAppUserWhitelistSite; import com.ruoyi.account.api.vo.AppUserWhitelistImportErrorVO; import com.ruoyi.account.api.vo.AppUserWhitelistImportResultVO; import com.ruoyi.account.mapper.TAppUserWhitelistMapper; import com.ruoyi.account.service.TAppUserService; import com.ruoyi.account.service.TAppUserWhitelistService; import com.ruoyi.account.service.TAppUserWhitelistSiteService; import com.ruoyi.chargingPile.api.feignClient.PartnerClient; import com.ruoyi.chargingPile.api.feignClient.SiteClient; import com.ruoyi.chargingPile.api.model.Partner; import com.ruoyi.chargingPile.api.model.Site; import com.ruoyi.common.core.domain.R; import com.ruoyi.common.core.exception.ServiceException; import com.ruoyi.common.core.utils.StringUtils; import com.ruoyi.common.core.utils.poi.ExcelUtil; import com.ruoyi.common.core.web.domain.BasePojo; import com.ruoyi.common.security.service.TokenService; import com.ruoyi.common.security.utils.SecurityUtils; import com.ruoyi.system.api.model.LoginUser; import org.apache.poi.ss.usermodel.Row; import org.apache.poi.ss.usermodel.Sheet; import org.apache.poi.ss.usermodel.Workbook; import org.apache.poi.ss.usermodel.WorkbookFactory; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.web.multipart.MultipartFile; import javax.annotation.Resource; import java.io.InputStream; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Objects; import java.util.Set; import java.util.regex.Pattern; import java.util.stream.Collectors; /** * 白名单用户服务实现 */ @Service public class TAppUserWhitelistServiceImpl extends ServiceImpl<TAppUserWhitelistMapper, TAppUserWhitelist> implements TAppUserWhitelistService { private static final Pattern PHONE_PATTERN = Pattern.compile("^1\\d{10}$"); private static final String IMPORT_HEADER_PHONE = "用户手机号"; private static final String IMPORT_HEADER_BENEFIT_TYPE = "享受权益"; private static final String IMPORT_HEADER_WHITELIST_SITE = "白名单电站"; private static final int BENEFIT_ALL_FREE = 1; private static final int BENEFIT_ELECTRIC_FREE = 2; private static final int BENEFIT_SERVICE_FREE = 3; private static final int SCOPE_ALL_SITE = 1; private static final int SCOPE_SELECTED_SITE = 2; private static final int SCOPE_PARTNER = 3; private static final int STATUS_ENABLED = 1; @Resource private TAppUserWhitelistSiteService whitelistSiteService; @Resource private TAppUserService appUserService; @Resource private SiteClient siteClient; @Resource private PartnerClient partnerClient; @Resource private TokenService tokenService; @Override public Page<TAppUserWhitelist> pageList(AppUserWhitelistQueryDTO queryDTO) { Page<TAppUserWhitelist> page = this.lambdaQuery() .like(StringUtils.isNotBlank(queryDTO.getPhone()), TAppUserWhitelist::getPhone, queryDTO.getPhone()) .orderByDesc(BasePojo::getCreateTime) .page(Page.of(queryDTO.getPageCurr(), queryDTO.getPageSize())); fillDisplay(page.getRecords()); return page; } @Override public TAppUserWhitelist detail(Long id) { TAppUserWhitelist whitelist = this.getById(id); if (whitelist == null) { throw new ServiceException("白名单用户不存在"); } fillDisplay(Collections.singletonList(whitelist)); return whitelist; } @Override @Transactional(rollbackFor = Exception.class) public void saveWhitelist(AppUserWhitelistSaveDTO saveDTO) { validateSaveDTO(saveDTO); if (saveDTO.getId() == null) { createWhitelist(saveDTO); } else { updateWhitelist(saveDTO); } } @Override @Transactional(rollbackFor = Exception.class) public void deleteByIds(String ids) { if (StringUtils.isBlank(ids)) { return; } for (String id : ids.split(",")) { if (StringUtils.isBlank(id)) { continue; } Long whitelistId = Long.valueOf(id); this.removeById(whitelistId); whitelistSiteService.remove(Wrappers.lambdaQuery(TAppUserWhitelistSite.class) .eq(TAppUserWhitelistSite::getWhitelistId, whitelistId)); } } @Override @Transactional(rollbackFor = Exception.class) public AppUserWhitelistImportResultVO importWhitelist(MultipartFile file) throws Exception { if (file == null || file.isEmpty()) { throw new ServiceException("导入文件不能为空"); } int titleNum = getImportTitleNum(file); ExcelUtil<AppUserWhitelistImportDTO> util = new ExcelUtil<>(AppUserWhitelistImportDTO.class); List<AppUserWhitelistImportDTO> rows = util.importExcel(file.getInputStream(), titleNum); if (rows == null || rows.isEmpty()) { throw new ServiceException("导入数据不能为空"); } Map<String, Site> siteCodeMap = getSiteCodeMap(); Map<String, AppUserWhitelistSaveDTO> validRows = new LinkedHashMap<>(); List<AppUserWhitelistImportErrorVO> errors = new ArrayList<>(); Set<String> importPhones = new HashSet<>(); for (int i = 0; i < rows.size(); i++) { AppUserWhitelistImportDTO row = rows.get(i); int rowNum = titleNum + i + 2; List<String> rowErrors = validateImportRow(row, siteCodeMap); if (!rowErrors.isEmpty()) { errors.add(new AppUserWhitelistImportErrorVO(rowNum, normalize(row.getPhone()), String.join(";", rowErrors))); continue; } AppUserWhitelistSaveDTO dto = buildSaveDTO(row, siteCodeMap); if (!importPhones.add(dto.getPhone())) { errors.add(new AppUserWhitelistImportErrorVO(rowNum, dto.getPhone(), "导入文件中手机号重复")); continue; } if (getByPhone(dto.getPhone()) != null) { errors.add(new AppUserWhitelistImportErrorVO(rowNum, dto.getPhone(), "该手机号已存在白名单配置")); continue; } validRows.put(dto.getPhone(), dto); } AppUserWhitelistImportResultVO result = new AppUserWhitelistImportResultVO(); result.setTotalCount(rows.size()); result.setErrorCount(errors.size()); result.setSuccessCount(errors.isEmpty() ? validRows.size() : 0); result.setErrorMessage(errors); if (!errors.isEmpty()) { return result; } for (AppUserWhitelistSaveDTO dto : validRows.values()) { createWhitelist(dto); } return result; } private int getImportTitleNum(MultipartFile file) throws Exception { try (InputStream inputStream = file.getInputStream(); Workbook workbook = WorkbookFactory.create(inputStream)) { Sheet sheet = workbook.getSheetAt(0); if (sheet == null) { throw new ServiceException("导入文件sheet不存在"); } int maxRow = Math.min(sheet.getLastRowNum(), 5); for (int i = 0; i <= maxRow; i++) { Row row = sheet.getRow(i); if (isImportHeaderRow(row)) { return i; } } } throw new ServiceException("导入文件表头不正确,请下载最新模板后填写"); } private boolean isImportHeaderRow(Row row) { if (row == null) { return false; } ExcelUtil<AppUserWhitelistImportDTO> util = new ExcelUtil<>(AppUserWhitelistImportDTO.class); return IMPORT_HEADER_PHONE.equals(normalize(String.valueOf(util.getCellValue(row, 0)))) && IMPORT_HEADER_BENEFIT_TYPE.equals(normalize(String.valueOf(util.getCellValue(row, 1)))) && IMPORT_HEADER_WHITELIST_SITE.equals(normalize(String.valueOf(util.getCellValue(row, 2)))); } private void validateSaveDTO(AppUserWhitelistSaveDTO saveDTO) { if (saveDTO == null) { throw new ServiceException("请求参数不能为空"); } saveDTO.setPhone(normalize(saveDTO.getPhone())); if (!isValidPhone(saveDTO.getPhone())) { throw new ServiceException("请输入正确的用户手机号"); } if (!isValidBenefit(saveDTO.getBenefitType())) { throw new ServiceException("请选择正确的享受权益"); } if (!isValidScope(saveDTO.getScopeType())) { throw new ServiceException("请选择正确的白名单电站范围"); } if (Objects.equals(saveDTO.getScopeType(), SCOPE_SELECTED_SITE) && (saveDTO.getSiteIds() == null || saveDTO.getSiteIds().isEmpty())) { throw new ServiceException("请选择白名单电站"); } if (Objects.equals(saveDTO.getScopeType(), SCOPE_PARTNER) && saveDTO.getPartnerId() == null) { throw new ServiceException("请选择加盟商"); } TAppUserWhitelist exists = getByPhone(saveDTO.getPhone()); if (saveDTO.getId() == null && exists != null) { throw new ServiceException("该手机号已存在白名单配置"); } if (saveDTO.getId() != null && exists != null && !Objects.equals(exists.getId(), saveDTO.getId())) { throw new ServiceException("该手机号已存在白名单配置"); } } private void createWhitelist(AppUserWhitelistSaveDTO saveDTO) { if (getByPhone(saveDTO.getPhone()) != null) { throw new ServiceException("该手机号已存在白名单配置"); } TAppUserWhitelist whitelist = new TAppUserWhitelist(); TAppUser appUser = appUserService.lambdaQuery() .eq(TAppUser::getPhone, saveDTO.getPhone()) .last("LIMIT 1") .one(); whitelist.setCreateBy(getUsername()); whitelist.setAppUserId(appUser == null ? null : appUser.getId()); whitelist.setPhone(saveDTO.getPhone()); whitelist.setBenefitType(saveDTO.getBenefitType()); whitelist.setScopeType(saveDTO.getScopeType()); whitelist.setPartnerId(Objects.equals(saveDTO.getScopeType(), SCOPE_PARTNER) ? saveDTO.getPartnerId() : null); whitelist.setStatus(STATUS_ENABLED); whitelist.setUpdateBy(getUsername()); whitelist.setRemark(saveDTO.getRemark()); whitelist.setDelFlag(false); if (whitelist.getId() == null) { this.save(whitelist); } whitelistSiteService.deleteByWhitelistId(whitelist.getId()); if (Objects.equals(saveDTO.getScopeType(), SCOPE_SELECTED_SITE)) { Long whitelistId = whitelist.getId(); List<TAppUserWhitelistSite> sites = saveDTO.getSiteIds().stream() .filter(Objects::nonNull) .distinct() .map(siteId -> { TAppUserWhitelistSite site = new TAppUserWhitelistSite(); site.setWhitelistId(whitelistId); site.setSiteId(siteId); site.setDelFlag(false); return site; }).collect(Collectors.toList()); if (!sites.isEmpty()) { whitelistSiteService.saveBatch(sites); } } } private void updateWhitelist(AppUserWhitelistSaveDTO saveDTO) { TAppUserWhitelist whitelist = this.getById(saveDTO.getId()); if (whitelist == null) { throw new ServiceException("白名单用户不存在"); } TAppUser appUser = appUserService.lambdaQuery() .eq(TAppUser::getPhone, saveDTO.getPhone()) .last("LIMIT 1") .one(); whitelist.setAppUserId(appUser == null ? null : appUser.getId()); whitelist.setPhone(saveDTO.getPhone()); whitelist.setBenefitType(saveDTO.getBenefitType()); whitelist.setScopeType(saveDTO.getScopeType()); whitelist.setPartnerId(Objects.equals(saveDTO.getScopeType(), SCOPE_PARTNER) ? saveDTO.getPartnerId() : null); whitelist.setStatus(STATUS_ENABLED); whitelist.setUpdateBy(getUsername()); whitelist.setRemark(saveDTO.getRemark()); whitelist.setDelFlag(false); this.baseMapper.updateByIdIgnoreLogic(whitelist); whitelistSiteService.deleteByWhitelistId(whitelist.getId()); if (Objects.equals(saveDTO.getScopeType(), SCOPE_SELECTED_SITE)) { Long whitelistId = whitelist.getId(); List<TAppUserWhitelistSite> sites = saveDTO.getSiteIds().stream() .filter(Objects::nonNull) .distinct() .map(siteId -> { TAppUserWhitelistSite site = new TAppUserWhitelistSite(); site.setWhitelistId(whitelistId); site.setSiteId(siteId); site.setDelFlag(false); return site; }).collect(Collectors.toList()); if (!sites.isEmpty()) { whitelistSiteService.saveBatch(sites); } } } private TAppUserWhitelist getByPhone(String phone) { return this.baseMapper.selectByPhoneIgnoreLogic(phone); } private List<String> validateImportRow(AppUserWhitelistImportDTO row, Map<String, Site> siteCodeMap) { List<String> errors = new ArrayList<>(); if (row == null) { errors.add("空行"); return errors; } String phone = normalize(row.getPhone()); if (!isValidPhone(phone)) { errors.add("用户手机号格式错误"); } Integer benefitType = parseInteger(row.getBenefitType()); if (!isValidBenefit(benefitType)) { errors.add("享受权益只能填写1、2、3"); } String whitelistSite = normalize(row.getWhitelistSite()); if (StringUtils.isBlank(whitelistSite)) { errors.add("白名单电站不能为空"); } else if (!"all".equalsIgnoreCase(whitelistSite)) { for (String code : whitelistSite.split(",")) { String siteCode = normalize(code); if (StringUtils.isBlank(siteCode)) { errors.add("白名单电站存在空编号"); } else if (!siteCodeMap.containsKey(siteCode)) { errors.add("站点编号不存在:" + siteCode); } } } return errors; } private AppUserWhitelistSaveDTO buildSaveDTO(AppUserWhitelistImportDTO row, Map<String, Site> siteCodeMap) { AppUserWhitelistSaveDTO dto = new AppUserWhitelistSaveDTO(); dto.setPhone(normalize(row.getPhone())); dto.setBenefitType(parseInteger(row.getBenefitType())); String whitelistSite = normalize(row.getWhitelistSite()); if ("all".equalsIgnoreCase(whitelistSite)) { dto.setScopeType(SCOPE_ALL_SITE); dto.setSiteIds(Collections.emptyList()); } else { dto.setScopeType(SCOPE_SELECTED_SITE); List<Integer> siteIds = new ArrayList<>(); for (String code : whitelistSite.split(",")) { Site site = siteCodeMap.get(normalize(code)); if (site != null) { siteIds.add(site.getId()); } } dto.setSiteIds(siteIds.stream().distinct().collect(Collectors.toList())); } return dto; } private Map<String, Site> getSiteCodeMap() { R<List<Site>> siteResult = siteClient.getSiteAll(); List<Site> sites = siteResult == null || siteResult.getData() == null ? Collections.emptyList() : siteResult.getData(); Map<String, Site> siteCodeMap = new HashMap<>(); for (Site site : sites) { if (site != null && StringUtils.isNotBlank(site.getCode())) { siteCodeMap.put(site.getCode(), site); } } return siteCodeMap; } private void fillDisplay(List<TAppUserWhitelist> records) { if (records == null || records.isEmpty()) { return; } Map<Integer, Site> siteMap = getSiteMap(records); Map<Integer, Partner> partnerMap = getPartnerMap(records, siteMap); for (TAppUserWhitelist record : records) { record.setUid(record.getId() == null ? null : record.getId().toString()); record.setBenefitName(getBenefitName(record.getBenefitType())); record.setScopeName(getScopeName(record.getScopeType())); if (record.getPartnerId() != null) { Partner partner = partnerMap.get(record.getPartnerId()); record.setPartnerName(partner == null ? null : partner.getName()); } List<TAppUserWhitelistSite> sites = whitelistSiteService.lambdaQuery() .eq(TAppUserWhitelistSite::getWhitelistId, record.getId()) .list(); for (TAppUserWhitelistSite siteItem : sites) { Site site = siteMap.get(siteItem.getSiteId()); if (site != null) { siteItem.setSiteCode(site.getCode()); siteItem.setSiteName(site.getName()); siteItem.setSiteType(site.getSiteType()); siteItem.setBusinessCategory(site.getBusinessCategory()); siteItem.setStatus(site.getStatus()); Partner partner = partnerMap.get(site.getPartnerId()); siteItem.setPartnerName(partner == null ? null : partner.getName()); } } record.setSiteList(sites); record.setSiteIds(sites.stream().map(TAppUserWhitelistSite::getSiteId).collect(Collectors.toList())); } } private Map<Integer, Site> getSiteMap(List<TAppUserWhitelist> records) { List<Long> whitelistIds = records.stream().map(TAppUserWhitelist::getId).collect(Collectors.toList()); List<TAppUserWhitelistSite> siteLinks = whitelistSiteService.lambdaQuery() .in(TAppUserWhitelistSite::getWhitelistId, whitelistIds) .list(); List<Integer> siteIds = siteLinks.stream().map(TAppUserWhitelistSite::getSiteId).distinct().collect(Collectors.toList()); if (siteIds.isEmpty()) { return Collections.emptyMap(); } R<List<Site>> siteResult = siteClient.getSiteByIds(siteIds); List<Site> sites = siteResult == null || siteResult.getData() == null ? Collections.emptyList() : siteResult.getData(); return sites.stream().collect(Collectors.toMap(Site::getId, site -> site, (a, b) -> a)); } private Map<Integer, Partner> getPartnerMap(List<TAppUserWhitelist> records, Map<Integer, Site> siteMap) { Map<Integer, Partner> partnerMap = new HashMap<>(); Set<Integer> partnerIds = new HashSet<>(); for (TAppUserWhitelist record : records) { if (record.getPartnerId() != null) { partnerIds.add(record.getPartnerId()); } } if (siteMap != null) { for (Site site : siteMap.values()) { if (site != null && site.getPartnerId() != null) { partnerIds.add(site.getPartnerId()); } } } for (Integer partnerId : partnerIds) { R<Partner> partnerResult = partnerClient.getPartnerById(partnerId); if (partnerResult != null && partnerResult.getData() != null) { partnerMap.put(partnerId, partnerResult.getData()); } } return partnerMap; } private boolean isValidPhone(String phone) { return StringUtils.isNotBlank(phone) && PHONE_PATTERN.matcher(phone).matches(); } private boolean isValidBenefit(Integer benefitType) { return Objects.equals(benefitType, BENEFIT_ALL_FREE) || Objects.equals(benefitType, BENEFIT_ELECTRIC_FREE) || Objects.equals(benefitType, BENEFIT_SERVICE_FREE); } private boolean isValidScope(Integer scopeType) { return Objects.equals(scopeType, SCOPE_ALL_SITE) || Objects.equals(scopeType, SCOPE_SELECTED_SITE) || Objects.equals(scopeType, SCOPE_PARTNER); } private Integer parseInteger(String value) { try { String normalizedValue = normalize(value); if (StringUtils.isBlank(normalizedValue)) { return null; } if (normalizedValue.matches("^\\d+\\.0+$")) { normalizedValue = normalizedValue.substring(0, normalizedValue.indexOf(".")); } return Integer.valueOf(normalizedValue); } catch (Exception e) { return null; } } private String normalize(String value) { return value == null ? null : value.trim(); } private String getBenefitName(Integer benefitType) { if (Objects.equals(benefitType, BENEFIT_ALL_FREE)) { return "全部免费"; } if (Objects.equals(benefitType, BENEFIT_ELECTRIC_FREE)) { return "免电费"; } if (Objects.equals(benefitType, BENEFIT_SERVICE_FREE)) { return "免服务费"; } return ""; } private String getScopeName(Integer scopeType) { if (Objects.equals(scopeType, SCOPE_ALL_SITE)) { return "全部电站"; } if (Objects.equals(scopeType, SCOPE_SELECTED_SITE)) { return "部分电站"; } if (Objects.equals(scopeType, SCOPE_PARTNER)) { return "指定合作商"; } return ""; } private String getUsername() { try { String username = SecurityUtils.getUsername(); if (StringUtils.isNotBlank(username)) { return username; } } catch (Exception e) { // ignore and try token context fallback } try { LoginUser loginUser = tokenService.getLoginUser(); if (loginUser != null) { if (StringUtils.isNotBlank(loginUser.getUsername())) { return loginUser.getUsername(); } if (loginUser.getSysUser() != null && StringUtils.isNotBlank(loginUser.getSysUser().getUserName())) { return loginUser.getSysUser().getUserName(); } } } catch (Exception e) { // ignore and fall through to null } return null; } } ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/service/impl/TAppUserWhitelistSiteServiceImpl.java
New file @@ -0,0 +1,19 @@ package com.ruoyi.account.service.impl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.ruoyi.account.api.model.TAppUserWhitelistSite; import com.ruoyi.account.mapper.TAppUserWhitelistSiteMapper; import com.ruoyi.account.service.TAppUserWhitelistSiteService; import org.springframework.stereotype.Service; /** * 白名单用户指定站点服务实现 */ @Service public class TAppUserWhitelistSiteServiceImpl extends ServiceImpl<TAppUserWhitelistSiteMapper, TAppUserWhitelistSite> implements TAppUserWhitelistSiteService { @Override public void deleteByWhitelistId(Long whitelistId) { this.baseMapper.deleteByWhitelistId(whitelistId); } } ruoyi-service/ruoyi-account/src/main/resources/mapper/account/TAppUserWhitelistMapper.xml
New file @@ -0,0 +1,48 @@ <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.ruoyi.account.mapper.TAppUserWhitelistMapper"> <resultMap id="BaseResultMap" type="com.ruoyi.account.api.model.TAppUserWhitelist"> <id column="id" property="id" /> <result column="app_user_id" property="appUserId" /> <result column="phone" property="phone" /> <result column="benefit_type" property="benefitType" /> <result column="scope_type" property="scopeType" /> <result column="partner_id" property="partnerId" /> <result column="status" property="status" /> <result column="create_by" property="createBy" /> <result column="create_time" property="createTime" /> <result column="update_by" property="updateBy" /> <result column="remark" property="remark" /> <result column="del_flag" property="delFlag" /> </resultMap> <sql id="Base_Column_List"> id, app_user_id, phone, benefit_type, scope_type, partner_id, status, create_by, create_time, update_by, update_time, remark, del_flag </sql> <select id="selectByPhoneIgnoreLogic" resultMap="BaseResultMap"> select <include refid="Base_Column_List" /> from t_app_user_whitelist where phone = #{phone} limit 1 </select> <update id="updateByIdIgnoreLogic"> update t_app_user_whitelist <set> app_user_id = #{appUserId}, phone = #{phone}, benefit_type = #{benefitType}, scope_type = #{scopeType}, partner_id = #{partnerId}, status = #{status}, update_by = #{updateBy}, update_time = now(), remark = #{remark}, del_flag = #{delFlag} </set> where id = #{id} </update> </mapper> ruoyi-service/ruoyi-account/src/main/resources/mapper/account/TAppUserWhitelistSiteMapper.xml
New file @@ -0,0 +1,20 @@ <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.ruoyi.account.mapper.TAppUserWhitelistSiteMapper"> <resultMap id="BaseResultMap" type="com.ruoyi.account.api.model.TAppUserWhitelistSite"> <id column="id" property="id" /> <result column="whitelist_id" property="whitelistId" /> <result column="site_id" property="siteId" /> <result column="create_time" property="createTime" /> <result column="del_flag" property="delFlag" /> </resultMap> <sql id="Base_Column_List"> id, whitelist_id, site_id, create_time, del_flag </sql> <delete id="deleteByWhitelistId"> delete from t_app_user_whitelist_site where whitelist_id = #{whitelistId} </delete> </mapper> ruoyi-service/ruoyi-chargingPile/src/main/resources/mapper/chargingPile/SiteMapper.xml
@@ -79,6 +79,12 @@ <if test="null != item.partnerName and '' != item.partnerName"> and b.name like CONCAT('%', #{item.partnerName}, '%') </if> <if test="null != item.partnerIds and item.partnerIds.size() > 0"> and a.partner_id in <foreach collection="item.partnerIds" item="partnerId" open="(" separator="," close=")"> #{partnerId} </foreach> </if> <if test="null != item.siteType"> and a.site_type = #{item.siteType} </if> @@ -315,4 +321,4 @@ </choose> </if> </select> </mapper> </mapper>