31 changed files with 765 additions and 18 deletions
-
18lottery-system/lottery-common/pom.xml
-
14lottery-system/lottery-common/src/main/java/com/lottery/constant/RedisCacheConstant.java
-
101lottery-system/lottery-common/src/main/java/com/lottery/utils/ExcelUtil.java
-
18lottery-system/lottery-pojo/pom.xml
-
27lottery-system/lottery-pojo/src/main/java/com/lottery/dto/PrizeDto.java
-
23lottery-system/lottery-pojo/src/main/java/com/lottery/dto/UserDto.java
-
22lottery-system/lottery-pojo/src/main/java/com/lottery/dto/UserImportDto.java
-
19lottery-system/lottery-pojo/src/main/java/com/lottery/dto/UserQueryDto.java
-
8lottery-system/lottery-pojo/src/main/java/com/lottery/entity/Prize.java
-
2lottery-system/lottery-pojo/src/main/java/com/lottery/vo/GradeVo.java
-
5lottery-system/lottery-pojo/src/main/java/com/lottery/vo/PrizeVo.java
-
16lottery-system/lottery-service/pom.xml
-
53lottery-system/lottery-service/src/main/java/com/lottery/admin/controller/AdminPrizeController.java
-
96lottery-system/lottery-service/src/main/java/com/lottery/admin/controller/AdminUserController.java
-
1lottery-system/lottery-service/src/main/java/com/lottery/admin/mapper/AdminGradeMapper.java
-
19lottery-system/lottery-service/src/main/java/com/lottery/admin/mapper/AdminPrizeMapper.java
-
23lottery-system/lottery-service/src/main/java/com/lottery/admin/mapper/AdminUserMapper.java
-
8lottery-system/lottery-service/src/main/java/com/lottery/admin/service/AdminPrizeService.java
-
34lottery-system/lottery-service/src/main/java/com/lottery/admin/service/AdminUserService.java
-
77lottery-system/lottery-service/src/main/java/com/lottery/admin/service/Impl/AdminPrizeServiceImpl.java
-
141lottery-system/lottery-service/src/main/java/com/lottery/admin/service/Impl/AdminUserServiceImpl.java
-
2lottery-system/lottery-service/src/main/java/com/lottery/api/controller/UserController.java
-
1lottery-system/lottery-service/src/main/java/com/lottery/api/mapper/IPrizeMapper.java
-
1lottery-system/lottery-service/src/main/java/com/lottery/api/service/IUserService.java
-
17lottery-system/lottery-service/src/main/java/com/lottery/api/service/Impl/UserServiceImpl.java
-
3lottery-system/lottery-service/src/main/resources/mapper/admin/AdminGradeMapper.xml
-
11lottery-system/lottery-service/src/main/resources/mapper/admin/AdminPrizeMapper.xml
-
6lottery-system/lottery-service/src/main/resources/mapper/admin/AdminUserMapper.xml
-
3lottery-system/lottery-service/src/main/resources/mapper/api/gradeMapper.xml
-
2lottery-system/lottery-service/src/main/resources/mapper/api/prizeMapper.xml
-
12lottery-system/pom.xml
@ -0,0 +1,14 @@ |
|||
package com.lottery.constant; |
|||
|
|||
/** |
|||
* @program: lottery |
|||
* @ClassName RedisCacheConstant |
|||
* @description: |
|||
* @author: wwl |
|||
* @create: 2025-07-15 17:59 |
|||
* @Version 1.0 |
|||
**/ |
|||
public class RedisCacheConstant { |
|||
|
|||
public static final String ALL_USER_CACHE = "all_user_cache"; |
|||
} |
@ -0,0 +1,101 @@ |
|||
package com.lottery.utils; |
|||
|
|||
import com.alibaba.excel.annotation.ExcelProperty; |
|||
import org.apache.poi.hssf.usermodel.HSSFWorkbook; |
|||
import org.apache.poi.ss.usermodel.*; |
|||
import org.apache.poi.xssf.usermodel.XSSFWorkbook; |
|||
import org.springframework.web.multipart.MultipartFile; |
|||
|
|||
import java.io.InputStream; |
|||
import java.lang.reflect.Field; |
|||
import java.util.ArrayList; |
|||
import java.util.HashMap; |
|||
import java.util.List; |
|||
import java.util.Map; |
|||
|
|||
/** |
|||
* @program: lottery |
|||
* @ClassName ExcelUtil |
|||
* @description: |
|||
* @author: wwl |
|||
* @create: 2025-07-15 16:32 |
|||
* @Version 1.0 |
|||
**/ |
|||
|
|||
public class ExcelUtil { |
|||
public static <T> List<T> parseExcel(MultipartFile file, Class<T> clazz) throws Exception { |
|||
try (InputStream inputStream = file.getInputStream()) { |
|||
Workbook workbook = WorkbookFactory.create(inputStream); |
|||
Sheet sheet = workbook.getSheetAt(0); |
|||
|
|||
// 获取表头映射 |
|||
Row headerRow = sheet.getRow(0); |
|||
Map<String, Integer> headerMap = new HashMap<>(); |
|||
for (Cell cell : headerRow) { |
|||
headerMap.put(cell.getStringCellValue().trim(), cell.getColumnIndex()); |
|||
} |
|||
|
|||
// 验证必要列是否存在 |
|||
for (Field field : clazz.getDeclaredFields()) { |
|||
ExcelProperty annotation = field.getAnnotation(ExcelProperty.class); |
|||
if (annotation != null && !headerMap.containsKey(annotation.value()[0])) { |
|||
throw new IllegalArgumentException("缺少必要列: " + annotation.value()[0]); |
|||
} |
|||
} |
|||
|
|||
// 读取数据 |
|||
List<T> dataList = new ArrayList<>(); |
|||
for (int i = 1; i <= sheet.getLastRowNum(); i++) { |
|||
Row row = sheet.getRow(i); |
|||
if (row == null) continue; |
|||
|
|||
T dto = clazz.getDeclaredConstructor().newInstance(); |
|||
boolean hasValue = false; |
|||
|
|||
for (Field field : clazz.getDeclaredFields()) { |
|||
ExcelProperty annotation = field.getAnnotation(ExcelProperty.class); |
|||
if (annotation != null) { |
|||
String headerName = annotation.value()[0]; |
|||
Integer colIndex = headerMap.get(headerName); |
|||
if (colIndex != null) { |
|||
Cell cell = row.getCell(colIndex); |
|||
Object value = getCellValue(cell); |
|||
if (value != null) { |
|||
field.setAccessible(true); |
|||
field.set(dto, value); |
|||
hasValue = true; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
if (hasValue) { |
|||
dataList.add(dto); |
|||
} |
|||
} |
|||
|
|||
return dataList; |
|||
} |
|||
} |
|||
|
|||
private static Object getCellValue(Cell cell) { |
|||
if (cell == null) return null; |
|||
|
|||
switch (cell.getCellType()) { |
|||
case STRING: |
|||
return cell.getStringCellValue().trim(); |
|||
case NUMERIC: |
|||
if (DateUtil.isCellDateFormatted(cell)) { |
|||
return cell.getDateCellValue(); |
|||
} |
|||
return cell.getNumericCellValue(); |
|||
case BOOLEAN: |
|||
return cell.getBooleanCellValue(); |
|||
case FORMULA: |
|||
return cell.getCellFormula(); |
|||
default: |
|||
return null; |
|||
} |
|||
} |
|||
} |
|||
|
@ -0,0 +1,27 @@ |
|||
package com.lottery.dto; |
|||
|
|||
import lombok.AllArgsConstructor; |
|||
import lombok.Data; |
|||
import lombok.NoArgsConstructor; |
|||
|
|||
/** |
|||
* @program: lottery |
|||
* @ClassName PrizeDto |
|||
* @description: |
|||
* @author: wwl |
|||
* @create: 2025-07-15 11:56 |
|||
* @Version 1.0 |
|||
**/ |
|||
@Data |
|||
@AllArgsConstructor |
|||
@NoArgsConstructor |
|||
public class PrizeDto { |
|||
|
|||
private Long id; |
|||
|
|||
private String prizeName; |
|||
|
|||
private String gradeName; |
|||
|
|||
private String imageUrl; |
|||
} |
@ -0,0 +1,23 @@ |
|||
package com.lottery.dto; |
|||
|
|||
import lombok.Builder; |
|||
import lombok.Data; |
|||
|
|||
/** |
|||
* @program: lottery |
|||
* @ClassName UserDto |
|||
* @description: |
|||
* @author: wwl |
|||
* @create: 2025-07-15 15:12 |
|||
* @Version 1.0 |
|||
**/ |
|||
|
|||
@Data |
|||
@Builder |
|||
public class UserDto { |
|||
private int id; |
|||
|
|||
private String username; |
|||
|
|||
private String jwcode; |
|||
} |
@ -0,0 +1,22 @@ |
|||
package com.lottery.dto; |
|||
|
|||
import com.alibaba.excel.annotation.ExcelProperty; |
|||
import lombok.Data; |
|||
|
|||
/** |
|||
* @program: lottery |
|||
* @ClassName UserImportDto |
|||
* @description: |
|||
* @author: wwl |
|||
* @create: 2025-07-15 16:27 |
|||
* @Version 1.0 |
|||
**/ |
|||
@Data |
|||
public class UserImportDto { |
|||
|
|||
@ExcelProperty("姓名") |
|||
private String username; |
|||
|
|||
@ExcelProperty("精网号") |
|||
private String jwcode; |
|||
} |
@ -0,0 +1,19 @@ |
|||
package com.lottery.dto; |
|||
|
|||
import lombok.Data; |
|||
|
|||
/** |
|||
* @program: lottery |
|||
* @ClassName UserQueryDto |
|||
* @description: |
|||
* @author: wwl |
|||
* @create: 2025-07-15 16:03 |
|||
* @Version 1.0 |
|||
**/ |
|||
@Data |
|||
public class UserQueryDto { |
|||
|
|||
private String username; |
|||
|
|||
private String jwcode; |
|||
} |
@ -0,0 +1,96 @@ |
|||
package com.lottery.admin.controller; |
|||
|
|||
import com.lottery.admin.service.AdminUserService; |
|||
import com.lottery.dto.UserDto; |
|||
import com.lottery.dto.UserImportDto; |
|||
import com.lottery.dto.UserQueryDto; |
|||
import com.lottery.entity.User; |
|||
import com.lottery.result.Result; |
|||
import com.lottery.utils.ConvertBeanUtil; |
|||
import com.lottery.utils.ExcelUtil; |
|||
import com.lottery.vo.PageInfo; |
|||
import com.lottery.vo.UserVo; |
|||
import org.slf4j.Logger; |
|||
import org.slf4j.LoggerFactory; |
|||
import org.springframework.beans.factory.annotation.Autowired; |
|||
import org.springframework.web.bind.annotation.*; |
|||
import org.springframework.web.multipart.MultipartFile; |
|||
|
|||
import java.util.*; |
|||
import java.util.stream.Collectors; |
|||
|
|||
/** |
|||
* @program: lottery |
|||
* @ClassName AdminUserController |
|||
* @description: |
|||
* @author: wwl |
|||
* @create: 2025-07-15 14:56 |
|||
* @Version 1.0 |
|||
**/ |
|||
|
|||
@RestController |
|||
@RequestMapping("/admin/user") |
|||
public class AdminUserController { |
|||
|
|||
@Autowired |
|||
private AdminUserService adminUserService; |
|||
|
|||
private final static Logger LOGGER = LoggerFactory.getLogger(AdminUserController.class); |
|||
|
|||
@PostMapping("/add") |
|||
public Result add(@RequestBody UserDto userDto) { |
|||
|
|||
LOGGER.info("新增用户:{}",userDto); |
|||
if (userDto.getUsername() == null || userDto.getJwcode() == null) { |
|||
return Result.failure("所有字段都必须填写"); |
|||
} |
|||
adminUserService.addUser(userDto); |
|||
return Result.success(); |
|||
} |
|||
|
|||
@PostMapping("/list") |
|||
public Result<PageInfo<UserVo>> getAllUser(@RequestParam(defaultValue = "1") int pageNum, @RequestParam(defaultValue = "10") int pageSize, |
|||
@RequestBody UserQueryDto userQueryDto ){ |
|||
LOGGER.info("分页查询所有用户"); |
|||
|
|||
return Result.success(adminUserService.listUser(pageNum,pageSize,userQueryDto)); |
|||
} |
|||
|
|||
|
|||
|
|||
@GetMapping() |
|||
|
|||
@DeleteMapping("/delete") |
|||
public Result delete(@RequestParam Long id) { |
|||
LOGGER.info("根据id删除用户:{}",id); |
|||
adminUserService.removeById(id); |
|||
return Result.success(); |
|||
} |
|||
|
|||
@DeleteMapping("/delete/batch") |
|||
public Result deleteBatch(@RequestParam List<Long> ids) { |
|||
LOGGER.info("批量删除用户:{}",ids); |
|||
if (ids == null || ids.size() == 0) { |
|||
return Result.failure("ids is null"); |
|||
} |
|||
adminUserService.removeBatchByIds(ids); |
|||
return Result.success(); |
|||
} |
|||
|
|||
@PostMapping("/import") |
|||
public Result importUsers(@RequestParam("file") MultipartFile file) { |
|||
LOGGER.info("开始导入用户Excel文件: {}", file.getOriginalFilename()); |
|||
|
|||
// 1. 基本文件校验 |
|||
if (file.isEmpty()) { |
|||
return Result.failure("请上传文件"); |
|||
} |
|||
|
|||
String fileName = file.getOriginalFilename(); |
|||
if (!fileName.endsWith(".xlsx") && !fileName.endsWith(".xls")) { |
|||
return Result.failure("仅支持Excel文件(.xlsx, .xls)"); |
|||
} |
|||
return adminUserService.importUsers(file); |
|||
} |
|||
|
|||
} |
@ -0,0 +1,19 @@ |
|||
package com.lottery.admin.mapper; |
|||
|
|||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
|||
import com.baomidou.mybatisplus.core.mapper.BaseMapper; |
|||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; |
|||
import com.lottery.entity.Prize; |
|||
|
|||
/** |
|||
* @program: lottery |
|||
* @ClassName AdminPrizeMapper |
|||
* @description: |
|||
* @author: wwl |
|||
* @create: 2025-07-15 15:00 |
|||
* @Version 1.0 |
|||
**/ |
|||
public interface AdminPrizeMapper extends BaseMapper<Prize> { |
|||
|
|||
Page<Prize> pageListPrize(Page<Prize> page, LambdaQueryWrapper<Prize> prizeLambdaQueryWrapper); |
|||
} |
@ -0,0 +1,23 @@ |
|||
package com.lottery.admin.mapper; |
|||
|
|||
import com.baomidou.mybatisplus.core.mapper.BaseMapper; |
|||
import com.lottery.entity.User; |
|||
import org.apache.ibatis.annotations.Mapper; |
|||
import org.apache.ibatis.annotations.Select; |
|||
|
|||
import java.util.Set; |
|||
|
|||
/** |
|||
* @program: lottery |
|||
* @ClassName AdminUserMapper |
|||
* @description: |
|||
* @author: wwl |
|||
* @create: 2025-07-15 14:59 |
|||
* @Version 1.0 |
|||
**/ |
|||
@Mapper |
|||
public interface AdminUserMapper extends BaseMapper<User> { |
|||
|
|||
@Select("select jwcode from user") |
|||
Set<String> selectAllUserCodes(); |
|||
} |
@ -0,0 +1,34 @@ |
|||
package com.lottery.admin.service; |
|||
|
|||
import com.baomidou.mybatisplus.extension.service.IService; |
|||
import com.lottery.dto.UserDto; |
|||
import com.lottery.dto.UserQueryDto; |
|||
import com.lottery.entity.User; |
|||
import com.lottery.result.Result; |
|||
import com.lottery.vo.PageInfo; |
|||
import com.lottery.vo.UserVo; |
|||
import org.springframework.stereotype.Service; |
|||
import org.springframework.web.multipart.MultipartFile; |
|||
|
|||
import java.util.List; |
|||
|
|||
/** |
|||
* @program: lottery |
|||
* @ClassName AdminUserService |
|||
* @description: |
|||
* @author: wwl |
|||
* @create: 2025-07-15 14:57 |
|||
* @Version 1.0 |
|||
**/ |
|||
|
|||
@Service |
|||
public interface AdminUserService extends IService<User> { |
|||
void addUser(UserDto userDto); |
|||
|
|||
|
|||
PageInfo<UserVo> listUser(int pageNum, int pageSize, UserQueryDto userQueryDto); |
|||
|
|||
|
|||
Result importUsers(MultipartFile file); |
|||
} |
|||
|
@ -0,0 +1,141 @@ |
|||
package com.lottery.admin.service.Impl; |
|||
|
|||
import com.alibaba.excel.EasyExcel; |
|||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
|||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; |
|||
import com.baomidou.mybatisplus.core.toolkit.StringUtils; |
|||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; |
|||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; |
|||
import com.lottery.admin.controller.AdminUserController; |
|||
import com.lottery.admin.mapper.AdminUserMapper; |
|||
import com.lottery.admin.service.AdminUserService; |
|||
import com.lottery.api.service.Impl.UserServiceImpl; |
|||
import com.lottery.dto.UserDto; |
|||
import com.lottery.dto.UserImportDto; |
|||
import com.lottery.dto.UserQueryDto; |
|||
import com.lottery.entity.Grade; |
|||
import com.lottery.entity.User; |
|||
import com.lottery.result.Result; |
|||
import com.lottery.utils.ConvertBeanUtil; |
|||
import com.lottery.utils.ExcelUtil; |
|||
import com.lottery.vo.PageInfo; |
|||
import com.lottery.vo.UserVo; |
|||
import org.slf4j.Logger; |
|||
import org.slf4j.LoggerFactory; |
|||
import org.springframework.beans.factory.annotation.Autowired; |
|||
import org.springframework.boot.context.properties.ConfigurationProperties; |
|||
import org.springframework.stereotype.Service; |
|||
import org.springframework.transaction.annotation.Transactional; |
|||
import org.springframework.web.multipart.MultipartFile; |
|||
|
|||
import java.util.*; |
|||
|
|||
/** |
|||
* @program: lottery |
|||
* @ClassName AdminUserServiceImpl |
|||
* @description: |
|||
* @author: wwl |
|||
* @create: 2025-07-15 14:58 |
|||
* @Version 1.0 |
|||
**/ |
|||
@Service |
|||
public class AdminUserServiceImpl extends ServiceImpl<AdminUserMapper, User> implements AdminUserService { |
|||
|
|||
@Autowired |
|||
private AdminUserMapper adminUserMapper; |
|||
private final static Logger LOGGER = LoggerFactory.getLogger(AdminUserController.class); |
|||
|
|||
@Override |
|||
public void addUser(UserDto userDto) { |
|||
this.save(ConvertBeanUtil.convert(userDto, User.class)); |
|||
} |
|||
|
|||
@Override |
|||
public PageInfo<UserVo> listUser(int pageNum, int pageSize, UserQueryDto userQueryDto) { |
|||
Page<User> page = new Page<>(pageNum, pageSize); |
|||
|
|||
LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>(); |
|||
|
|||
if (StringUtils.isNotBlank(userQueryDto.getUsername())) { |
|||
queryWrapper.like(User::getUsername, userQueryDto.getUsername()); |
|||
} |
|||
if(StringUtils.isNotBlank(userQueryDto.getJwcode())){ |
|||
queryWrapper.like(User::getJwcode, userQueryDto.getJwcode()); |
|||
} |
|||
|
|||
Page<User> userPage = this.page(page, queryWrapper); |
|||
List<UserVo> userVolist = ConvertBeanUtil.convertList(userPage.getRecords(), UserVo.class); |
|||
return PageInfo.of(userPage, userVolist); |
|||
} |
|||
|
|||
@Override |
|||
public Result importUsers(MultipartFile file) { |
|||
|
|||
try { |
|||
// 2. 解析Excel |
|||
// List<UserImportDto> userDtos = ExcelUtil.parseExcel(file, UserImportDto.class); |
|||
List<UserImportDto> userDtos = EasyExcel.read(file.getInputStream()) |
|||
.head(UserImportDto.class) |
|||
.sheet() |
|||
.doReadSync(); |
|||
|
|||
// 3. 数据校验和去重 |
|||
Set<String> existingCodes = adminUserMapper.selectAllUserCodes(); // 查询已存在的精网号 |
|||
List<User> users = new ArrayList<>(); |
|||
Set<String> processedCodes = new HashSet<>(); // 用于当前文件内的去重 |
|||
|
|||
for (int i = 0; i < userDtos.size(); i++) { |
|||
UserImportDto dto = userDtos.get(i); |
|||
try { |
|||
validateUser(dto, i + 2, existingCodes, processedCodes); // i+2对应Excel行号 |
|||
users.add(convertToEntity(dto)); |
|||
processedCodes.add(dto.getJwcode()); |
|||
} catch (IllegalArgumentException e) { |
|||
LOGGER.warn("导入数据校验失败: {}", e.getMessage()); |
|||
} |
|||
} |
|||
|
|||
// 4. 批量保存 |
|||
if (!users.isEmpty()) { |
|||
boolean success = this.saveBatch(users); |
|||
return success ? |
|||
Result.success(String.format("导入成功%d条,跳过%d条", users.size(), userDtos.size() - users.size())) : |
|||
Result.failure("部分数据导入失败"); |
|||
} |
|||
return Result.failure("没有有效数据可导入"); |
|||
} catch (Exception e) { |
|||
LOGGER.error("导入用户失败", e); |
|||
return Result.failure("导入失败: " + e.getMessage()); |
|||
} |
|||
} |
|||
|
|||
private User convertToEntity(UserImportDto dto) { |
|||
User user = new User(); |
|||
user.setJwcode(dto.getJwcode()); |
|||
user.setUsername(dto.getUsername()); |
|||
user.setCreateTime(new Date()); |
|||
user.setUpdateTime(new Date()); |
|||
// 设置默认密码 |
|||
user.setPassword("123456"); |
|||
return user; |
|||
} |
|||
|
|||
private void validateUser(UserImportDto dto, int rowNum, Set<String> existingCodes, Set<String> processedCodes) { |
|||
if (StringUtils.isBlank(dto.getJwcode())) { |
|||
throw new IllegalArgumentException("第" + rowNum + "行: 精网号不能为空"); |
|||
} |
|||
|
|||
if (StringUtils.isBlank(dto.getUsername())) { |
|||
throw new IllegalArgumentException("第" + rowNum + "行: 姓名不能为空"); |
|||
} |
|||
|
|||
if (existingCodes.contains(dto.getJwcode())) { |
|||
throw new IllegalArgumentException("第" + rowNum + "行: 精网号已存在"); |
|||
} |
|||
|
|||
if (processedCodes.contains(dto.getJwcode())) { |
|||
throw new IllegalArgumentException("第" + rowNum + "行: 精网号在当前文件中重复"); |
|||
} |
|||
} |
|||
} |
|||
|
@ -0,0 +1,11 @@ |
|||
<?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.lottery.admin.mapper.AdminPrizeMapper"> |
|||
|
|||
<select id="pageListPrize" resultType="com.lottery.entity.Prize"> |
|||
select p.*, g.grade_name |
|||
from prize p |
|||
left join grade g on p.grade_id = g.id |
|||
order by g.sort desc |
|||
</select> |
|||
</mapper> |
@ -0,0 +1,6 @@ |
|||
<?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.lottery.admin.mapper.AdminUserMapper"> |
|||
|
|||
|
|||
</mapper> |
Write
Preview
Loading…
Cancel
Save
Reference in new issue