From 0273f753c5f251d5e445f968cd3368e89b030294 Mon Sep 17 00:00:00 2001 From: FalingCliff Date: Sun, 15 Jun 2025 14:57:44 +0800 Subject: [PATCH] =?UTF-8?q?feat(admin-server):=20=E6=96=B0=E5=A2=9E?= =?UTF-8?q?=E5=AE=A2=E6=88=B7=E6=96=87=E4=BB=B6=E4=B8=8A=E4=BC=A0=E6=8E=A5?= =?UTF-8?q?=E5=8F=A3=E5=8F=8A=E5=AE=A2=E6=88=B7=E4=BF=A1=E6=81=AF=E7=AE=A1?= =?UTF-8?q?=E7=90=86=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../config/FileUploadProperties.java | 13 +++++ .../admin_server/config/SwaggerConfig.java | 11 +--- .../controller/admin/AdminAuthController.java | 57 +++++++++++++++++-- .../admin/AdminFileUploadController.java | 29 ++++++++++ .../client/ClientMainController.java | 24 -------- .../controller/client/CustomerController.java | 47 +++++++++++++-- .../client/CustomerFileUploadController.java | 29 ++++++++++ .../controller/client/WxLoginController.java | 10 ++-- .../employee/EmployeeMainController.java | 24 -------- .../model/dto/AdminUpdateMeDTO.java | 22 +++++++ .../model/dto/CustomerUpdateDTO.java | 29 ++++++++++ .../model/dto/UpdatePassword.java | 18 ++++++ .../admin_server/model/entity/Admin.java | 8 +-- .../admin_server/model/entity/Customer.java | 20 ++++--- .../admin_server/model/vo/AdminVO.java | 2 +- .../admin_server/model/vo/CustomerVO.java | 49 ++++++++++++++++ .../service/FileStorageService.java | 9 +++ .../impl/LocalFileStorageServiceImpl.java | 46 +++++++++++++++ 18 files changed, 361 insertions(+), 86 deletions(-) create mode 100644 src/main/java/com/example/admin_server/config/FileUploadProperties.java create mode 100644 src/main/java/com/example/admin_server/controller/admin/AdminFileUploadController.java delete mode 100644 src/main/java/com/example/admin_server/controller/client/ClientMainController.java create mode 100644 src/main/java/com/example/admin_server/controller/client/CustomerFileUploadController.java delete mode 100644 src/main/java/com/example/admin_server/controller/employee/EmployeeMainController.java create mode 100644 src/main/java/com/example/admin_server/model/dto/AdminUpdateMeDTO.java create mode 100644 src/main/java/com/example/admin_server/model/dto/CustomerUpdateDTO.java create mode 100644 src/main/java/com/example/admin_server/model/dto/UpdatePassword.java create mode 100644 src/main/java/com/example/admin_server/model/vo/CustomerVO.java create mode 100644 src/main/java/com/example/admin_server/service/FileStorageService.java create mode 100644 src/main/java/com/example/admin_server/service/impl/LocalFileStorageServiceImpl.java diff --git a/src/main/java/com/example/admin_server/config/FileUploadProperties.java b/src/main/java/com/example/admin_server/config/FileUploadProperties.java new file mode 100644 index 0000000..89bd61b --- /dev/null +++ b/src/main/java/com/example/admin_server/config/FileUploadProperties.java @@ -0,0 +1,13 @@ +package com.example.admin_server.config; + +import lombok.Data; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.stereotype.Component; + +@Data +@Component +@ConfigurationProperties(prefix = "file") +public class FileUploadProperties { + private String uploadDir; + private String urlPrefix; +} diff --git a/src/main/java/com/example/admin_server/config/SwaggerConfig.java b/src/main/java/com/example/admin_server/config/SwaggerConfig.java index 36e1138..46e8ca0 100644 --- a/src/main/java/com/example/admin_server/config/SwaggerConfig.java +++ b/src/main/java/com/example/admin_server/config/SwaggerConfig.java @@ -35,16 +35,7 @@ public class SwaggerConfig { } @Bean - public Docket employeeApi() { - return new Docket(DocumentationType.OAS_30) - .groupName("员工端") - .select() - .apis(RequestHandlerSelectors.basePackage("com.example.admin_server.controller.employee")) - .paths(PathSelectors.ant("/api/employee/**")) - .build(); - } - - private ApiInfo apiInfo() { + protected ApiInfo apiInfo() { return new ApiInfoBuilder() .title("后台管理接口文档") .description("接口文档说明") diff --git a/src/main/java/com/example/admin_server/controller/admin/AdminAuthController.java b/src/main/java/com/example/admin_server/controller/admin/AdminAuthController.java index 2e283e4..8a6cd4c 100644 --- a/src/main/java/com/example/admin_server/controller/admin/AdminAuthController.java +++ b/src/main/java/com/example/admin_server/controller/admin/AdminAuthController.java @@ -4,7 +4,9 @@ import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.example.admin_server.common.Result; import com.example.admin_server.enums.ResultCode; import com.example.admin_server.mapper.AdminMapper; +import com.example.admin_server.model.dto.AdminUpdateMeDTO; import com.example.admin_server.model.dto.LoginDTO; +import com.example.admin_server.model.dto.UpdatePassword; import com.example.admin_server.model.entity.Admin; import com.example.admin_server.utils.JwtUtil; import io.jsonwebtoken.Claims; @@ -88,24 +90,23 @@ public class AdminAuthController { if (!StringUtils.hasText(token)) { return Result.of(ResultCode.UNAUTHORIZED, "缺少 token"); } - Optional claimsOpt = jwtUtil.parseToken(token); if (!claimsOpt.isPresent() || jwtUtil.isTokenExpired(token)) { return Result.of(ResultCode.UNAUTHORIZED, "token 无效或已过期"); } - Claims claims = claimsOpt.get(); - Map userInfo = new HashMap<>(); + Admin admin = adminMapper.selectById((Integer) claims.get("id")); userInfo.put("userId", String.valueOf(claims.get("id"))); userInfo.put("userName", claims.get("username")); + userInfo.put("userInfo", admin); userInfo.put("roles", new String[]{"R_SUPER"}); userInfo.put("buttons", new String[]{"B_CODE1", "B_CODE2", "B_CODE3"}); - return Result.ok(userInfo); } + // 获取 Token 与 RefreshToken private Result getResult(Map data) { String newToken = jwtUtil.generateToken(data); String newRefreshToken = jwtUtil.generateRefreshToken(data); @@ -116,4 +117,52 @@ public class AdminAuthController { return Result.ok(tokenMap); } + + @PostMapping("/updatePassword") + @ApiOperation("修改密码") + public Result updatePassword( + @RequestHeader("authorization") String token, + @RequestBody UpdatePassword updatePassword) { + if (!StringUtils.hasText(token)) { + return Result.of(ResultCode.UNAUTHORIZED, "缺少 token"); + } + Optional claimsOpt = jwtUtil.parseToken(token); + if (!claimsOpt.isPresent() || jwtUtil.isTokenExpired(token)) { + return Result.of(ResultCode.UNAUTHORIZED, "token 无效或已过期"); + } + Claims claims = claimsOpt.get(); + Integer adminId = (Integer) claims.get("id"); + Admin admin = adminMapper.selectById(adminId); + String encryptedOldPassword = DigestUtils.md5DigestAsHex(updatePassword.getOldPassword().getBytes()); + if (!admin.getPassword().equals(encryptedOldPassword)) { + return Result.of(ResultCode.UNAUTHORIZED, "旧密码不正确"); + } + String encryptedNewPassword = DigestUtils.md5DigestAsHex(updatePassword.getNewPassword().getBytes()); + admin.setPassword(encryptedNewPassword); + adminMapper.updateById(admin); + return Result.ok("密码修改成功"); + } + + @PostMapping("/updateProfile") + @ApiOperation("修改个人信息") + public Result updateProfile( + @RequestHeader("authorization") String token, + @RequestBody AdminUpdateMeDTO adminUpdateMeDTO) { + if (!StringUtils.hasText(token)) { + return Result.of(ResultCode.UNAUTHORIZED, "缺少 token"); + } + Optional claimsOpt = jwtUtil.parseToken(token); + if (!claimsOpt.isPresent() || jwtUtil.isTokenExpired(token)) { + return Result.of(ResultCode.UNAUTHORIZED, "token 无效或已过期"); + } + Claims claims = claimsOpt.get(); + Integer adminId = (Integer) claims.get("id"); + Admin admin = adminMapper.selectById(adminId); + admin.setNickname(adminUpdateMeDTO.getNickname()); + admin.setAvatar(adminUpdateMeDTO.getAvatar()); + admin.setEmail(adminUpdateMeDTO.getEmail()); + admin.setPhone(adminUpdateMeDTO.getPhone()); + adminMapper.updateById(admin); + return Result.ok(admin); + } } diff --git a/src/main/java/com/example/admin_server/controller/admin/AdminFileUploadController.java b/src/main/java/com/example/admin_server/controller/admin/AdminFileUploadController.java new file mode 100644 index 0000000..2c11175 --- /dev/null +++ b/src/main/java/com/example/admin_server/controller/admin/AdminFileUploadController.java @@ -0,0 +1,29 @@ +package com.example.admin_server.controller.admin; + +import com.example.admin_server.common.Result; +import com.example.admin_server.service.FileStorageService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import lombok.RequiredArgsConstructor; +import org.springframework.web.bind.annotation.PostMapping; +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 java.io.IOException; + +@RestController +@RequestMapping("/api/admin/upload") +@RequiredArgsConstructor +@Api(tags = {"上传接口"}) +public class AdminFileUploadController { + + private final FileStorageService fileStorageService; + + @PostMapping + @ApiOperation(value = "上传接口") + public Result uploadSingle(@RequestParam MultipartFile file) throws IOException { + return Result.ok(fileStorageService.store(file)); + } +} diff --git a/src/main/java/com/example/admin_server/controller/client/ClientMainController.java b/src/main/java/com/example/admin_server/controller/client/ClientMainController.java deleted file mode 100644 index a6f47c0..0000000 --- a/src/main/java/com/example/admin_server/controller/client/ClientMainController.java +++ /dev/null @@ -1,24 +0,0 @@ -package com.example.admin_server.controller.client; - -import com.example.admin_server.config.AppConfig; -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiOperation; -import lombok.RequiredArgsConstructor; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; - -@RestController -@RequestMapping("/api/client") -@Api(tags = {"ClientMain"}) -@RequiredArgsConstructor -public class ClientMainController { - - private final AppConfig appConfig; - - @GetMapping("/welcome") - @ApiOperation(value = "Hello client") - public String welcome(){ - return "Hello client" + appConfig.getEnvName(); - } -} diff --git a/src/main/java/com/example/admin_server/controller/client/CustomerController.java b/src/main/java/com/example/admin_server/controller/client/CustomerController.java index 7856132..f5ce48c 100644 --- a/src/main/java/com/example/admin_server/controller/client/CustomerController.java +++ b/src/main/java/com/example/admin_server/controller/client/CustomerController.java @@ -1,19 +1,58 @@ package com.example.admin_server.controller.client; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; +import cn.hutool.core.bean.BeanUtil; +import com.example.admin_server.common.Result; +import com.example.admin_server.enums.ResultCode; +import com.example.admin_server.model.dto.CustomerUpdateDTO; +import com.example.admin_server.model.entity.Customer; +import com.example.admin_server.model.vo.CustomerVO; +import com.example.admin_server.service.ICustomerService; +import com.example.admin_server.utils.JwtUtil; +import io.jsonwebtoken.Claims; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import lombok.RequiredArgsConstructor; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; + +import java.util.Optional; /** *

- * 前端控制器 + * 前端控制器 *

* * @author FallingCliff * @since 2025-05-24 */ @RestController -@RequestMapping("/api/client/customer") +@RequestMapping("/api/client/user") +@RequiredArgsConstructor +@Api(tags = {"个人信息管理"}) public class CustomerController { + private final ICustomerService iCustomerService; + private final JwtUtil jwtUtil; + + @GetMapping("/info") + @ApiOperation("获取个人信息") + public Result getUserInfo(@RequestHeader("assessToken") String token) { + Optional claimsOpt = jwtUtil.parseToken(token); + if (!claimsOpt.isPresent() || jwtUtil.isTokenExpired(token)) { + return Result.of(ResultCode.UNAUTHORIZED, "token 无效或已过期"); + } + Claims claims = claimsOpt.get(); + Integer userId = (Integer) claims.get("id"); + Customer customer = iCustomerService.getById(userId); + CustomerVO customerVO = BeanUtil.copyProperties(customer, CustomerVO.class); + return Result.ok(customerVO); + } + + @ApiOperation("修改个人信息") + @PutMapping("/edit") + public Result addCustomer(@Validated @RequestBody CustomerUpdateDTO customerUpdateDTO) { + Customer customer = BeanUtil.copyProperties(customerUpdateDTO, Customer.class); + return Result.ok(iCustomerService.updateById(customer)); + } } diff --git a/src/main/java/com/example/admin_server/controller/client/CustomerFileUploadController.java b/src/main/java/com/example/admin_server/controller/client/CustomerFileUploadController.java new file mode 100644 index 0000000..4dcea5a --- /dev/null +++ b/src/main/java/com/example/admin_server/controller/client/CustomerFileUploadController.java @@ -0,0 +1,29 @@ +package com.example.admin_server.controller.client; + +import com.example.admin_server.common.Result; +import com.example.admin_server.service.FileStorageService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import lombok.RequiredArgsConstructor; +import org.springframework.web.bind.annotation.PostMapping; +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 java.io.IOException; + +@RestController +@RequestMapping("/api/client/upload") +@RequiredArgsConstructor +@Api(tags = {"上传接口"}) +public class CustomerFileUploadController { + + private final FileStorageService fileStorageService; + + @PostMapping + @ApiOperation(value = "上传接口") + public Result uploadSingle(@RequestParam MultipartFile file) throws IOException { + return Result.ok(fileStorageService.store(file)); + } +} diff --git a/src/main/java/com/example/admin_server/controller/client/WxLoginController.java b/src/main/java/com/example/admin_server/controller/client/WxLoginController.java index 93471c1..061f868 100644 --- a/src/main/java/com/example/admin_server/controller/client/WxLoginController.java +++ b/src/main/java/com/example/admin_server/controller/client/WxLoginController.java @@ -1,11 +1,13 @@ package com.example.admin_server.controller.client; +import cn.hutool.core.bean.BeanUtil; import com.alibaba.fastjson.JSONObject; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.example.admin_server.common.Result; import com.example.admin_server.config.WxConfig; import com.example.admin_server.model.dto.WxLoginDTO; import com.example.admin_server.model.entity.Customer; +import com.example.admin_server.model.vo.CustomerVO; import com.example.admin_server.service.ICustomerService; import com.example.admin_server.utils.JwtUtil; import io.swagger.annotations.Api; @@ -68,7 +70,7 @@ public class WxLoginController { .setSessionKey(sessionKey) .setUnionid(unionid) .setNickname("微信用户") // 默认昵称,可后续完善 - .setAvatarUrl(null) + .setAvatar(null) .setCreateTime(LocalDateTime.now()) .setUpdateTime(LocalDateTime.now()); @@ -86,12 +88,10 @@ public class WxLoginController { claims.put("sessionKey", customer.getSessionKey()); claims.put("openid", customer.getOpenid()); String token = jwtUtil.generateToken(claims); + CustomerVO customerVO = BeanUtil.copyProperties(customer, CustomerVO.class); Map resultData = new HashMap<>(); resultData.put("token", token); - resultData.put("openid", openid); - resultData.put("nickname", customer.getNickname()); - resultData.put("avatar", customer.getAvatarUrl()); - + resultData.put("userInfo", customerVO); return Result.ok("登录成功", resultData); } } diff --git a/src/main/java/com/example/admin_server/controller/employee/EmployeeMainController.java b/src/main/java/com/example/admin_server/controller/employee/EmployeeMainController.java deleted file mode 100644 index 38aa3ed..0000000 --- a/src/main/java/com/example/admin_server/controller/employee/EmployeeMainController.java +++ /dev/null @@ -1,24 +0,0 @@ -package com.example.admin_server.controller.employee; - -import com.example.admin_server.config.AppConfig; -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiOperation; -import lombok.RequiredArgsConstructor; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; - -@RestController -@RequestMapping("/api/employee") -@Api(tags = {"EmployeeMain"}) -@RequiredArgsConstructor -public class EmployeeMainController { - - private final AppConfig appConfig; - - @GetMapping("/welcome") - @ApiOperation(value = "Hello employee") - public String welcome() { - return "Hello employee" + appConfig.getEnvName(); - } -} diff --git a/src/main/java/com/example/admin_server/model/dto/AdminUpdateMeDTO.java b/src/main/java/com/example/admin_server/model/dto/AdminUpdateMeDTO.java new file mode 100644 index 0000000..f4fab84 --- /dev/null +++ b/src/main/java/com/example/admin_server/model/dto/AdminUpdateMeDTO.java @@ -0,0 +1,22 @@ +package com.example.admin_server.model.dto; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +@Data +@ApiModel(value="管理员更新对象", description="用于更新现有管理员信息的数据传输对象") +public class AdminUpdateMeDTO { + + @ApiModelProperty(value = "昵称") + private String nickname; + + @ApiModelProperty(value = "邮箱") + private String email; + + @ApiModelProperty(value = "手机号") + private String phone; + + @ApiModelProperty(value = "头像") + private String avatar; +} diff --git a/src/main/java/com/example/admin_server/model/dto/CustomerUpdateDTO.java b/src/main/java/com/example/admin_server/model/dto/CustomerUpdateDTO.java new file mode 100644 index 0000000..351bcf2 --- /dev/null +++ b/src/main/java/com/example/admin_server/model/dto/CustomerUpdateDTO.java @@ -0,0 +1,29 @@ +package com.example.admin_server.model.dto; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +@Data +public class CustomerUpdateDTO { + + @ApiModelProperty(value = "主键ID") + private Integer id; + + @ApiModelProperty(value = "用户名") + private String username; + + @ApiModelProperty(value = "用户昵称") + private String nickname; + + @ApiModelProperty(value = "头像URL") + private String avatar; + + @ApiModelProperty(value = "邮箱") + private String email; + + @ApiModelProperty(value = "性别") + private String sex; + + @ApiModelProperty(value = "手机号(后续绑定时)") + private String phone; +} diff --git a/src/main/java/com/example/admin_server/model/dto/UpdatePassword.java b/src/main/java/com/example/admin_server/model/dto/UpdatePassword.java new file mode 100644 index 0000000..3a35522 --- /dev/null +++ b/src/main/java/com/example/admin_server/model/dto/UpdatePassword.java @@ -0,0 +1,18 @@ +package com.example.admin_server.model.dto; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotBlank; + +@Data +public class UpdatePassword { + + @ApiModelProperty(value = "旧密码") + @NotBlank(message = "旧密码不能为空") + private String oldPassword; + + @ApiModelProperty(value = "新密码") + @NotBlank(message = "新密码不能为空") + private String newPassword; +} diff --git a/src/main/java/com/example/admin_server/model/entity/Admin.java b/src/main/java/com/example/admin_server/model/entity/Admin.java index 05f82d3..be30a17 100644 --- a/src/main/java/com/example/admin_server/model/entity/Admin.java +++ b/src/main/java/com/example/admin_server/model/entity/Admin.java @@ -1,10 +1,6 @@ package com.example.admin_server.model.entity; -import com.baomidou.mybatisplus.annotation.IdType; -import com.baomidou.mybatisplus.annotation.TableField; -import com.baomidou.mybatisplus.annotation.TableId; -import com.baomidou.mybatisplus.annotation.TableName; -import com.baomidou.mybatisplus.annotation.TableLogic; +import com.baomidou.mybatisplus.annotation.*; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Data; @@ -33,7 +29,7 @@ public class Admin implements Serializable { @ApiModelProperty(value = "主键ID") @TableId(value = "id", type = IdType.AUTO) - private Long id; + private Integer id; @ApiModelProperty(value = "用户名") @TableField("username") diff --git a/src/main/java/com/example/admin_server/model/entity/Customer.java b/src/main/java/com/example/admin_server/model/entity/Customer.java index 2cbb176..1328257 100644 --- a/src/main/java/com/example/admin_server/model/entity/Customer.java +++ b/src/main/java/com/example/admin_server/model/entity/Customer.java @@ -1,10 +1,6 @@ package com.example.admin_server.model.entity; -import com.baomidou.mybatisplus.annotation.IdType; -import com.baomidou.mybatisplus.annotation.TableField; -import com.baomidou.mybatisplus.annotation.TableId; -import com.baomidou.mybatisplus.annotation.TableName; -import com.baomidou.mybatisplus.annotation.TableLogic; +import com.baomidou.mybatisplus.annotation.*; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Data; @@ -33,7 +29,7 @@ public class Customer implements Serializable { @ApiModelProperty(value = "主键ID") @TableId(value = "id", type = IdType.AUTO) - private Long id; + private Integer id; @ApiModelProperty(value = "微信openid") @TableField("openid") @@ -60,8 +56,8 @@ public class Customer implements Serializable { private String nickname; @ApiModelProperty(value = "头像URL") - @TableField("avatar_url") - private String avatarUrl; + @TableField("avatar") + private String avatar; @ApiModelProperty(value = "邮箱") @TableField("email") @@ -71,6 +67,14 @@ public class Customer implements Serializable { @TableField("phone") private String phone; + @ApiModelProperty(value = "性别") + @TableField("sex") + private String sex; + + @ApiModelProperty(value = "积分") + @TableField("points") + private Integer points; + @ApiModelProperty(value = "创建时间") @TableField("create_time") private LocalDateTime createTime; diff --git a/src/main/java/com/example/admin_server/model/vo/AdminVO.java b/src/main/java/com/example/admin_server/model/vo/AdminVO.java index cb4247d..2028242 100644 --- a/src/main/java/com/example/admin_server/model/vo/AdminVO.java +++ b/src/main/java/com/example/admin_server/model/vo/AdminVO.java @@ -21,7 +21,7 @@ import java.time.LocalDateTime; public class AdminVO implements Serializable { @ApiModelProperty(value = "主键ID") - private Long id; + private Integer id; @ApiModelProperty(value = "用户名") private String username; diff --git a/src/main/java/com/example/admin_server/model/vo/CustomerVO.java b/src/main/java/com/example/admin_server/model/vo/CustomerVO.java new file mode 100644 index 0000000..c85349b --- /dev/null +++ b/src/main/java/com/example/admin_server/model/vo/CustomerVO.java @@ -0,0 +1,49 @@ +package com.example.admin_server.model.vo; + +import com.baomidou.mybatisplus.annotation.TableField; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.time.LocalDateTime; + +/** + *

+ * + *

+ * + * @author FallingCliff + * @since 2025-05-24 + */ +@Data +public class CustomerVO { + @ApiModelProperty(value = "主键ID") + private Integer id; + + @ApiModelProperty(value = "用户名") + private String username; + + @ApiModelProperty(value = "用户昵称") + private String nickname; + + @ApiModelProperty(value = "头像URL") + private String avatar; + + @ApiModelProperty(value = "邮箱") + private String email; + + @ApiModelProperty(value = "手机号(后续绑定时)") + private String phone; + + @ApiModelProperty(value = "性别") + private String sex; + + @ApiModelProperty(value = "积分") + private Integer points; + + @ApiModelProperty(value = "创建时间") + private LocalDateTime createTime; + + @ApiModelProperty(value = "更新时间") + @TableField("update_time") + private LocalDateTime updateTime; +} diff --git a/src/main/java/com/example/admin_server/service/FileStorageService.java b/src/main/java/com/example/admin_server/service/FileStorageService.java new file mode 100644 index 0000000..2ef1257 --- /dev/null +++ b/src/main/java/com/example/admin_server/service/FileStorageService.java @@ -0,0 +1,9 @@ +package com.example.admin_server.service; + +import org.springframework.web.multipart.MultipartFile; + +import java.io.IOException; + +public interface FileStorageService { + String store(MultipartFile file) throws IOException; +} diff --git a/src/main/java/com/example/admin_server/service/impl/LocalFileStorageServiceImpl.java b/src/main/java/com/example/admin_server/service/impl/LocalFileStorageServiceImpl.java new file mode 100644 index 0000000..9e9c21e --- /dev/null +++ b/src/main/java/com/example/admin_server/service/impl/LocalFileStorageServiceImpl.java @@ -0,0 +1,46 @@ +package com.example.admin_server.service.impl; + +import com.example.admin_server.config.FileUploadProperties; +import com.example.admin_server.service.FileStorageService; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.web.multipart.MultipartFile; + +import java.io.File; +import java.io.IOException; +import java.util.UUID; + +@Service +@RequiredArgsConstructor +public class LocalFileStorageServiceImpl implements FileStorageService { + + private final FileUploadProperties properties; + + @Override + public String store(MultipartFile file) throws IOException { + if (file.isEmpty()) { + throw new IOException("文件为空"); + } + + String originalFilename = file.getOriginalFilename(); + String extension = ""; + if (originalFilename != null && originalFilename.contains(".")) { + extension = originalFilename.substring(originalFilename.lastIndexOf(".")); + } + + String uuid = UUID.randomUUID().toString(); + String fileName = uuid + extension; + String fullPath = properties.getUploadDir() + fileName; + + File dest = new File(fullPath); + File parentDir = dest.getParentFile(); + if (!parentDir.exists() && !parentDir.mkdirs()) { + throw new IOException("无法创建目录: " + parentDir.getAbsolutePath()); + } + + file.transferTo(dest); + + return properties.getUrlPrefix() + fileName; + } +} +