Browse Source

Merge branch 'milestone-20250723-wwl' into jihaipeng/feature-20250714184358-抽奖众筹

feature/0725lihuilin
jihaipeng 1 month ago
parent
commit
2b4bfe7c48
  1. 124
      .idea/uiDesigner.xml
  2. 30
      lottery-system/lottery-common/src/main/java/com/lottery/utils/LoginHttpUtils.java
  3. 17
      lottery-system/lottery-pojo/src/main/java/com/lottery/dto/AdminLogin.java
  4. 21
      lottery-system/lottery-pojo/src/main/java/com/lottery/dto/FixUserDto.java
  5. 2
      lottery-system/lottery-pojo/src/main/java/com/lottery/dto/GradeDto.java
  6. 20
      lottery-system/lottery-pojo/src/main/java/com/lottery/dto/StartLotteryDto.java
  7. 32
      lottery-system/lottery-pojo/src/main/java/com/lottery/entity/UserDetail.java
  8. 1
      lottery-system/lottery-service/pom.xml
  9. 4
      lottery-system/lottery-service/src/main/java/com/lottery/admin/controller/AdminGradeController.java
  10. 16
      lottery-system/lottery-service/src/main/java/com/lottery/admin/controller/AdminPrizeController.java
  11. 65
      lottery-system/lottery-service/src/main/java/com/lottery/admin/controller/AdminUserController.java
  12. 1
      lottery-system/lottery-service/src/main/java/com/lottery/admin/mapper/AdminGradeMapper.java
  13. 23
      lottery-system/lottery-service/src/main/java/com/lottery/admin/mapper/AdminUserDetailMapper.java
  14. 2
      lottery-system/lottery-service/src/main/java/com/lottery/admin/mapper/AdminUserMapper.java
  15. 4
      lottery-system/lottery-service/src/main/java/com/lottery/admin/service/AdminPrizeService.java
  16. 25
      lottery-system/lottery-service/src/main/java/com/lottery/admin/service/AdminUserDetailService.java
  17. 10
      lottery-system/lottery-service/src/main/java/com/lottery/admin/service/AdminUserService.java
  18. 39
      lottery-system/lottery-service/src/main/java/com/lottery/admin/service/Impl/AdminPrizeServiceImpl.java
  19. 180
      lottery-system/lottery-service/src/main/java/com/lottery/admin/service/Impl/AdminUserDetailServiceImpl.java
  20. 52
      lottery-system/lottery-service/src/main/java/com/lottery/admin/service/Impl/AdminUserServiceImpl.java
  21. 39
      lottery-system/lottery-service/src/main/java/com/lottery/api/controller/LotteryController.java
  22. 3
      lottery-system/lottery-service/src/main/java/com/lottery/api/mapper/IGradeMapper.java
  23. 18
      lottery-system/lottery-service/src/main/java/com/lottery/api/mapper/IUserDetailMapper.java
  24. 17
      lottery-system/lottery-service/src/main/java/com/lottery/api/service/IUserDetailService.java
  25. 129
      lottery-system/lottery-service/src/main/java/com/lottery/api/service/Impl/UserDetailServiceImpl.java
  26. 2
      lottery-system/lottery-service/src/main/java/com/lottery/api/service/Impl/UserServiceImpl.java
  27. 13
      lottery-system/lottery-service/src/main/resources/application.yml
  28. 6
      lottery-system/lottery-service/src/main/resources/mapper/admin/AdminUserDetailMapper.xml
  29. 3
      lottery-system/lottery-service/src/main/resources/mapper/admin/AdminUserMapper.xml
  30. 3
      lottery-system/lottery-service/src/main/resources/mapper/api/gradeMapper.xml
  31. 6
      lottery-system/lottery-service/src/main/resources/mapper/api/userDetailMapper.xml
  32. 6
      lottery-system/pom.xml

124
.idea/uiDesigner.xml

@ -0,0 +1,124 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Palette2">
<group name="Swing">
<item class="com.intellij.uiDesigner.HSpacer" tooltip-text="Horizontal Spacer" icon="/com/intellij/uiDesigner/icons/hspacer.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="1" hsize-policy="6" anchor="0" fill="1" />
</item>
<item class="com.intellij.uiDesigner.VSpacer" tooltip-text="Vertical Spacer" icon="/com/intellij/uiDesigner/icons/vspacer.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="1" anchor="0" fill="2" />
</item>
<item class="javax.swing.JPanel" icon="/com/intellij/uiDesigner/icons/panel.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3" />
</item>
<item class="javax.swing.JScrollPane" icon="/com/intellij/uiDesigner/icons/scrollPane.svg" removable="false" auto-create-binding="false" can-attach-label="true">
<default-constraints vsize-policy="7" hsize-policy="7" anchor="0" fill="3" />
</item>
<item class="javax.swing.JButton" icon="/com/intellij/uiDesigner/icons/button.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="3" anchor="0" fill="1" />
<initial-values>
<property name="text" value="Button" />
</initial-values>
</item>
<item class="javax.swing.JRadioButton" icon="/com/intellij/uiDesigner/icons/radioButton.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
<initial-values>
<property name="text" value="RadioButton" />
</initial-values>
</item>
<item class="javax.swing.JCheckBox" icon="/com/intellij/uiDesigner/icons/checkBox.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
<initial-values>
<property name="text" value="CheckBox" />
</initial-values>
</item>
<item class="javax.swing.JLabel" icon="/com/intellij/uiDesigner/icons/label.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="0" anchor="8" fill="0" />
<initial-values>
<property name="text" value="Label" />
</initial-values>
</item>
<item class="javax.swing.JTextField" icon="/com/intellij/uiDesigner/icons/textField.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
<preferred-size width="150" height="-1" />
</default-constraints>
</item>
<item class="javax.swing.JPasswordField" icon="/com/intellij/uiDesigner/icons/passwordField.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
<preferred-size width="150" height="-1" />
</default-constraints>
</item>
<item class="javax.swing.JFormattedTextField" icon="/com/intellij/uiDesigner/icons/formattedTextField.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
<preferred-size width="150" height="-1" />
</default-constraints>
</item>
<item class="javax.swing.JTextArea" icon="/com/intellij/uiDesigner/icons/textArea.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JTextPane" icon="/com/intellij/uiDesigner/icons/textPane.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JEditorPane" icon="/com/intellij/uiDesigner/icons/editorPane.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JComboBox" icon="/com/intellij/uiDesigner/icons/comboBox.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="2" anchor="8" fill="1" />
</item>
<item class="javax.swing.JTable" icon="/com/intellij/uiDesigner/icons/table.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JList" icon="/com/intellij/uiDesigner/icons/list.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="2" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JTree" icon="/com/intellij/uiDesigner/icons/tree.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JTabbedPane" icon="/com/intellij/uiDesigner/icons/tabbedPane.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
<preferred-size width="200" height="200" />
</default-constraints>
</item>
<item class="javax.swing.JSplitPane" icon="/com/intellij/uiDesigner/icons/splitPane.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
<preferred-size width="200" height="200" />
</default-constraints>
</item>
<item class="javax.swing.JSpinner" icon="/com/intellij/uiDesigner/icons/spinner.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
</item>
<item class="javax.swing.JSlider" icon="/com/intellij/uiDesigner/icons/slider.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
</item>
<item class="javax.swing.JSeparator" icon="/com/intellij/uiDesigner/icons/separator.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3" />
</item>
<item class="javax.swing.JProgressBar" icon="/com/intellij/uiDesigner/icons/progressbar.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1" />
</item>
<item class="javax.swing.JToolBar" icon="/com/intellij/uiDesigner/icons/toolbar.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1">
<preferred-size width="-1" height="20" />
</default-constraints>
</item>
<item class="javax.swing.JToolBar$Separator" icon="/com/intellij/uiDesigner/icons/toolbarSeparator.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="0" anchor="0" fill="1" />
</item>
<item class="javax.swing.JScrollBar" icon="/com/intellij/uiDesigner/icons/scrollbar.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="0" anchor="0" fill="2" />
</item>
</group>
</component>
</project>

30
lottery-system/lottery-common/src/main/java/com/lottery/utils/LoginHttpUtils.java

@ -0,0 +1,30 @@
//package com.lottery.utils;
//
//import org.springframework.stereotype.Component;
//
///**
// * @program: lottery
// * @ClassName LoginHttpUtils
// * @description:
// * @author: wwl
// * @create: 2025-07-16 10:07
// * @Version 1.0
// **/
//
//@Component
//public class LoginHttpUtils {
// private final RestTemplate restTemplate;
//
// public HttpUtil(RestTemplateBuilder restTemplateBuilder) {
// this.restTemplate = restTemplateBuilder.build();
// }
//
// public <T> T post(String url, Object request, Class<T> responseType) {
// HttpHeaders headers = new HttpHeaders();
// headers.setContentType(MediaType.APPLICATION_JSON);
// HttpEntity<Object> entity = new HttpEntity<>(request, headers);
//
// ResponseEntity<T> response = restTemplate.postForEntity(url, entity, responseType);
// return response.getBody();
// }
//}

17
lottery-system/lottery-pojo/src/main/java/com/lottery/dto/AdminLogin.java

@ -0,0 +1,17 @@
package com.lottery.dto;
import lombok.Data;
/**
* @program: lottery
* @ClassName AdminLogin
* @description:
* @author: wwl
* @create: 2025-07-16 10:19
* @Version 1.0
**/
@Data
public class AdminLogin {
private String username;
private String password;
}

21
lottery-system/lottery-pojo/src/main/java/com/lottery/dto/FixUserDto.java

@ -0,0 +1,21 @@
package com.lottery.dto;
import lombok.Data;
/**
* @program: lottery
* @ClassName WinUserDto
* @description:
* @author: wwl
* @create: 2025-07-16 14:01
* @Version 1.0
**/
@Data
public class FixUserDto {
private String username;
private String jwcode;
private String GradeName;
}

2
lottery-system/lottery-pojo/src/main/java/com/lottery/dto/GradeDto.java

@ -16,7 +16,7 @@ public class GradeDto {
private Long id;
private String GradeName; // 等级名称
private String gradeName; // 等级名称
private Integer amount; //等级数量

20
lottery-system/lottery-pojo/src/main/java/com/lottery/dto/StartLotteryDto.java

@ -0,0 +1,20 @@
package com.lottery.dto;
import lombok.Data;
/**
* @program: lottery
* @ClassName StartLotteryDto
* @description:
* @author: wwl
* @create: 2025-07-16 16:49
* @Version 1.0
**/
@Data
public class StartLotteryDto {
private int perWin;
private String gradeName;
private String PrizeName;
}

32
lottery-system/lottery-pojo/src/main/java/com/lottery/entity/UserDetail.java

@ -0,0 +1,32 @@
package com.lottery.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* @program: lottery
* @ClassName UserDetail
* @description:
* @author: wwl
* @create: 2025-07-16 9:32
* @Version 1.0
**/
@Data
@AllArgsConstructor
@NoArgsConstructor
@TableName("user_detail")
public class UserDetail {
@TableId(type = IdType.AUTO)
private Long id; // 主键ID表中未显示但建议添加
private Long userId;
private Long gradeId;
private int isFixed;
}

1
lottery-system/lottery-service/pom.xml

@ -17,6 +17,7 @@
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.lottery</groupId>
<artifactId>lottery-pojo</artifactId>

4
lottery-system/lottery-service/src/main/java/com/lottery/admin/controller/AdminGradeController.java

@ -75,7 +75,7 @@ public class AdminGradeController {
}
@PutMapping("/update")
@PostMapping("/update")
public Result update(@RequestBody GradeDto gradeDto){
if (gradeDto.getGradeName() == null || gradeDto.getAmount() == null||
@ -96,7 +96,7 @@ public class AdminGradeController {
}
@DeleteMapping("/delete")
@PostMapping("/delete")
public Result delete(@RequestParam Long id){
LOGGER.info("删除id为:{} 的等级" ,id);
if (!adminGradeService.removeById(id)){

16
lottery-system/lottery-service/src/main/java/com/lottery/admin/controller/AdminPrizeController.java

@ -2,6 +2,7 @@ package com.lottery.admin.controller;
import com.lottery.admin.service.AdminPrizeService;
import com.lottery.dto.PrizeDto;
import com.lottery.dto.FixUserDto;
import com.lottery.result.Result;
import com.lottery.vo.PageInfo;
import com.lottery.vo.PrizeVo;
@ -50,10 +51,11 @@ public class AdminPrizeController {
if(!adminPrizeService.add(prizeDto)){
return Result.failure("该等级下已有礼物");
};
//TODO 新增的时候选择不存在的等级给前端返回错误信息
return Result.success();
}
@PutMapping("/update")
@PostMapping("/update")
public Result updatePrize(@RequestBody PrizeDto prizeDto) {
LOGGER.info("修改奖品信息:{}",prizeDto);
if (prizeDto.getPrizeName() == null || prizeDto.getImageUrl() == null||
@ -68,10 +70,12 @@ public class AdminPrizeController {
if(!adminPrizeService.updatePrize(prizeDto)){
return Result.failure("该等级下已有礼物");
};
//TODO 修改的时候选择不存在的等级给前端返回错误信息
return Result.success();
}
@DeleteMapping("/delete")
@PostMapping("/delete")
public Result deletePrize(@RequestParam Long id) {
LOGGER.info("根基id:{},删除奖品",id);
if (!adminPrizeService.removeById(id)){
@ -80,5 +84,13 @@ public class AdminPrizeController {
return Result.success();
}
@PostMapping("/addFixUser")
public Result addWinUser(@RequestBody FixUserDto fixUserDto) {
if (fixUserDto.getUsername() == null || fixUserDto.getJwcode() == null) {
return Result.failure("所有字段都必须填写");
}
adminPrizeService.addWinUser(fixUserDto);
return Result.success();
}
}

65
lottery-system/lottery-service/src/main/java/com/lottery/admin/controller/AdminUserController.java

@ -1,6 +1,8 @@
package com.lottery.admin.controller;
import com.lottery.admin.service.AdminUserDetailService;
import com.lottery.admin.service.AdminUserService;
import com.lottery.dto.AdminLogin;
import com.lottery.dto.UserDto;
import com.lottery.dto.UserImportDto;
import com.lottery.dto.UserQueryDto;
@ -10,6 +12,7 @@ import com.lottery.utils.ConvertBeanUtil;
import com.lottery.utils.ExcelUtil;
import com.lottery.vo.PageInfo;
import com.lottery.vo.UserVo;
import org.apache.logging.log4j.util.PerformanceSensitive;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
@ -35,6 +38,9 @@ public class AdminUserController {
@Autowired
private AdminUserService adminUserService;
@Autowired
private AdminUserDetailService adminUserDetailService;
private final static Logger LOGGER = LoggerFactory.getLogger(AdminUserController.class);
@PostMapping("/add")
@ -44,7 +50,9 @@ public class AdminUserController {
if (userDto.getUsername() == null || userDto.getJwcode() == null) {
return Result.failure("所有字段都必须填写");
}
adminUserService.addUser(userDto);
if (!adminUserService.addUser(userDto)){
return Result.failure("精网号已存在,无法添加");
}
return Result.success();
}
@ -58,16 +66,14 @@ public class AdminUserController {
@GetMapping()
@DeleteMapping("/delete")
@PostMapping("/delete")
public Result delete(@RequestParam Long id) {
LOGGER.info("根据id删除用户:{}",id);
adminUserService.removeById(id);
return Result.success();
}
@DeleteMapping("/delete/batch")
@PostMapping("/delete/batch")
public Result deleteBatch(@RequestParam List<Long> ids) {
LOGGER.info("批量删除用户:{}",ids);
if (ids == null || ids.size() == 0) {
@ -93,4 +99,53 @@ public class AdminUserController {
return adminUserService.importUsers(file);
}
@PostMapping("/login")
public Result login(@RequestBody AdminLogin adminLogin) {
LOGGER.info("管理员登录:{}",adminLogin);
return adminUserService.AdminUserlogin(adminLogin);
}
@PostMapping("/list/fix")
public Result<PageInfo<UserVo>> getAllFixUser(@RequestParam(defaultValue = "1") int pageNum, @RequestParam(defaultValue = "10") int pageSize,
@RequestBody UserQueryDto userQueryDto ){
LOGGER.info("分页查询所有内定用户");
return Result.success(adminUserDetailService.listFixUser(pageNum,pageSize,userQueryDto));
}
@PostMapping("/delete/fix")
public Result deleteFix(@RequestParam Long id) {
LOGGER.info("根据id删除内定用户:{}",id);
adminUserDetailService.removeById(id);
return Result.success();
}
@PostMapping("/delete/fix/batch")
public Result deleteBatchFix(@RequestParam List<Long> ids) {
LOGGER.info("批量删除内定用户:{}",ids);
if (ids == null || ids.size() == 0) {
return Result.failure("ids is null");
}
adminUserDetailService.removeBatchByIds(ids);
return Result.success();
}
@PostMapping("/import/fix")
public Result importFixUsers(@RequestParam("file") MultipartFile file, @RequestParam String gradeName) {
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 adminUserDetailService.importUsers(file,gradeName);
}
}

1
lottery-system/lottery-service/src/main/java/com/lottery/admin/mapper/AdminGradeMapper.java

@ -16,4 +16,5 @@ import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface AdminGradeMapper extends BaseMapper<Grade> {
Grade selectByName(String gradeName);
}

23
lottery-system/lottery-service/src/main/java/com/lottery/admin/mapper/AdminUserDetailMapper.java

@ -0,0 +1,23 @@
package com.lottery.admin.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.lottery.entity.UserDetail;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;
import java.util.Set;
/**
* @program: lottery
* @ClassName IUserDetailMapper
* @description:
* @author: wwl
* @create: 2025-07-16 9:47
* @Version 1.0
**/
@Mapper
public interface AdminUserDetailMapper extends BaseMapper<UserDetail> {
@Select("select jwcode from user_detail")
Set<String> selectAllUserCodes();
}

2
lottery-system/lottery-service/src/main/java/com/lottery/admin/mapper/AdminUserMapper.java

@ -20,4 +20,6 @@ public interface AdminUserMapper extends BaseMapper<User> {
@Select("select jwcode from user")
Set<String> selectAllUserCodes();
Long selectByJwcode(String jwcode);
}

4
lottery-system/lottery-service/src/main/java/com/lottery/admin/service/AdminPrizeService.java

@ -2,8 +2,8 @@ package com.lottery.admin.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.lottery.dto.PrizeDto;
import com.lottery.dto.FixUserDto;
import com.lottery.entity.Prize;
import com.lottery.result.Result;
import com.lottery.vo.PageInfo;
import com.lottery.vo.PrizeVo;
@ -23,4 +23,6 @@ public interface AdminPrizeService extends IService<Prize> {
boolean updatePrize(PrizeDto prizeDto);
PrizeVo getPrizeById(Long id);
void addWinUser(FixUserDto fixUserDto);
}

25
lottery-system/lottery-service/src/main/java/com/lottery/admin/service/AdminUserDetailService.java

@ -0,0 +1,25 @@
package com.lottery.admin.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.lottery.dto.UserQueryDto;
import com.lottery.entity.UserDetail;
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;
/**
* @program: lottery
* @ClassName IUserDetail
* @description:
* @author: wwl
* @create: 2025-07-16 9:36
* @Version 1.0
**/
public interface AdminUserDetailService extends IService<UserDetail> {
PageInfo<UserVo> listFixUser(int pageNum, int pageSize, UserQueryDto userQueryDto);
Result importUsers(MultipartFile file, String gradeName);
}

10
lottery-system/lottery-service/src/main/java/com/lottery/admin/service/AdminUserService.java

@ -1,6 +1,7 @@
package com.lottery.admin.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.lottery.dto.AdminLogin;
import com.lottery.dto.UserDto;
import com.lottery.dto.UserQueryDto;
import com.lottery.entity.User;
@ -23,7 +24,14 @@ import java.util.List;
@Service
public interface AdminUserService extends IService<User> {
void addUser(UserDto userDto);
Result AdminUserlogin(AdminLogin adminLogin);
boolean addUser(UserDto userDto);
PageInfo<UserVo> listUser(int pageNum, int pageSize, UserQueryDto userQueryDto);

39
lottery-system/lottery-service/src/main/java/com/lottery/admin/service/Impl/AdminPrizeServiceImpl.java

@ -1,28 +1,25 @@
package com.lottery.admin.service.Impl;
import ch.qos.logback.classic.spi.EventArgUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.lottery.admin.mapper.AdminGradeMapper;
import com.lottery.admin.mapper.AdminPrizeMapper;
import com.lottery.admin.mapper.AdminUserDetailMapper;
import com.lottery.admin.mapper.AdminUserMapper;
import com.lottery.admin.service.AdminPrizeService;
import com.lottery.api.mapper.IGradeMapper;
import com.lottery.api.mapper.IPrizeMapper;
import com.lottery.dto.PrizeDto;
import com.lottery.dto.FixUserDto;
import com.lottery.entity.Grade;
import com.lottery.entity.Prize;
import com.lottery.exception.SomeException;
import com.lottery.result.Result;
import com.lottery.entity.User;
import com.lottery.entity.UserDetail;
import com.lottery.utils.ConvertBeanUtil;
import com.lottery.vo.PageInfo;
import com.lottery.vo.PrizeVo;
import net.bytebuddy.implementation.auxiliary.AuxiliaryType;
import org.hibernate.engine.jdbc.connections.internal.ConnectionValidator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.lang.module.Configuration;
import java.util.Date;
import java.util.List;
@ -43,6 +40,12 @@ public class AdminPrizeServiceImpl extends ServiceImpl<AdminPrizeMapper, Prize>
@Autowired
private AdminPrizeMapper adminPrizeMapper;
@Autowired
private AdminUserDetailMapper adminUserDetailMapper;
@Autowired
private AdminUserMapper adminUserMapper;
@Override
public PageInfo<PrizeVo> pageListPrize(int pageNum, int pageSize) {
Page<Prize> page = new Page<>(pageNum, pageSize);
@ -116,4 +119,24 @@ public class AdminPrizeServiceImpl extends ServiceImpl<AdminPrizeMapper, Prize>
prizeVo.setGradeName(grade.getGradeName());
return prizeVo;
}
@Override
public void addWinUser(FixUserDto fixUserDto) {
//先判断新增的内定用户是否在总的抽奖用户中
Long userId = adminUserMapper.selectByJwcode(fixUserDto.getJwcode());
if (userId == null) {
adminUserMapper.insert(ConvertBeanUtil.convert(fixUserDto, User.class)); //不存在插入总表
}
Grade grade = adminGradeMapper.selectByName(fixUserDto.getGradeName());
Long gradeId = grade.getId();
Long userIdd = adminUserMapper.selectByJwcode(fixUserDto.getJwcode());
UserDetail userDetail = new UserDetail();
userDetail.setUserId(userIdd);
userDetail.setGradeId(gradeId);
userDetail.setIsFixed(1);
adminUserDetailMapper.insert(userDetail);
}
}

180
lottery-system/lottery-service/src/main/java/com/lottery/admin/service/Impl/AdminUserDetailServiceImpl.java

@ -0,0 +1,180 @@
package com.lottery.admin.service.Impl;
import com.alibaba.excel.EasyExcel;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
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.mapper.AdminGradeMapper;
import com.lottery.admin.mapper.AdminUserDetailMapper;
import com.lottery.admin.mapper.AdminUserMapper;
import com.lottery.admin.service.AdminUserDetailService;
import com.lottery.admin.service.AdminUserService;
import com.lottery.api.mapper.IUserDetailMapper;
import com.lottery.api.service.IUserDetailService;
import com.lottery.api.service.IUserService;
import com.lottery.dto.UserImportDto;
import com.lottery.dto.UserQueryDto;
import com.lottery.entity.Grade;
import com.lottery.entity.User;
import com.lottery.entity.UserDetail;
import com.lottery.result.Result;
import com.lottery.utils.ConvertBeanUtil;
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.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
import java.util.*;
import java.util.stream.Collectors;
/**
* @program: lottery
* @ClassName UserDetailServiceImpl
* @description:
* @author: wwl
* @create: 2025-07-16 9:43
* @Version 1.0
**/
@Service
public class AdminUserDetailServiceImpl extends ServiceImpl<IUserDetailMapper, UserDetail> implements AdminUserDetailService {
@Autowired
private AdminUserMapper adminUserMapper;
@Autowired
private AdminUserDetailMapper adminUserDetailMapper;
@Autowired
private AdminUserService adminUserService;
private final static Logger LOGGER = LoggerFactory.getLogger(AdminUserDetailServiceImpl.class);
@Autowired
private AdminGradeMapper adminGradeMapper;
@Override
public PageInfo<UserVo> listFixUser(int pageNum, int pageSize, UserQueryDto userQueryDto) {
//查UserDetail表吧所有的userid取出来然后在从user表根据id查就行了
List<UserDetail> list = this.list();
List<Long> UserIds = list.stream().map(UserDetail::getUserId).collect(Collectors.toList());
Page<User> page = new Page<>(pageNum, pageSize);
//user表根据id批量查询
LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.in(User::getId, UserIds);
if (StringUtils.isNotBlank(userQueryDto.getUsername())) {
queryWrapper.like(User::getUsername, userQueryDto.getUsername());
}
if(StringUtils.isNotBlank(userQueryDto.getJwcode())){
queryWrapper.like(User::getPassword, userQueryDto.getJwcode());
}
Page<User> userPage = this.adminUserMapper.selectPage(page, queryWrapper);
List<UserVo> userVolist = ConvertBeanUtil.convertList(userPage.getRecords(), UserVo.class);
return PageInfo.of(userPage, userVolist);
}
@Override
@Transactional(rollbackFor = Exception.class)
public Result importUsers(MultipartFile file, String gradeName) {
try {
// 1. 解析Excel
List<UserImportDto> userDtos = EasyExcel.read(file.getInputStream())
.head(UserImportDto.class)
.sheet()
.doReadSync();
// 2. 数据校验和去重
Set<String> existingCodes = adminUserMapper.selectAllUserCodes();
List<User> users = new ArrayList<>();
List<UserDetail> userDetails = new ArrayList<>();
Set<String> processedCodes = new HashSet<>();
int successCount = 0;
int skipCount = 0;
for (int i = 0; i < userDtos.size(); i++) {
UserImportDto dto = userDtos.get(i);
try {
validateUser(dto, i + 2, existingCodes, processedCodes);
// 转换User实体
User user = convertToEntity(dto);
users.add(user);
// 生成UserDetail
UserDetail detail = new UserDetail();
detail.setUserId(user.getId()); // 会在保存后自动填充
detail.setGradeId(adminGradeMapper.selectByName(gradeName).getId()); // 默认等级
detail.setIsFixed(1); // 默认未固定
userDetails.add(detail);
processedCodes.add(dto.getJwcode());
successCount++;
} catch (IllegalArgumentException e) {
LOGGER.warn("导入数据校验失败: {}", e.getMessage());
skipCount++;
}
}
// 3. 批量保存
if (!users.isEmpty()) {
// 批量保存用户
boolean userSaved = adminUserService.saveBatch(users);
// 设置userDetail的userId
for (int i = 0; i < users.size(); i++) {
userDetails.get(i).setUserId(users.get(i).getId());
}
// 批量保存用户详情
boolean detailSaved = this.saveBatch(userDetails);
if (userSaved && detailSaved) {
return Result.success(String.format("导入成功%d条,跳过%d条", successCount, skipCount));
}
return 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 + "行: 精网号在当前文件中重复");
}
}
}

52
lottery-system/lottery-service/src/main/java/com/lottery/admin/service/Impl/AdminUserServiceImpl.java

@ -10,6 +10,7 @@ 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.AdminLogin;
import com.lottery.dto.UserDto;
import com.lottery.dto.UserImportDto;
import com.lottery.dto.UserQueryDto;
@ -27,9 +28,12 @@ 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 org.json.JSONObject;
import java.util.*;
import static com.lottery.utils.HttpUtils.postUrlencoded;
/**
* @program: lottery
* @ClassName AdminUserServiceImpl
@ -46,8 +50,52 @@ public class AdminUserServiceImpl extends ServiceImpl<AdminUserMapper, User> imp
private final static Logger LOGGER = LoggerFactory.getLogger(AdminUserController.class);
@Override
public void addUser(UserDto userDto) {
this.save(ConvertBeanUtil.convert(userDto, User.class));
public Result AdminUserlogin(AdminLogin adminLogin) {
try {
// 1. 准备请求参数
Map<String, String> params = new HashMap<>();
params.put("username", adminLogin.getUsername()); // 替换为实际用户名
params.put("password", adminLogin.getPassword()); // 替换为实际密码
params.put("app_from", "en"); // canshu
// 2. 调用登录API
String loginUrl = "http://39.101.133.168:8828/hljwgo/api/user/login_jwcode";
String response = postUrlencoded(loginUrl, params);
// 3. 处理响应
LOGGER.info("登录成功,响应数据:{} " , response);
JSONObject jsonResponse = new JSONObject(response);
// 检查状态码
if (jsonResponse.getInt("code") == 200) {
JSONObject data = jsonResponse.getJSONObject("data");
String token = data.getString("token");
LOGGER.info("登录成功,Token:{} " ,token);
// 后续可以使用token调用其他API
} else {
LOGGER.error(jsonResponse.getString("msg"));
return Result.failure(jsonResponse.getString("msg"));
}
} catch (Exception e) {
System.err.println("登录失败: " + e.getMessage());
return Result.failure("登录失败");
}
return Result.success();
}
@Override
public boolean addUser(UserDto userDto) {
String jwcode = userDto.getJwcode();
LambdaQueryWrapper<User> lambdaQueryWrapper = new LambdaQueryWrapper<>();
lambdaQueryWrapper.eq(User::getJwcode, jwcode);
if(this.count(lambdaQueryWrapper) > 0) {
return false;
}
return this.save(ConvertBeanUtil.convert(userDto, User.class));
}
@Override

39
lottery-system/lottery-service/src/main/java/com/lottery/api/controller/LotteryController.java

@ -0,0 +1,39 @@
package com.lottery.api.controller;
import com.lottery.api.service.IUserDetailService;
import com.lottery.api.service.Impl.UserDetailServiceImpl;
import com.lottery.dto.StartLotteryDto;
import com.lottery.entity.User;
import com.lottery.result.Result;
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.*;
/**
* @program: lottery
* @ClassName LotteryController
* @description:
* @author: wwl
* @create: 2025-07-16 9:29
* @Version 1.0
**/
@RestController
@RequestMapping("api/lottery")
public class LotteryController {
private final static Logger LOGGER = LoggerFactory.getLogger(LotteryController.class);
@Autowired
private IUserDetailService userDetailService;
@GetMapping()
public Result<UserVo> StartLottery(@RequestBody StartLotteryDto startLotteryDto){
LOGGER.info("开始抽奖,{}等级,奖品是:{},抽取人数:{}",startLotteryDto.getGradeName(),startLotteryDto.getPrizeName(),startLotteryDto.getPerWin());
userDetailService.StartLottery(startLotteryDto);
return Result.success();
}
}

3
lottery-system/lottery-service/src/main/java/com/lottery/api/mapper/IGradeMapper.java

@ -3,6 +3,7 @@ package com.lottery.api.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.lottery.entity.Grade;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;
/**
* @program: lottery-system
@ -15,4 +16,6 @@ import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface IGradeMapper extends BaseMapper<Grade> {
@Select("select id from grade where grade_name = #{gradeName}")
Long selectByName(String gradeName);
}

18
lottery-system/lottery-service/src/main/java/com/lottery/api/mapper/IUserDetailMapper.java

@ -0,0 +1,18 @@
package com.lottery.api.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.lottery.entity.UserDetail;
import org.apache.ibatis.annotations.Mapper;
/**
* @program: lottery
* @ClassName IUserDetailMapper
* @description:
* @author: wwl
* @create: 2025-07-16 9:47
* @Version 1.0
**/
@Mapper
public interface IUserDetailMapper extends BaseMapper<UserDetail> {
}

17
lottery-system/lottery-service/src/main/java/com/lottery/api/service/IUserDetailService.java

@ -0,0 +1,17 @@
package com.lottery.api.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.lottery.dto.StartLotteryDto;
import com.lottery.entity.UserDetail;
/**
* @program: lottery
* @ClassName IUserDetail
* @description:
* @author: wwl
* @create: 2025-07-16 9:36
* @Version 1.0
**/
public interface IUserDetailService extends IService<UserDetail> {
void StartLottery(StartLotteryDto startLotteryDto);
}

129
lottery-system/lottery-service/src/main/java/com/lottery/api/service/Impl/UserDetailServiceImpl.java

@ -0,0 +1,129 @@
package com.lottery.api.service.Impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.lottery.LotteryApplication;
import com.lottery.api.mapper.IGradeMapper;
import com.lottery.api.mapper.IUserDetailMapper;
import com.lottery.api.mapper.IUserMapper;
import com.lottery.api.service.IUserDetailService;
import com.lottery.dto.StartLotteryDto;
import com.lottery.entity.Grade;
import com.lottery.entity.User;
import com.lottery.entity.UserDetail;
import com.lottery.exception.SomeException;
import com.lottery.vo.UserVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
* @program: lottery
* @ClassName UserDetailServiceImpl
* @description:
* @author: wwl
* @create: 2025-07-16 9:43
* @Version 1.0
**/
@Service
public class UserDetailServiceImpl extends ServiceImpl<IUserDetailMapper, UserDetail> implements IUserDetailService {
@Autowired
private IUserMapper userMapper;
@Autowired
private IGradeMapper gradeMapper;
@Autowired
private IUserDetailMapper userDetailMapper;
@Override
public void StartLottery(StartLotteryDto startLotteryDto) {
Long gradeId = gradeMapper.selectByName(startLotteryDto.getGradeName());
if (gradeId == null) {
throw new SomeException("未找到指定等级:" + startLotteryDto.getGradeName());
}
LambdaQueryWrapper<UserDetail> userDetailLambdaQueryWrapper = new LambdaQueryWrapper<>();
userDetailLambdaQueryWrapper
.eq(UserDetail::getGradeId, gradeId)
.eq(UserDetail::getIsFixed, 1);
//该等级下的内定人员
List<UserDetail> userDetails = userDetailMapper.selectList(userDetailLambdaQueryWrapper);
if (userDetails.isEmpty()) {
System.out.println("无内定");
//从user表中抽取
}
if (startLotteryDto.getPerWin() > userDetails.size()) {
//抽取人数大于内定人数所有内定人员均中奖剩余的从总的user表抽取
List<UserVo> userVoList = new ArrayList<>();
//内定中奖的
for (UserDetail userDetail : userDetails) {
User user = userMapper.selectById(userDetail.getUserId());
if (user == null) {
throw new SomeException("未找到用户ID:" + userDetail.getUserId());
}
UserVo userVo = new UserVo();
userVo.setUsername(user.getUsername());
userVo.setJwcode(user.getJwcode());
userVoList.add(userVo);
}
//总中奖人数 - 内定人数 = 剩余从总用户表中抽取
int lastNum = startLotteryDto.getPerWin() - userVoList.size();
LambdaQueryWrapper<User> UserQueryWrapper = new LambdaQueryWrapper<>();
List<User> users = randomSelectFromAll(userMapper.selectList(UserQueryWrapper), lastNum);
for (User user : users) {
UserVo userVo = new UserVo();
userVo.setUsername(user.getUsername());
userVo.setJwcode(user.getJwcode());
}
}
if (startLotteryDto.getPerWin() <= userDetails.size()) {
//抽取人数小于等于内定人数从内定人数中随机抽取
List<UserDetail> winners = randomSelect(userDetails, startLotteryDto.getPerWin());
List<UserVo> userVoList = new ArrayList<>();
// 遍历所有中奖用户
for (UserDetail userDetail : winners) {
// 关联查询user表获取详细信息
User user = userMapper.selectById(userDetail.getUserId());
// 检查用户是否存在
if (user == null) {
throw new SomeException("未找到用户ID:" + userDetail.getUserId());
}
// 创建UserVo对象并添加到结果列表
UserVo userVo = new UserVo();
userVo.setUsername(user.getUsername());
userVo.setJwcode(user.getJwcode());
userVoList.add(userVo);
}
}
}
// 随机选择指定数量的用户(内定名单中)
private List<UserDetail> randomSelect(List<UserDetail> users, int count) {
List<UserDetail> shuffled = new ArrayList<>(users); // 避免修改原集合
Collections.shuffle(shuffled); // 随机打乱顺序
return shuffled.subList(0, count); // 取前N个
}
// 随机选择指定数量的用户(总名单中)
private List<User> randomSelectFromAll(List<User> user, int count) {
List<User> shuffled = new ArrayList<>(user); // 避免修改原集合
Collections.shuffle(shuffled); // 随机打乱顺序
return shuffled.subList(0, count); // 取前N个
}
}

2
lottery-system/lottery-service/src/main/java/com/lottery/api/service/Impl/UserServiceImpl.java

@ -50,7 +50,7 @@ public class UserServiceImpl extends ServiceImpl<IUserMapper, User> implements I
@Override
public List<User> listAllUser() {
List<User> list = this.list();
redisTemplate.opsForValue().set(RedisCacheConstant.ALL_USER_CACHE, JSON.toJSONString(list));
//redisTemplate.opsForValue().set(RedisCacheConstant.ALL_USER_CACHE, JSON.toJSONString(list));
return list;
}
}

13
lottery-system/lottery-service/src/main/resources/application.yml

@ -8,10 +8,17 @@ spring:
username: link
password: tEhdERkaGprEA7nT
driver-class-name: com.mysql.cj.jdbc.Driver
# hikari:
# pool-name: LotteryHikariCP
# maximum-pool-size: 10 # 连接池大小
# connection-timeout: 30000
hikari:
pool-name: LotteryHikariCP
maximum-pool-size: 10 # 连接池大小
connection-timeout: 30000
maximum-pool-size: 20 # 默认一般是 10,根据并发量调整
connection-timeout: 30000 # 连接超时时间(毫秒),默认 30s
idle-timeout: 600000 # 空闲连接超时时间(默认 10 分钟)
max-lifetime: 1800000 # 连接最大生命周期(默认 30 分钟)
leak-detection-threshold: 5000 # 连接泄漏检测(毫秒,建议 5s)
# ========== Redis 配置 ==========
# redis:

6
lottery-system/lottery-service/src/main/resources/mapper/admin/AdminUserDetailMapper.xml

@ -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.AdminUserDetailMapper">
</mapper>

3
lottery-system/lottery-service/src/main/resources/mapper/admin/AdminUserMapper.xml

@ -3,4 +3,7 @@
<mapper namespace="com.lottery.admin.mapper.AdminUserMapper">
<select id="selectByJwcode" resultType="java.lang.Long">
select id from user where jwcode = #{jwcode}
</select>
</mapper>

3
lottery-system/lottery-service/src/main/resources/mapper/api/gradeMapper.xml

@ -2,7 +2,4 @@
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.lottery.api.mapper.IGradeMapper">
<select id="selectByName" resultType="com.lottery.entity.Grade">
select * from grade where grade_name = #{gradeName}
</select>
</mapper>

6
lottery-system/lottery-service/src/main/resources/mapper/api/userDetailMapper.xml

@ -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.api.mapper.IUserDetailMapper">
</mapper>

6
lottery-system/pom.xml

@ -42,6 +42,12 @@
<version>2.2.2</version>
</dependency>
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>20231013</version> <!-- 可用最新版本 -->
</dependency>
<!-- MySQL 驱动 -->
<dependency>
<groupId>mysql</groupId>

Loading…
Cancel
Save