首次提交

This commit is contained in:
guotao 2026-01-09 12:20:44 +08:00
parent 1101681331
commit ed171eda88
107 changed files with 1370 additions and 524 deletions

210
pom.xml
View file

@ -1,102 +1,120 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<parent> <parent>
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId> <artifactId>spring-boot-starter-parent</artifactId>
<version>4.0.1</version> <version>3.5.9</version>
<relativePath/> <!-- lookup parent from repository --> <relativePath/> <!-- lookup parent from repository -->
</parent> </parent>
<groupId>com.xjhs.findme.merchant</groupId> <groupId>com.xjhs.findmemerchant</groupId>
<artifactId>findme-merchant</artifactId> <artifactId>findme-backend-merchant-java</artifactId>
<version>0.0.1-SNAPSHOT</version> <version>0.0.1-SNAPSHOT</version>
<name>findme-backend-merchant-java</name> <name>findme-backend-merchant-java</name>
<description>findme-backend-merchant-java</description> <description>findme-backend-merchant-java</description>
<url/>
<licenses>
<license/>
</licenses>
<developers>
<developer/>
</developers>
<scm>
<connection/>
<developerConnection/>
<tag/>
<url/>
</scm>
<properties>
<java.version>25</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webmvc</artifactId>
</dependency>
<dependency> <properties>
<groupId>com.mysql</groupId> <java.version>25</java.version>
<artifactId>mysql-connector-j</artifactId> </properties>
<scope>runtime</scope> <dependencies>
</dependency> <dependency>
<dependency> <groupId>org.springframework.boot</groupId>
<groupId>org.projectlombok</groupId> <artifactId>spring-boot-starter-web</artifactId>
<artifactId>lombok</artifactId> </dependency>
<optional>true</optional> <dependency>
</dependency> <groupId>org.springframework.boot</groupId>
<dependency> <artifactId>spring-boot-starter-actuator</artifactId>
<groupId>org.springframework.boot</groupId> </dependency>
<artifactId>spring-boot-starter-actuator-test</artifactId> <dependency>
<scope>test</scope> <groupId>org.springframework.boot</groupId>
</dependency> <artifactId>spring-boot-starter-test</artifactId>
<dependency> </dependency>
<groupId>org.springframework.boot</groupId> <dependency>
<artifactId>spring-boot-starter-data-jpa-test</artifactId> <groupId>org.springframework.boot</groupId>
<scope>test</scope> <artifactId>spring-boot-starter-security</artifactId>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webmvc-test</artifactId> <artifactId>spring-boot-starter-validation</artifactId>
<scope>test</scope> </dependency>
</dependency> <dependency>
</dependencies> <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct</artifactId>
<version>1.6.3</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok-mapstruct-binding</artifactId>
<version>0.2.0</version>
</dependency>
<dependency>
<groupId>org.bitbucket.b_c</groupId>
<artifactId>jose4j</artifactId>
<version>0.9.6</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.18.0</version>
</dependency>
</dependencies>
<build> <build>
<plugins> <plugins>
<plugin> <plugin>
<groupId>org.apache.maven.plugins</groupId> <groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId> <artifactId>maven-compiler-plugin</artifactId>
<configuration> <configuration>
<annotationProcessorPaths> <annotationProcessorPaths>
<path> <path>
<groupId>org.projectlombok</groupId> <groupId>org.mapstruct</groupId>
<artifactId>lombok</artifactId> <artifactId>mapstruct-processor</artifactId>
</path> <version>1.6.3</version>
</annotationProcessorPaths> </path>
</configuration> <path>
</plugin> <groupId>org.projectlombok</groupId>
<plugin> <artifactId>lombok</artifactId>
<groupId>org.springframework.boot</groupId> </path>
<artifactId>spring-boot-maven-plugin</artifactId> <path>
<configuration> <groupId>org.projectlombok</groupId>
<excludes> <artifactId>lombok-mapstruct-binding</artifactId>
<exclude> <version>0.2.0</version>
<groupId>org.projectlombok</groupId> </path>
<artifactId>lombok</artifactId> </annotationProcessorPaths>
</exclude> </configuration>
</excludes> </plugin>
</configuration> <plugin>
</plugin> <groupId>org.springframework.boot</groupId>
</plugins> <artifactId>spring-boot-maven-plugin</artifactId>
</build> <configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
</project> </project>

View file

@ -66,18 +66,26 @@ public class ApiResult<T> {
public static <T> ApiResult<T> fail(){ public static <T> ApiResult<T> fail(){
var result = new ApiResult<T>(); var result = new ApiResult<T>();
result.code = ErrorCode.FAIL; result.code = ErrorCode.Fail;
result.msg = ErrorCode.FAIL.getMsg(); result.msg = ErrorCode.Fail.getMsg();
return result; return result;
} }
public static <T> ApiResult<T> fail(String msg){ public static <T> ApiResult<T> fail(String msg){
var result = new ApiResult<T>(); var result = new ApiResult<T>();
result.code = ErrorCode.FAIL; result.code = ErrorCode.Fail;
result.msg = msg; result.msg = msg;
return result; return result;
} }
public static <T> ApiResult<T> fail(String msg,T data){
var result = new ApiResult<T>();
result.code = ErrorCode.Fail;
result.msg = msg;
result.data = data;
return result;
}
public static <T> ApiResult<T> fail(ErrorCode errorCode){ public static <T> ApiResult<T> fail(ErrorCode errorCode){
var result = new ApiResult<T>(); var result = new ApiResult<T>();
result.code = errorCode; result.code = errorCode;

View file

@ -11,10 +11,18 @@ import lombok.Getter;
@AllArgsConstructor @AllArgsConstructor
@Getter @Getter
public enum ErrorCode { public enum ErrorCode {
/**
OK(200,"操作成功"), * 成功
FAIL(500,"fail"), */
Unauthorized(401,"Unauthorized") OK(200,"成功"),
/**
* 失败
*/
Fail(500,"失败"),
/**
* 未登录
*/
Unauthorized(401,"未登录")
; ;

View file

@ -10,5 +10,5 @@ import java.lang.annotation.*;
@Documented @Documented
@JacksonAnnotationsInside @JacksonAnnotationsInside
@JsonDeserialize(using = SafeLongDeserializer.class) @JsonDeserialize(using = SafeLongDeserializer.class)
public @interface JsonDeserializeToLong { public @interface JsonLong {
} }

View file

@ -1,4 +1,18 @@
package com.xjhs.findmemerchant.common.jackson; package com.xjhs.findmemerchant.common.jackson;
public class SafeLongDeserializer { import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import java.io.IOException;
public class SafeLongDeserializer extends JsonDeserializer<Long> {
@Override
public Long deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
String value = p.getText();
if (value == null || value.isBlank()) {
return null;
}
return Long.valueOf(value);
}
} }

View file

@ -1,10 +1,7 @@
package com.xjhs.findmemerchant.common.jpa; package com.xjhs.findmemerchant.common.jpa;
import com.xjhs.findmemerchant.adapter.id.SnowflakeGenerated; import com.xjhs.findmemerchant.common.jpa.id.SnowflakeGenerated;
import jakarta.persistence.Column; import jakarta.persistence.*;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.Id;
import jakarta.persistence.MappedSuperclass;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
import org.hibernate.annotations.Comment; import org.hibernate.annotations.Comment;
@ -12,12 +9,14 @@ import org.springframework.data.annotation.CreatedBy;
import org.springframework.data.annotation.CreatedDate; import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.LastModifiedBy; import org.springframework.data.annotation.LastModifiedBy;
import org.springframework.data.annotation.LastModifiedDate; import org.springframework.data.annotation.LastModifiedDate;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;
import java.time.LocalDateTime; import java.time.LocalDateTime;
@MappedSuperclass @MappedSuperclass
@Getter @Getter
@Setter @Setter
@EntityListeners(AuditingEntityListener.class)
public class AbstractBaseEntity { public class AbstractBaseEntity {
/** /**
* 主键雪花 ID * 主键雪花 ID
@ -40,9 +39,9 @@ public class AbstractBaseEntity {
* 创建人 * 创建人
*/ */
@CreatedBy @CreatedBy
@Column(name = "created_at", nullable = false, updatable = false) @Column(name = "created_by", nullable = false, updatable = false)
@Comment("创建人") @Comment("创建人")
private String createdBy; private Long createdBy;
/** /**
* 更新时间 * 更新时间
@ -55,9 +54,9 @@ public class AbstractBaseEntity {
* 更新人 * 更新人
*/ */
@LastModifiedBy @LastModifiedBy
@Column(name = "updated_at", nullable = false) @Column(name = "updated_by")
@Comment("更新人") @Comment("更新人")
private String updatedBy; private Long updatedBy;
/** /**
* 软删除时间null 表示未删除 * 软删除时间null 表示未删除
*/ */

View file

@ -1,4 +1,4 @@
package com.xjhs.findmemerchant.adapter.id; package com.xjhs.findmemerchant.common.jpa.id;
import org.hibernate.annotations.IdGeneratorType; import org.hibernate.annotations.IdGeneratorType;

View file

@ -1,4 +1,4 @@
package com.xjhs.findmemerchant.adapter.id; package com.xjhs.findmemerchant.common.jpa.id;
import org.hibernate.engine.spi.SharedSessionContractImplementor; import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.id.IdentifierGenerator; import org.hibernate.id.IdentifierGenerator;

View file

@ -1,4 +1,4 @@
package com.xjhs.findmemerchant.adapter.id; package com.xjhs.findmemerchant.common.jpa.id;
/** /**
* 雪花Id生成器 * 雪花Id生成器

View file

@ -1,4 +1,4 @@
package com.xjhs.findmemerchant.adapter.json; package com.xjhs.findmemerchant.common.jpa.json;
import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.core.type.TypeReference;

View file

@ -1,4 +1,4 @@
package com.xjhs.findmemerchant.adapter.json; package com.xjhs.findmemerchant.common.jpa.json;
import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;

View file

@ -1,4 +1,72 @@
package com.xjhs.findmemerchant.common.mvc; package com.xjhs.findmemerchant.common.mvc;
public class GlobalResponseHandler { import com.xjhs.findmemerchant.common.ApiResult;
import jakarta.validation.ConstraintViolationException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.MethodParameter;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.lang.Nullable;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;
import java.util.HashMap;
import java.util.Map;
/**
* mvc响应处理器 & 统一异常处理器
*/
@Slf4j
@RestControllerAdvice
public class GlobalResponseHandler implements ResponseBodyAdvice<Object> {
@Override
public boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter<?>> converterType) {
return true;
}
@Nullable
@Override
public Object beforeBodyWrite(@Nullable Object body, MethodParameter returnType, MediaType selectedContentType, Class<? extends HttpMessageConverter<?>> selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) {
String url = request.getURI().toString(); // 完整请求 URL
log.info("发起请求: {} {} ", request.getMethod(), url);
return body;
}
/**
* 捕获 @Valid 触发的字段级校验异常
*/
@ExceptionHandler(MethodArgumentNotValidException.class)
public ApiResult<?> handleValidException(MethodArgumentNotValidException ex) {
Map<String, String> errors = new HashMap<>();
ex.getBindingResult()
.getFieldErrors()
.forEach(err -> errors.put(err.getField(), err.getDefaultMessage()));
log.error("参数校验失败:{}", errors);
return ApiResult.fail("参数校验失败: " + errors);
}
/**
* 捕获 @Validated 触发的单参数校验异常形参上加了 @Validated
*/
@ExceptionHandler(ConstraintViolationException.class)
public ApiResult<?> handleConstraintViolation(ConstraintViolationException ex) {
Map<String, String> errors = new HashMap<>();
ex.getConstraintViolations().forEach(cv -> {
String field = cv.getPropertyPath().toString();
errors.put(field, cv.getMessage());
});
log.error("参数校验失败:{}", errors);
return ApiResult.fail("参数校验失败",errors);
}
@ExceptionHandler(Exception.class)
public ApiResult<?> handleException(Exception ex) {
log.error("系统异常", ex);
return ApiResult.fail("系统内部错误:" + ex.getMessage());
}
} }

View file

@ -1,4 +1,24 @@
package com.xjhs.findmemerchant.common.mvc; package com.xjhs.findmemerchant.common.mvc;
import lombok.Data;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
/**
* 分页请求参数
*/
@Data
public class PageVo { public class PageVo {
/**
* 页号(默认 1)
*/
private int pageNo = 1;
/**
* 当页数据条数(默认 20)
*/
private int pageSize = 20;
public Pageable getPageable() {
return PageRequest.of(pageNo, pageSize);
}
} }

View file

@ -1,5 +1,6 @@
package com.xjhs.findmemerchant.config; package com.xjhs.findmemerchant.config;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer; import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer; import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer; import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer;

View file

@ -1,4 +1,30 @@
package com.xjhs.findmemerchant.config; package com.xjhs.findmemerchant.config;
import com.xjhs.findmemerchant.entity.Merchant;
import com.xjhs.findmemerchant.security.sms.SmsAuthenticationToken;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.domain.AuditorAware;
import org.springframework.data.jpa.repository.config.EnableJpaAuditing;
import org.springframework.security.core.context.SecurityContextHolder;
import java.util.Optional;
@Configuration
@EnableJpaAuditing(auditorAwareRef = "auditorAwareImpl")
public class JpaConfig { public class JpaConfig {
@Bean(name = "auditorAwareImpl")
public AuditorAware<Long> auditorAwareImpl(){
return ()->{
var auth = SecurityContextHolder.getContext().getAuthentication();
if (auth instanceof SmsAuthenticationToken){
var principal = auth.getPrincipal();
if (principal instanceof Merchant merchant){
return Optional.of(merchant.getId());
}
}
return Optional.of(0L);
};
}
} }

View file

@ -4,32 +4,32 @@ import com.xjhs.findmemerchant.common.ApiResult;
import com.xjhs.findmemerchant.dto.MerchantDto; import com.xjhs.findmemerchant.dto.MerchantDto;
import com.xjhs.findmemerchant.dto.auth.RegisterDto; import com.xjhs.findmemerchant.dto.auth.RegisterDto;
import com.xjhs.findmemerchant.entity.Merchant; import com.xjhs.findmemerchant.entity.Merchant;
import com.xjhs.findmemerchant.mapper.MerchantMapper;
import com.xjhs.findmemerchant.redis.TokenBlacklistRedisService; import com.xjhs.findmemerchant.redis.TokenBlacklistRedisService;
import com.xjhs.findmemerchant.repository.MerchantRepository; import com.xjhs.findmemerchant.repository.MerchantRepository;
import com.xjhs.findmemerchant.security.JwtTokenService; import com.xjhs.findmemerchant.security.JwtTokenService;
import com.xjhs.findmemerchant.security.RefreshTokenService; import com.xjhs.findmemerchant.security.RefreshTokenService;
import com.xjhs.findmemerchant.security.sms.SmsAuthenticationToken; import com.xjhs.findmemerchant.security.sms.SmsAuthenticationToken;
import com.xjhs.findmemerchant.security.sms.SmsCodeService; import com.xjhs.findmemerchant.security.sms.SmsCodeService;
import com.xjhs.findmemerchant.security.sms.SmsLoginVo; import com.xjhs.findmemerchant.vo.auth.SmsLoginVo;
import com.xjhs.findmemerchant.security.sms.SmsSendVo; import com.xjhs.findmemerchant.vo.auth.SmsSendVo;
import com.xjhs.findmemerchant.service.MerchantService; import com.xjhs.findmemerchant.service.MerchantService;
import com.xjhs.findmemerchant.vo.merchant.MerchantUpdateVo; import com.xjhs.findmemerchant.vo.merchant.MerchantUpdateVo;
import com.xjhs.findmemerchant.vo.auth.RegisterVo; import com.xjhs.findmemerchant.vo.auth.RegisterVo;
import jakarta.validation.Valid; import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.http.HttpHeaders; import org.springframework.http.HttpHeaders;
import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import java.security.Principal;
import java.util.Map; import java.util.Map;
/** /**
* 登录授权管理接口 * 登录授权管理接口
*/ */
@Slf4j
@RestController @RestController
@RequiredArgsConstructor @RequiredArgsConstructor
@RequestMapping("/auth") @RequestMapping("/auth")
@ -39,13 +39,14 @@ public class AuthController {
private final AuthenticationManager authenticationManager; private final AuthenticationManager authenticationManager;
private final RefreshTokenService refreshTokenService; private final RefreshTokenService refreshTokenService;
private final MerchantRepository merchantRepository; private final MerchantRepository merchantRepository;
private final MerchantMapper merchantMapper;
private final StringRedisTemplate stringRedisTemplate;
private final TokenBlacklistRedisService tokenBlacklistRedisService; private final TokenBlacklistRedisService tokenBlacklistRedisService;
private final MerchantService merchantService; private final MerchantService merchantService;
/** /**
* 发送短信验证码 * 发送短信验证码
*
* @param sendVo 请求参数
* @return 发送结果
*/ */
@PostMapping("/sms/send") @PostMapping("/sms/send")
public ApiResult<Void> sendCode(@Valid @RequestBody SmsSendVo sendVo) { public ApiResult<Void> sendCode(@Valid @RequestBody SmsSendVo sendVo) {
@ -55,6 +56,7 @@ public class AuthController {
/** /**
* 短信验证码登录 * 短信验证码登录
*
* @param vo 登录信息 * @param vo 登录信息
* @return 令牌信息 * @return 令牌信息
*/ */
@ -67,6 +69,7 @@ public class AuthController {
var refreshToken = refreshTokenService.create(vo.getPhone()); var refreshToken = refreshTokenService.create(vo.getPhone());
return ApiResult.returnToken(accessToken, refreshToken); return ApiResult.returnToken(accessToken, refreshToken);
} catch (Exception e) { } catch (Exception e) {
log.error("登录失败", e);
return ApiResult.fail("登录失败:" + e.getMessage()); return ApiResult.fail("登录失败:" + e.getMessage());
} }
} }
@ -93,12 +96,13 @@ public class AuthController {
/** /**
* 注销登录 * 注销登录
*
* @param authHeader @ignore 认证头信息 * @param authHeader @ignore 认证头信息
* @return 注销结果 * @return 注销结果
*/ */
@PostMapping("/logout") @PostMapping("/logout")
public ApiResult<Void> logout(@RequestHeader(HttpHeaders.AUTHORIZATION) String authHeader){ public ApiResult<Void> logout(@RequestHeader(HttpHeaders.AUTHORIZATION) String authHeader) {
if (StringUtils.isEmpty(authHeader) || !authHeader.startsWith("Bearer ")) { if (StringUtils.isEmpty(authHeader) || !authHeader.startsWith("Bearer ")) {
return ApiResult.fail("访问令牌错误"); return ApiResult.fail("访问令牌错误");
} }
try { try {
@ -136,42 +140,43 @@ public class AuthController {
) )
); );
} catch (Exception e) { } catch (Exception e) {
log.error("注册失败", e);
return ApiResult.fail("注册失败:" + e.getMessage()); return ApiResult.fail("注册失败:" + e.getMessage());
} }
} }
/** /**
* 获取当前登录的商户基本信息 * 获取当前登录的商家基本信息
* @param principal @ignore 登录信息对象 *
* @return 商户信息 * @param merchant @ignore 当前商家
* @return 商家信息
*/ */
@GetMapping("/profile") @GetMapping("/profile")
public ApiResult<MerchantDto> getProfile(Principal principal) { public ApiResult<MerchantDto> getProfile(@AuthenticationPrincipal Merchant merchant) {
if (principal instanceof Merchant merchant) { if (merchant == null) {
return this.merchantService.getById(merchant.getId()) return ApiResult.fail("商家信息不存在");
.map(ApiResult::data)
.orElse(ApiResult.fail("商户信息不存在"));
} }
return ApiResult.fail("商户信息不存在"); return this.merchantService.getById(merchant.getId())
.map(ApiResult::data)
.orElse(ApiResult.fail("商家信息不存在"));
} }
/** /**
* 更新当前登录的商户基本信息 * 更新当前登录的商家基本信息
* @param principal @ignore 登录信息对象 *
* @param merchant @ignore 当前商家
* @param merchantUpdateVo 更新信息对象 * @param merchantUpdateVo 更新信息对象
* @return 信息 * @return 信息
*/ */
@PutMapping("/profile") @PutMapping("/profile")
public ApiResult<MerchantDto> updateProfile(Principal principal,@Valid @RequestBody MerchantUpdateVo merchantUpdateVo) { public ApiResult<MerchantDto> updateProfile(@AuthenticationPrincipal Merchant merchant,
if (principal instanceof Merchant merchant) { @Valid @RequestBody MerchantUpdateVo merchantUpdateVo) {
try { try {
var result = this.merchantService.updateMerchant(merchant.getId(),merchantUpdateVo); var result = this.merchantService.updateMerchant(merchant.getId(), merchantUpdateVo);
return ApiResult.data(result); return ApiResult.data(result);
} catch (Exception e) { } catch (Exception e) {
return ApiResult.fail(e.getMessage()); return ApiResult.fail(e.getMessage());
}
} }
return ApiResult.fail("商户信息不存在");
} }
} }

View file

@ -9,10 +9,14 @@ import com.xjhs.findmemerchant.vo.merchant.MerchantVerifyVo;
import jakarta.validation.Valid; import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import java.security.Principal; import java.security.Principal;
/**
* 商家管理接口
*/
@Slf4j @Slf4j
@RestController @RestController
@RequestMapping("/merchant") @RequestMapping("/merchant")
@ -20,39 +24,52 @@ import java.security.Principal;
public class MerchantController { public class MerchantController {
private final MerchantService merchantService; private final MerchantService merchantService;
/**
* 查询当前登录商家详情
*
* @param merchant @ignore 当前商家
* @return 商家详情信息
*/
@GetMapping @GetMapping
public ApiResult<MerchantDto> getMerchant(Principal principal) { public ApiResult<MerchantDto> getMerchant(@AuthenticationPrincipal Merchant merchant) {
if (principal instanceof Merchant merchant) { return this.merchantService.getById(merchant.getId())
return this.merchantService.getById(merchant.getId()) .map(ApiResult::data)
.map(ApiResult::data) .orElse(ApiResult.fail("商家信息不存在"));
.orElse(ApiResult.fail("商户信息不存在"));
}
return ApiResult.fail("商户信息不存在");
} }
/**
* 更新当前登录商家信息
*
* @param merchant @ignore 当前商家
* @param merchantUpdateVo 更新参数
* @return 商家信息
*/
@PutMapping @PutMapping
public ApiResult<MerchantDto> updateMerchant(Principal principal,@Valid @RequestBody MerchantUpdateVo merchantUpdateVo) { public ApiResult<MerchantDto> updateMerchant(@AuthenticationPrincipal Merchant merchant,
if (principal instanceof Merchant merchant) { @Valid @RequestBody MerchantUpdateVo merchantUpdateVo) {
try { try {
var dto = this.merchantService.updateMerchant(merchant.getId(),merchantUpdateVo); var dto = this.merchantService.updateMerchant(merchant.getId(), merchantUpdateVo);
return ApiResult.data(dto); return ApiResult.data(dto);
} catch (Exception e) { } catch (Exception e) {
return ApiResult.fail(e.getMessage()); return ApiResult.fail(e.getMessage());
}
} }
return ApiResult.fail("商户信息不存在");
} }
/**
* 当前商家验证
*
* @param merchant @ignore 当前商家
* @param merchantVerifyVo 验证参数
* @return 商家信息
*/
@PostMapping("/verify") @PostMapping("/verify")
public ApiResult<MerchantDto> verifyMerchant(Principal principal,@Valid @RequestBody MerchantVerifyVo merchantVerifyVo) { public ApiResult<MerchantDto> verifyMerchant(@AuthenticationPrincipal Merchant merchant,
if (principal instanceof Merchant merchant) { @Valid @RequestBody MerchantVerifyVo merchantVerifyVo) {
try { try {
var dto = this.merchantService.verifyMerchant(merchant.getId(),merchantVerifyVo.getIdCardNo(),merchantVerifyVo.getRealName()); var dto = this.merchantService.verifyMerchant(merchant.getId(), merchantVerifyVo.getIdCardNo(), merchantVerifyVo.getRealName());
return ApiResult.data(dto); return ApiResult.data(dto);
} catch (Exception e) { } catch (Exception e) {
return ApiResult.fail(e.getMessage()); return ApiResult.fail(e.getMessage());
}
} }
return ApiResult.fail("商户信息不存在");
} }
} }

View file

@ -3,25 +3,37 @@ package com.xjhs.findmemerchant.controller;
import com.xjhs.findmemerchant.common.ApiResult; import com.xjhs.findmemerchant.common.ApiResult;
import com.xjhs.findmemerchant.common.PageData; import com.xjhs.findmemerchant.common.PageData;
import com.xjhs.findmemerchant.common.jpa.query.JpaSpecs; import com.xjhs.findmemerchant.common.jpa.query.JpaSpecs;
import com.xjhs.findmemerchant.common.mvc.PageVo;
import com.xjhs.findmemerchant.dto.store.BusinessPeriodDto;
import com.xjhs.findmemerchant.dto.store.StoreBusinessStatusDto;
import com.xjhs.findmemerchant.dto.store.StoreDto; import com.xjhs.findmemerchant.dto.store.StoreDto;
import com.xjhs.findmemerchant.entity.BusinessPeriod;
import com.xjhs.findmemerchant.entity.Merchant; import com.xjhs.findmemerchant.entity.Merchant;
import com.xjhs.findmemerchant.entity.Store; import com.xjhs.findmemerchant.entity.Store;
import com.xjhs.findmemerchant.mapper.StoreMapper; import com.xjhs.findmemerchant.mapper.StoreMapper;
import com.xjhs.findmemerchant.repository.BusinessPeriodRepository;
import com.xjhs.findmemerchant.repository.MerchantRepository; import com.xjhs.findmemerchant.repository.MerchantRepository;
import com.xjhs.findmemerchant.repository.StoreRepository; import com.xjhs.findmemerchant.repository.StoreRepository;
import com.xjhs.findmemerchant.vo.store.BusinessPeriodVo;
import com.xjhs.findmemerchant.vo.store.StoreBusinessStatusUpdateVo;
import com.xjhs.findmemerchant.vo.store.StoreCreateVo; import com.xjhs.findmemerchant.vo.store.StoreCreateVo;
import com.xjhs.findmemerchant.vo.store.StoreUpdateVo; import com.xjhs.findmemerchant.vo.store.StoreUpdateVo;
import jakarta.validation.Valid; import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification; import org.springframework.data.jpa.domain.Specification;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import java.security.Principal; import java.security.Principal;
import java.util.List;
import java.util.Objects; import java.util.Objects;
/**
* 门店管理接口
*/
@Slf4j @Slf4j
@RestController @RestController
@RequestMapping("/stores") @RequestMapping("/stores")
@ -30,38 +42,36 @@ public class StoreController {
private final MerchantRepository merchantRepository; private final MerchantRepository merchantRepository;
private final StoreRepository storeRepository; private final StoreRepository storeRepository;
private final StoreMapper storeMapper; private final StoreMapper storeMapper;
private final BusinessPeriodRepository businessPeriodRepository;
/** /**
* 门店信息(分页查询) * 门店信息(分页查询)
* *
* @param pageable 分页参数 * @param pageVo 分页参数
* @param principal @ignore 当前登录门店 * @param merchant @ignore 当前登录商家
* @return 分页数据信息 * @return 分页数据信息
*/ */
@GetMapping @GetMapping
@Transactional(readOnly = true) @Transactional(readOnly = true)
public ApiResult<PageData<StoreDto>> findPage(Pageable pageable, Principal principal) { public ApiResult<PageData<StoreDto>> findPage(@AuthenticationPrincipal Merchant merchant, PageVo pageVo) {
var merchant = (Merchant) principal;
var pageData = this.storeRepository.findAll(Specification.allOf( var pageData = this.storeRepository.findAll(Specification.allOf(
JpaSpecs.eq("merchant.id", merchant.getId()) JpaSpecs.eq("merchant.id", merchant.getId())
), pageable).map(this.storeMapper::toDto); ), pageVo.getPageable()).map(this.storeMapper::toDto);
return ApiResult.page(pageData.getTotalElements(), pageData.getContent()); return ApiResult.page(pageData.getTotalElements(), pageData.getContent());
} }
/** /**
* 创建商的门店 * 创建商的门店
* *
* @param vo 门店信息 * @param vo 门店信息
* @param principal @ignore 当前登录的商户 * @param merchant @ignore 当前登录的商家
* @return 门店信息 * @return 门店信息
*/ */
@PostMapping @PostMapping
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public ApiResult<StoreDto> create(@Valid @RequestBody StoreCreateVo vo, Principal principal) { public ApiResult<StoreDto> create(@AuthenticationPrincipal Merchant merchant,
var merchant = (Merchant) principal; @Valid @RequestBody StoreCreateVo vo) {
if (Objects.isNull(merchant)) {
return ApiResult.fail("商家信息错误");
}
var store = this.storeMapper.toEntity(vo); var store = this.storeMapper.toEntity(vo);
merchant.addStore(store); merchant.addStore(store);
this.storeRepository.save(store); this.storeRepository.save(store);
@ -73,16 +83,13 @@ public class StoreController {
* 查询门店详情 * 查询门店详情
* *
* @param storeId 门店id * @param storeId 门店id
* @param principal @ignore 当前登录的商户 * @param merchant @ignore 当前登录的商家
* @return 门店详情 * @return 门店详情
*/ */
@GetMapping("/{storeId}") @GetMapping("/{storeId}")
@Transactional(readOnly = true) @Transactional(readOnly = true)
public ApiResult<StoreDto> findById(@PathVariable("storeId") String storeId, Principal principal) { public ApiResult<StoreDto> findById(@AuthenticationPrincipal Merchant merchant,
var merchant = (Merchant) principal; @PathVariable("storeId") String storeId) {
if (Objects.isNull(merchant)) {
return ApiResult.fail("商家信息错误");
}
var storeIdLong = Long.parseLong(storeId); var storeIdLong = Long.parseLong(storeId);
return merchant.getStores().stream() return merchant.getStores().stream()
.filter(x -> Objects.equals(x.getId(), storeIdLong)) .filter(x -> Objects.equals(x.getId(), storeIdLong))
@ -96,17 +103,15 @@ public class StoreController {
* 更新门店信息 * 更新门店信息
* *
* @param storeId 门店id * @param storeId 门店id
* @param principal @ignore 当前登录的商户 * @param merchant @ignore 当前登录的商家
* @param vo 更新对象 * @param vo 更新对象
* @return 门店信息 * @return 门店信息
*/ */
@PutMapping("/{storeId}") @PutMapping("/{storeId}")
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public ApiResult<StoreDto> updateById(@PathVariable("storeId") String storeId, Principal principal, @Valid @RequestBody StoreUpdateVo vo) { public ApiResult<StoreDto> updateById(@AuthenticationPrincipal Merchant merchant,
var merchant = (Merchant) principal; @PathVariable("storeId") String storeId,
if (Objects.isNull(merchant)) { @Valid @RequestBody StoreUpdateVo vo) {
return ApiResult.fail("商家信息错误");
}
var storeIdLong = Long.parseLong(storeId); var storeIdLong = Long.parseLong(storeId);
for (Store store : merchant.getStores()) { for (Store store : merchant.getStores()) {
if (Objects.equals(storeIdLong, store.getId())) { if (Objects.equals(storeIdLong, store.getId())) {
@ -121,19 +126,112 @@ public class StoreController {
/** /**
* 删除门店 * 删除门店
* *
* @param storeId 门店id * @param storeId 门店id
* @param principal @ignore 当前登录的商户 * @param merchant @ignore 当前登录的商家
*/ */
@DeleteMapping("/{storeId}") @DeleteMapping("/{storeId}")
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public ApiResult<Void> delteById(@PathVariable("storeId") String storeId, Principal principal) { public ApiResult<Void> delteById(@AuthenticationPrincipal Merchant merchant,
var merchant = (Merchant) principal; @PathVariable("storeId") String storeId) {
if (Objects.isNull(merchant)) {
return ApiResult.fail("商家信息错误");
}
var storeIdLong = Long.parseLong(storeId); var storeIdLong = Long.parseLong(storeId);
merchant.getStores().removeIf(x -> Objects.equals(storeIdLong, x.getId())); merchant.getStores().removeIf(x -> Objects.equals(storeIdLong, x.getId()));
this.merchantRepository.save(merchant); this.merchantRepository.save(merchant);
return ApiResult.success("删除成功"); return ApiResult.success("删除成功");
} }
/**
* 获取门店营业状态
*
* @param storeId 门店id
* @param merchant @ignore 当前商户
* @return 门店营业状态信息
*/
@GetMapping("/{storeId}/business-status")
@Transactional(readOnly = true)
public ApiResult<StoreBusinessStatusDto> getStoreBusinessStatus(@AuthenticationPrincipal Merchant merchant,
@PathVariable("storeId") String storeId) {
var storeIdLong = Long.parseLong(storeId);
return merchant.getStores().stream()
.filter(x -> Objects.equals(x.getId(), storeIdLong))
.map(this.storeMapper::toBusinessStatusDto)
.map(ApiResult::data)
.findFirst()
.orElse(ApiResult.fail("门店信息不存在"));
}
/**
* 设置门店营业状态
*
* @param storeId 门店id
* @param merchant @ignore 当前商家
* @param updateVo 更新参数
* @return 门店营业状态信息
*/
@PutMapping("/{storeId}/business-status")
@Transactional(rollbackFor = Exception.class)
public ApiResult<StoreBusinessStatusDto> putStoreBusinessStatus(@PathVariable("storeId") String storeId,
@AuthenticationPrincipal Merchant merchant,
@Validated @RequestBody StoreBusinessStatusUpdateVo updateVo) {
var storeIdLong = Long.parseLong(storeId);
return merchant.getStores().stream()
.filter(x -> Objects.equals(x.getId(), storeIdLong))
.findFirst()
.map(x -> {
this.storeMapper.updateFromBusinessUpdateVo(updateVo, x);
this.storeRepository.save(x);
return this.storeMapper.toBusinessStatusDto(x);
})
.map(ApiResult::data)
.orElse(ApiResult.fail("门店信息不存在"));
}
/**
* 获取门店营业时间段
*
* @param storeId 门店id
* @param merchant @ignore 当前商家
* @return 门店营业时间段 列表
*/
@GetMapping("/{storeId}/business-periods")
public ApiResult<List<BusinessPeriodDto>> getStoreBusinessPeriodList(@AuthenticationPrincipal Merchant merchant,
@PathVariable("storeId") String storeId) {
var storeIdLong = Long.parseLong(storeId);
return merchant.getStores().stream()
.filter(x -> Objects.equals(x.getId(), storeIdLong))
.findFirst()
.map(x -> this.storeMapper.toDtoList(x.getBusinessPeriods()))
.map(ApiResult::data)
.orElse(ApiResult.fail("门店信息不存在"));
}
/**
* 设置门店营业时间段
*
* @param storeId 门店id
* @param merchant @ignore 当前商家
* @param updateVoList 门店营业时间段更新参数列表
* @return 门店营业时间段 列表
*/
@PutMapping("/{storeId}/business-periods")
public ApiResult<List<BusinessPeriodDto>> putStoreBusinessPeriodList(@PathVariable("storeId") String storeId,
@AuthenticationPrincipal Merchant merchant,
@Validated @RequestBody List<BusinessPeriodVo> updateVoList) {
var storeIdLong = Long.parseLong(storeId);
return merchant.getStores().stream()
.filter(x -> Objects.equals(x.getId(), storeIdLong))
.findFirst()
.map(store -> {
store.getBusinessPeriods().clear();
for (BusinessPeriodVo businessPeriodVo : updateVoList) {
var entity = this.storeMapper.toEntity(businessPeriodVo);
store.addBusinessPeriods(entity);
this.businessPeriodRepository.save(entity);
}
return this.storeMapper.toDtoList(store.getBusinessPeriods());
})
.map(ApiResult::data)
.orElse(ApiResult.fail("门店信息不存在"));
}
} }

View file

@ -1,4 +1,157 @@
package com.xjhs.findmemerchant.controller; package com.xjhs.findmemerchant.controller;
import com.xjhs.findmemerchant.common.ApiResult;
import com.xjhs.findmemerchant.dto.member.EmployeeDto;
import com.xjhs.findmemerchant.entity.Merchant;
import com.xjhs.findmemerchant.mapper.EmployeeMapper;
import com.xjhs.findmemerchant.repository.EmployeeRepository;
import com.xjhs.findmemerchant.vo.member.EmployeeCreateVo;
import com.xjhs.findmemerchant.vo.member.EmployeeUpdateVo;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.util.List;
import java.util.Objects;
/**
* 门店员工管理接口
*/
@Slf4j
@RestController
@RequestMapping("/stores/{storeId}/employees")
@RequiredArgsConstructor
public class StoreEmployeeController { public class StoreEmployeeController {
private final EmployeeRepository employeeRepository;
private final EmployeeMapper employeeMapper;
/**
* 查询门店员工列表
* @param merchant @ignore 当前商户
* @param storeId 门店id
* @return 员工列表信息
*/
@GetMapping
@Transactional(readOnly = true)
public ApiResult<List<EmployeeDto>> getList(@AuthenticationPrincipal Merchant merchant,
@PathVariable("storeId") Long storeId) {
var list = this.employeeRepository.findByStoreId(storeId)
.stream().map(this.employeeMapper::toDto)
.toList();
return ApiResult.data(list);
}
/**
* 新建门店员工
* @param merchant @ignore 当前商户
* @param storeId 门店id
* @param createVo 员工信息参数
* @return 门店员工信息
*/
@PostMapping
@Transactional
public ApiResult<EmployeeDto> create(@AuthenticationPrincipal Merchant merchant,
@PathVariable("storeId") Long storeId,
@Validated @RequestBody EmployeeCreateVo createVo) throws Exception {
try {
var store = merchant.getStores().stream()
.filter(x -> Objects.equals(storeId, x.getId()))
.findFirst()
.orElseThrow(() -> new Exception("门店信息不存在"));
var phoneExists = store.getEmployees().stream()
.anyMatch(x -> Objects.equals(x.getPhone(), createVo.getPhone()));
if (phoneExists) {
throw new Exception("手机号码已被使用");
}
var employee = this.employeeMapper.toEntity(createVo);
store.addEmployee(employee);
this.employeeRepository.save(employee);
var dto = this.employeeMapper.toDto(employee);
return ApiResult.data(dto);
} catch (Exception e) {
log.error("员工信息注册失败", e);
throw e;
}
}
/**
* 查询门店员工详情
* @param merchant @ignore 当前商户
* @param storeId 门店id
* @param employeeId 门店员工id
* @return 员工详情
*/
@GetMapping("/{employeeId}")
@Transactional(readOnly = true)
public ApiResult<EmployeeDto> findById(@AuthenticationPrincipal Merchant merchant,
@PathVariable("storeId") Long storeId,
@PathVariable("employeeId") Long employeeId) {
return merchant.getStores().stream()
.filter(x -> Objects.equals(storeId, x.getId()))
.flatMap(x -> x.getEmployees().stream())
.filter(x -> Objects.equals(employeeId, x.getId()))
.findFirst()
.map(this.employeeMapper::toDto)
.map(ApiResult::data)
.orElse(ApiResult.fail("员工信息不存在"));
}
/**
* 根据员工id更新员工信息
* @param merchant @ignore 当前商户
* @param storeId 门店id
* @param employeeId 员工id
* @param updateVo 更新参数
* @return 员工详情
*/
@PutMapping("/{employeeId}")
@Transactional
public ApiResult<EmployeeDto> updateById(@AuthenticationPrincipal Merchant merchant,
@PathVariable("storeId") Long storeId,
@PathVariable("employeeId") Long employeeId,
@Validated @RequestBody EmployeeUpdateVo updateVo) {
return merchant.getStores().stream()
.filter(x -> Objects.equals(storeId, x.getId()))
.flatMap(x -> x.getEmployees().stream())
.filter(x -> Objects.equals(employeeId, x.getId()))
.findFirst()
.map(employee -> {
this.employeeMapper.updateEntityFormUpdateVo(updateVo, employee);
this.employeeRepository.save(employee);
return ApiResult.data(
this.employeeMapper.toDto(employee)
);
})
.orElse(ApiResult.fail("员工信息不存在"));
}
/**
* 根据id删除员工信息
* @param merchant @ignore 当前商户
* @param storeId 门店id
* @param employeeId 员工id
* @return 删除结果
*/
@DeleteMapping("/{employeeId}")
@Transactional
public ApiResult<Void> deleteById(@AuthenticationPrincipal Merchant merchant,
@PathVariable("storeId") Long storeId,
@PathVariable("employeeId") Long employeeId) throws Exception {
try {
var store = merchant.getStores().stream()
.filter(x -> Objects.equals(storeId, x.getId()))
.findFirst()
.orElseThrow(()->new Exception("门店信息不存在"));
store.getEmployees().removeIf(x->Objects.equals(employeeId,x.getId()));
return ApiResult.success();
} catch (Exception e) {
log.error("删除员工失败",e);
throw e;
}
}
} }

View file

@ -1,17 +1,22 @@
package com.xjhs.findmemerchant.dto; package com.xjhs.findmemerchant.dto;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import com.xjhs.findmemerchant.types.AuthStatus; import com.xjhs.findmemerchant.types.AuthStatus;
import lombok.Data; import lombok.Data;
import java.time.LocalDateTime;
/** /**
* 商户信息 * 信息
*/ */
@Data @Data
public class MerchantDto { public class MerchantDto {
/** /**
* id * id
*/ */
private String id; @JsonSerialize(using = ToStringSerializer.class)
private Long id;
/** /**
* 手机号码 * 手机号码
* TODO: 手机号码需要脱敏 * TODO: 手机号码需要脱敏
@ -36,5 +41,5 @@ public class MerchantDto {
/** /**
* 创建时间 * 创建时间
*/ */
private String createAt; private LocalDateTime createdAt;
} }

View file

@ -1,15 +1,30 @@
package com.xjhs.findmemerchant.dto.auth; package com.xjhs.findmemerchant.dto.auth;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
/** /**
* 商家注册响应内容 * 商家注册响应内容
*
* @param merchantId 商户id
* @param accessToken 访问令牌
* @param refreshToken 刷新令牌
*/ */
public record RegisterDto( @Data
Long merchantId, @AllArgsConstructor
String accessToken, @NoArgsConstructor
String refreshToken public class RegisterDto {
) { /**
* 商家id
*/
@JsonSerialize(using = ToStringSerializer.class)
private Long merchantId;
/**
* 访问令牌
*/
private String accessToken;
/**
* 刷新令牌
*/
private String refreshToken;
} }

View file

@ -1,4 +1,40 @@
package com.xjhs.findmemerchant.dto.member; package com.xjhs.findmemerchant.dto.member;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import lombok.Data;
import java.time.LocalDateTime;
@Data
public class EmployeeDto { public class EmployeeDto {
@JsonSerialize(using = ToStringSerializer.class)
private Long id;
/**
* 员工姓名
*/
private String name;
/**
* 手机号码
*/
private String phone;
/**
* 关联角色id
*/
@JsonSerialize(using = ToStringSerializer.class)
private Long roleId;
/**
* 关联门店id
*/
@JsonSerialize(using = ToStringSerializer.class)
private Long storeId;
/**
* 员工状态
*/
private Integer status;
/**
* 创建时间
*/
private LocalDateTime createdAt;
} }

View file

@ -1,27 +1,27 @@
package com.xjhs.findmemerchant.vo.store; package com.xjhs.findmemerchant.dto.store;
import jakarta.validation.constraints.NotBlank; import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import jakarta.validation.constraints.NotNull; import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import jakarta.validation.constraints.Size;
import lombok.Data; import lombok.Data;
@Data @Data
public class BusinessPeriodVo { public class BusinessPeriodDto {
/**
* 门店id
*/
@JsonSerialize(using = ToStringSerializer.class)
private Long storeId;
/** /**
* 周几周天0,... * 周几周天0,...
*/ */
@Size(max = 6)
@NotNull
private Integer dayOfWeek; private Integer dayOfWeek;
/** /**
* 开始营业时间 HH:mm 格式 * 开始营业时间 HH:mm 格式
*/ */
@NotBlank
private String startTime; private String startTime;
/** /**
* 结束营业时间 HH:mm 格式 * 结束营业时间 HH:mm 格式
*/ */
@NotBlank
private String endTime; private String endTime;
/** /**
* 是否启用 * 是否启用

View file

@ -1,4 +1,36 @@
package com.xjhs.findmemerchant.dto.store; package com.xjhs.findmemerchant.dto.store;
import lombok.Data;
import java.time.LocalDateTime;
/**
* 门店营业状态
*/
@Data
public class StoreBusinessStatusDto { public class StoreBusinessStatusDto {
/**
* 业务状态值
*/
private Integer status;
/**
* 业务状态文案
*/
private String statusText;
/**
* 临时关闭原因可为空
*/
private String tempCloseReason;
/**
* 临时关闭截止时间可为空
*/
private LocalDateTime tempCloseUntil;
/**
* 是否营业
*/
private Boolean isOpen;
} }

View file

@ -1,5 +1,7 @@
package com.xjhs.findmemerchant.dto.store; package com.xjhs.findmemerchant.dto.store;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import com.xjhs.findmemerchant.types.BusinessStatus; import com.xjhs.findmemerchant.types.BusinessStatus;
import com.xjhs.findmemerchant.types.CommonStatus; import com.xjhs.findmemerchant.types.CommonStatus;
import com.xjhs.findmemerchant.types.StoreAuditStatus; import com.xjhs.findmemerchant.types.StoreAuditStatus;
@ -12,11 +14,13 @@ public class StoreDto {
/** /**
* 门店id * 门店id
*/ */
private String id; @JsonSerialize(using = ToStringSerializer.class)
private Long id;
/** /**
* id * id
*/ */
private String merchantId; @JsonSerialize(using = ToStringSerializer.class)
private Long merchantId;
/** /**
* 门店名称 * 门店名称
*/ */

View file

@ -8,7 +8,7 @@ import lombok.Setter;
import org.hibernate.annotations.Comment; import org.hibernate.annotations.Comment;
/** /**
* 提现银行卡 * 提现银行卡
* 对应表bank_cards * 对应表bank_cards
*/ */
@Getter @Getter
@ -23,7 +23,7 @@ import org.hibernate.annotations.Comment;
public class BankCard extends AbstractBaseEntity { public class BankCard extends AbstractBaseEntity {
/** /**
* *
*/ */
@ManyToOne(fetch = FetchType.LAZY) @ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "merchant_id", insertable = false, updatable = false) @JoinColumn(name = "merchant_id", insertable = false, updatable = false)
@ -67,14 +67,14 @@ public class BankCard extends AbstractBaseEntity {
/** /**
* 是否默认卡 * 是否默认卡
*/ */
@Column(name = "is_default", nullable = false) @Column(name = "is_default")
@Comment("是否默认卡") @Comment("是否默认卡")
private Boolean isDefault = false; private Boolean isDefault = false;
/** /**
* 状态0-禁用 1-启用 * 状态0-禁用 1-启用
*/ */
@Column(name = "status",columnDefinition = "VARCHAR(15)",length = 15, nullable = false) @Column(name = "status",columnDefinition = "VARCHAR(15)",length = 15)
@Enumerated(EnumType.STRING) @Enumerated(EnumType.STRING)
@Comment("状态0禁用 1启用") @Comment("状态0禁用 1启用")
private CommonStatus status = CommonStatus.ENABLED; private CommonStatus status = CommonStatus.ENABLED;

View file

@ -1,7 +1,7 @@
package com.xjhs.findmemerchant.entity; package com.xjhs.findmemerchant.entity;
import com.xjhs.findmemerchant.adapter.json.HashMapJsonConverter; import com.xjhs.findmemerchant.common.jpa.json.HashMapJsonConverter;
import com.xjhs.findmemerchant.common.jpa.AbstractBaseEntity; import com.xjhs.findmemerchant.common.jpa.AbstractBaseEntity;
import com.xjhs.findmemerchant.types.BusinessLicenseStatus; import com.xjhs.findmemerchant.types.BusinessLicenseStatus;
import jakarta.persistence.*; import jakarta.persistence.*;
@ -30,7 +30,7 @@ public class BusinessLicense extends AbstractBaseEntity {
@JoinColumn(name = "merchant_id", insertable = false, updatable = false) @JoinColumn(name = "merchant_id", insertable = false, updatable = false)
private Merchant merchant; private Merchant merchant;
@Column(name = "image_url", nullable = false, length = 500) @Column(name = "image_url", length = 500)
@Comment("营业执照图片URL") @Comment("营业执照图片URL")
private String imageUrl; private String imageUrl;
@ -47,7 +47,7 @@ public class BusinessLicense extends AbstractBaseEntity {
@Comment("OCR原始结果") @Comment("OCR原始结果")
private HashMap<String, Object> ocrRaw; private HashMap<String, Object> ocrRaw;
@Column(name = "status",length = 15,columnDefinition = "VARCHAR(15)", nullable = false) @Column(name = "status",length = 15,columnDefinition = "VARCHAR(15)")
@Enumerated(EnumType.STRING) @Enumerated(EnumType.STRING)
@Comment("状态0待审核 1已通过 2已拒绝") @Comment("状态0待审核 1已通过 2已拒绝")
private BusinessLicenseStatus status = BusinessLicenseStatus.PENDING; private BusinessLicenseStatus status = BusinessLicenseStatus.PENDING;

View file

@ -32,28 +32,28 @@ public class BusinessPeriod extends AbstractBaseEntity {
/** /**
* 周几0=周日 ... 6=周六 * 周几0=周日 ... 6=周六
*/ */
@Column(name = "day_of_week", nullable = false) @Column(name = "day_of_week")
@Comment("周几0周日 1周一 ... 6周六") @Comment("周几0周日 1周一 ... 6周六")
private Byte dayOfWeek; private Integer dayOfWeek;
/** /**
* 开始时间HH:MM * 开始时间HH:MM
*/ */
@Column(name = "start_time", nullable = false, length = 5) @Column(name = "start_time", length = 5)
@Comment("开始时间HH:MM") @Comment("开始时间HH:MM")
private String startTime; private String startTime;
/** /**
* 结束时间HH:MM * 结束时间HH:MM
*/ */
@Column(name = "end_time", nullable = false, length = 5) @Column(name = "end_time", length = 5)
@Comment("结束时间HH:MM") @Comment("结束时间HH:MM")
private String endTime; private String endTime;
/** /**
* 是否启用 * 是否启用
*/ */
@Column(name = "is_enabled", nullable = false) @Column(name = "is_enabled")
@Comment("是否启用") @Comment("是否启用")
private Boolean isEnabled = Boolean.TRUE; private Boolean isEnabled = Boolean.TRUE;

View file

@ -32,14 +32,14 @@ public class Coupon extends AbstractBaseEntity {
/** /**
* 优惠券名称 * 优惠券名称
*/ */
@Column(name = "name", nullable = false, length = 100) @Column(name = "name", length = 100)
@Comment("优惠券名称") @Comment("优惠券名称")
private String name; private String name;
/** /**
* 优惠券类型1-折扣券 2-满减券 3-现金券 4-赠品券 * 优惠券类型1-折扣券 2-满减券 3-现金券 4-赠品券
*/ */
@Column(name = "type",length = 15,columnDefinition = "VARCHAR(15)", nullable = false) @Column(name = "type",length = 15,columnDefinition = "VARCHAR(15)")
@Comment("优惠券类型1折扣券 2满减券 3现金券 4赠品券") @Comment("优惠券类型1折扣券 2满减券 3现金券 4赠品券")
private CouponType type; private CouponType type;
@ -74,49 +74,49 @@ public class Coupon extends AbstractBaseEntity {
/** /**
* 赠品数量默认 1 * 赠品数量默认 1
*/ */
@Column(name = "gift_quantity", nullable = false) @Column(name = "gift_quantity")
@Comment("赠品数量") @Comment("赠品数量")
private Integer giftQuantity = 1; private Integer giftQuantity = 1;
/** /**
* 发放总量 * 发放总量
*/ */
@Column(name = "total_count", nullable = false) @Column(name = "total_count")
@Comment("发放总量") @Comment("发放总量")
private Integer totalCount; private Integer totalCount;
/** /**
* 已领取数量 * 已领取数量
*/ */
@Column(name = "claimed_count", nullable = false) @Column(name = "claimed_count")
@Comment("已领取数量") @Comment("已领取数量")
private Integer claimedCount = 0; private Integer claimedCount = 0;
/** /**
* 每人限领数量0 表示不限 * 每人限领数量0 表示不限
*/ */
@Column(name = "per_user_limit", nullable = false) @Column(name = "per_user_limit")
@Comment("每人限领数量0表示不限") @Comment("每人限领数量0表示不限")
private Integer perUserLimit = 1; private Integer perUserLimit = 1;
/** /**
* 领取后有效天数 * 领取后有效天数
*/ */
@Column(name = "valid_days", nullable = false) @Column(name = "valid_days")
@Comment("领取后有效天数") @Comment("领取后有效天数")
private Integer validDays; private Integer validDays;
/** /**
* 活动开始时间 * 活动开始时间
*/ */
@Column(name = "start_time", nullable = false) @Column(name = "start_time")
@Comment("活动开始时间") @Comment("活动开始时间")
private LocalDateTime startTime; private LocalDateTime startTime;
/** /**
* 活动结束时间 * 活动结束时间
*/ */
@Column(name = "end_time", nullable = false) @Column(name = "end_time")
@Comment("活动结束时间") @Comment("活动结束时间")
private LocalDateTime endTime; private LocalDateTime endTime;
@ -130,7 +130,7 @@ public class Coupon extends AbstractBaseEntity {
/** /**
* 状态0-下架 1-进行中 2-已结束 * 状态0-下架 1-进行中 2-已结束
*/ */
@Column(name = "status",columnDefinition = "VARCHAR(15)",length = 15, nullable = false) @Column(name = "status",columnDefinition = "VARCHAR(15)",length = 15)
@Comment("状态0下架 1进行中 2已结束") @Comment("状态0下架 1进行中 2已结束")
private CouponStatus status = CouponStatus.ONLINE; private CouponStatus status = CouponStatus.ONLINE;
@ -138,7 +138,7 @@ public class Coupon extends AbstractBaseEntity {
// ================= 关联关系 ================= // ================= 关联关系 =================
/** /**
* 所属商 * 所属商
*/ */
@ManyToOne(fetch = FetchType.LAZY) @ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "merchant_id", insertable = false, updatable = false) @JoinColumn(name = "merchant_id", insertable = false, updatable = false)

View file

@ -33,14 +33,14 @@ public class CouponCode extends AbstractBaseEntity {
/** /**
* 券码 * 券码
*/ */
@Column(name = "code", nullable = false, length = 32) @Column(name = "code", length = 32)
@Comment("优惠券码") @Comment("优惠券码")
private String code; private String code;
/** /**
* 状态0-未领取 1-已领取 2-已核销 3-已过期 * 状态0-未领取 1-已领取 2-已核销 3-已过期
*/ */
@Column(name = "status",columnDefinition = "VARCHAR(20)",length = 20, nullable = false) @Column(name = "status",columnDefinition = "VARCHAR(20)",length = 20)
@Comment("状态0未领取 1已领取 2已核销 3已过期") @Comment("状态0未领取 1已领取 2已核销 3已过期")
private CouponCodeStatus status = CouponCodeStatus.UNCLAIMED; private CouponCodeStatus status = CouponCodeStatus.UNCLAIMED;
@ -117,7 +117,7 @@ public class CouponCode extends AbstractBaseEntity {
*/ */
public boolean isClaimed() { public boolean isClaimed() {
return this.status != null && return this.status != null &&
this.status.getCodeValue() >= CouponCodeStatus.CLAIMED.getCodeValue(); this.status.ordinal() >= CouponCodeStatus.CLAIMED.ordinal();
} }
/** /**

View file

@ -29,35 +29,27 @@ public class Employee extends AbstractBaseEntity {
/** /**
* 手机号 * 手机号
*/ */
@Column(name = "phone", nullable = false, length = 11) @Column(name = "phone", length = 11)
@Comment("手机号") @Comment("手机号")
private String phone; private String phone;
/** /**
* 员工姓名 * 员工姓名
*/ */
@Column(name = "name", nullable = false, length = 50) @Column(name = "name", length = 50)
@Comment("员工姓名") @Comment("员工姓名")
private String name; private String name;
/** /**
* 状态0-禁用 1-启用 * 状态0-禁用 1-启用
*/ */
@Column(name = "status",columnDefinition = "VARCHAR(15)",length = 15, nullable = false) @Column(name = "status",columnDefinition = "VARCHAR(15)",length = 15)
@Comment("状态0禁用 1启用") @Comment("状态")
private CommonStatus status = CommonStatus.ENABLED; private CommonStatus status = CommonStatus.ENABLED;
// ===== 关联关系 ===== // ===== 关联关系 =====
/**
* 商户
*/
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "merchant_id", insertable = false, updatable = false)
private Merchant merchant;
/** /**
* 门店 * 门店
*/ */

View file

@ -1,6 +1,6 @@
package com.xjhs.findmemerchant.entity; package com.xjhs.findmemerchant.entity;
import com.xjhs.findmemerchant.adapter.json.HashMapJsonConverter; import com.xjhs.findmemerchant.common.jpa.json.HashMapJsonConverter;
import com.xjhs.findmemerchant.common.jpa.AbstractBaseEntity; import com.xjhs.findmemerchant.common.jpa.AbstractBaseEntity;
import com.xjhs.findmemerchant.types.HealthCertificateStatus; import com.xjhs.findmemerchant.types.HealthCertificateStatus;
import jakarta.persistence.*; import jakarta.persistence.*;
@ -27,7 +27,7 @@ import java.util.HashMap;
) )
public class HealthCertificate extends AbstractBaseEntity { public class HealthCertificate extends AbstractBaseEntity {
@Column(name = "image_url", nullable = false, length = 500) @Column(name = "image_url", length = 500)
@Comment("健康证图片URL") @Comment("健康证图片URL")
private String imageUrl; private String imageUrl;
@ -48,7 +48,7 @@ public class HealthCertificate extends AbstractBaseEntity {
@Comment("OCR原始结果") @Comment("OCR原始结果")
private HashMap<String, Object> ocrRaw; private HashMap<String, Object> ocrRaw;
@Column(name = "status",columnDefinition = "VARCHAR(20)",length = 20, nullable = false) @Column(name = "status",columnDefinition = "VARCHAR(20)",length = 20)
@Comment("状态0待审核 1有效 2过期") @Comment("状态0待审核 1有效 2过期")
private HealthCertificateStatus status = HealthCertificateStatus.PENDING; private HealthCertificateStatus status = HealthCertificateStatus.PENDING;

View file

@ -34,7 +34,7 @@ public class Member extends AbstractBaseEntity {
/** /**
* 手机号 * 手机号
*/ */
@Column(name = "phone", nullable = false, length = 11) @Column(name = "phone", length = 11)
@Comment("手机号") @Comment("手机号")
private String phone; private String phone;
@ -55,14 +55,14 @@ public class Member extends AbstractBaseEntity {
/** /**
* 累计订单数 * 累计订单数
*/ */
@Column(name = "total_orders", nullable = false) @Column(name = "total_orders")
@Comment("累计订单数") @Comment("累计订单数")
private Integer totalOrders = 0; private Integer totalOrders = 0;
/** /**
* 累计消费金额 * 累计消费金额
*/ */
@Column(name = "total_amount", nullable = false, precision = 12, scale = 2) @Column(name = "total_amount", precision = 12, scale = 2)
@Comment("累计消费金额") @Comment("累计消费金额")
private BigDecimal totalAmount = BigDecimal.ZERO; private BigDecimal totalAmount = BigDecimal.ZERO;
@ -75,7 +75,7 @@ public class Member extends AbstractBaseEntity {
// ============ 关联关系 ============ // ============ 关联关系 ============
/** /**
* *
*/ */
@ManyToOne(fetch = FetchType.LAZY) @ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "merchant_id", insertable = false, updatable = false) @JoinColumn(name = "merchant_id", insertable = false, updatable = false)

View file

@ -12,7 +12,7 @@ import org.hibernate.annotations.Comment;
import java.util.List; import java.util.List;
/** /**
* 实体 * 实体
* 对应表merchants * 对应表merchants
*/ */
@Getter @Getter
@ -34,7 +34,7 @@ public class Merchant extends AbstractBaseEntity {
/** /**
* 登录手机号 * 登录手机号
*/ */
@Column(name = "phone", nullable = false, length = 11) @Column(name = "phone", length = 11)
@Comment("手机号") @Comment("手机号")
private String phone; private String phone;
@ -68,15 +68,17 @@ public class Merchant extends AbstractBaseEntity {
/** /**
* 认证状态 * 认证状态
*/ */
@Column(name = "auth_status",length = 20,columnDefinition = "VARCHAR(20)", nullable = false) @Column(name = "auth_status",length = 20,columnDefinition = "VARCHAR(20)")
@Comment("认证状态0未认证 1已认证") @Comment("认证状态")
@Enumerated(EnumType.STRING)
private AuthStatus authStatus = AuthStatus.NOT_VERIFIED; private AuthStatus authStatus = AuthStatus.NOT_VERIFIED;
/** /**
* 账户状态 * 账户状态
*/ */
@Column(name = "status", nullable = false) @Column(name = "status",length = 20,columnDefinition = "VARCHAR(20)")
@Comment("账户状态0禁用 1启用") @Comment("账户状态")
@Enumerated(EnumType.STRING)
private CommonStatus status = CommonStatus.ENABLED; private CommonStatus status = CommonStatus.ENABLED;
// ========== 关联关系 ========== // ========== 关联关系 ==========

View file

@ -28,7 +28,7 @@ public class Message extends AbstractBaseEntity {
/** /**
* 消息类型1-系统通知 2-活动提醒 3-私信 * 消息类型1-系统通知 2-活动提醒 3-私信
*/ */
@Column(name = "type",columnDefinition = "VARCHAR(20)",length = 20,nullable = false) @Column(name = "type",columnDefinition = "VARCHAR(20)",length = 20)
@Enumerated(EnumType.STRING) @Enumerated(EnumType.STRING)
@Comment("消息类型1系统通知 2活动提醒 3私信") @Comment("消息类型1系统通知 2活动提醒 3私信")
private MessageType type; private MessageType type;
@ -36,28 +36,28 @@ public class Message extends AbstractBaseEntity {
/** /**
* 标题 * 标题
*/ */
@Column(name = "title", nullable = false, length = 200) @Column(name = "title", length = 200)
@Comment("消息标题") @Comment("消息标题")
private String title; private String title;
/** /**
* 内容 * 内容
*/ */
@Column(name = "content", nullable = false, columnDefinition = "text") @Column(name = "content", columnDefinition = "text")
@Comment("消息内容") @Comment("消息内容")
private String content; private String content;
/** /**
* 是否已读0-未读 1-已读 * 是否已读0-未读 1-已读
*/ */
@Column(name = "is_read", nullable = false) @Column(name = "is_read")
@Comment("是否已读0未读 1已读") @Comment("是否已读0未读 1已读")
private Byte isRead = 0; private Boolean isRead = false;
/** /**
* 创建时间 * 创建时间
*/ */
@Column(name = "created_at", nullable = false) @Column(name = "created_at")
@Comment("创建时间") @Comment("创建时间")
private LocalDateTime createdAt; private LocalDateTime createdAt;
@ -69,7 +69,7 @@ public class Message extends AbstractBaseEntity {
private LocalDateTime readAt; private LocalDateTime readAt;
/** /**
* *
*/ */
@ManyToOne(fetch = FetchType.LAZY) @ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "merchant_id", insertable = false, updatable = false) @JoinColumn(name = "merchant_id", insertable = false, updatable = false)
@ -81,7 +81,7 @@ public class Message extends AbstractBaseEntity {
* 标记为已读 * 标记为已读
*/ */
public void markAsRead() { public void markAsRead() {
this.isRead = 1; this.isRead = true;
this.readAt = LocalDateTime.now(); this.readAt = LocalDateTime.now();
} }
@ -89,7 +89,7 @@ public class Message extends AbstractBaseEntity {
* 是否未读 * 是否未读
*/ */
public boolean isUnread() { public boolean isUnread() {
return this.isRead != null && this.isRead == 0; return this.isRead != null && !this.isRead;
} }
/** /**

View file

@ -33,7 +33,7 @@ public class Order extends AbstractBaseEntity {
/** /**
* 订单号 * 订单号
*/ */
@Column(name = "order_no", nullable = false, length = 32) @Column(name = "order_no", length = 32)
@Comment("订单号") @Comment("订单号")
private String orderNo; private String orderNo;
@ -41,21 +41,21 @@ public class Order extends AbstractBaseEntity {
/** /**
* 订单总金额 * 订单总金额
*/ */
@Column(name = "total_amount", nullable = false, precision = 10, scale = 2) @Column(name = "total_amount", precision = 10, scale = 2)
@Comment("订单总金额") @Comment("订单总金额")
private BigDecimal totalAmount; private BigDecimal totalAmount;
/** /**
* 优惠金额 * 优惠金额
*/ */
@Column(name = "discount_amount", nullable = false, precision = 10, scale = 2) @Column(name = "discount_amount", precision = 10, scale = 2)
@Comment("优惠金额") @Comment("优惠金额")
private BigDecimal discountAmount = BigDecimal.ZERO; private BigDecimal discountAmount = BigDecimal.ZERO;
/** /**
* 实付金额 * 实付金额
*/ */
@Column(name = "pay_amount", nullable = false, precision = 10, scale = 2) @Column(name = "pay_amount", precision = 10, scale = 2)
@Comment("实付金额") @Comment("实付金额")
private BigDecimal payAmount; private BigDecimal payAmount;
@ -69,7 +69,7 @@ public class Order extends AbstractBaseEntity {
/** /**
* 订单状态1-待支付 2-已支付 3-已完成 4-已退款 5-已取消 * 订单状态1-待支付 2-已支付 3-已完成 4-已退款 5-已取消
*/ */
@Column(name = "status", nullable = false) @Column(name = "status")
@Comment("订单状态1待支付 2已支付 3已完成 4已退款 5已取消") @Comment("订单状态1待支付 2已支付 3已完成 4已退款 5已取消")
private OrderStatus status; private OrderStatus status;

View file

@ -1,6 +1,6 @@
package com.xjhs.findmemerchant.entity; package com.xjhs.findmemerchant.entity;
import com.xjhs.findmemerchant.adapter.id.SnowflakeGenerated; import com.xjhs.findmemerchant.common.jpa.id.SnowflakeGenerated;
import jakarta.persistence.*; import jakarta.persistence.*;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
@ -32,7 +32,6 @@ public class OrderItem {
@Id @Id
@GeneratedValue @GeneratedValue
@SnowflakeGenerated @SnowflakeGenerated
@Column(nullable = false)
@Comment("主键ID") @Comment("主键ID")
private Long id; private Long id;
@ -48,7 +47,7 @@ public class OrderItem {
/** /**
* 商品名称快照 * 商品名称快照
*/ */
@Column(name = "product_name", nullable = false, length = 100) @Column(name = "product_name", length = 100)
@Comment("商品名称(快照)") @Comment("商品名称(快照)")
private String productName; private String productName;
@ -76,28 +75,28 @@ public class OrderItem {
/** /**
* 商品单价 * 商品单价
*/ */
@Column(name = "unit_price", nullable = false, precision = 10, scale = 2) @Column(name = "unit_price", precision = 10, scale = 2)
@Comment("商品单价") @Comment("商品单价")
private BigDecimal unitPrice; private BigDecimal unitPrice;
/** /**
* 购买数量 * 购买数量
*/ */
@Column(name = "quantity", nullable = false) @Column(name = "quantity")
@Comment("购买数量") @Comment("购买数量")
private Integer quantity = 1; private Integer quantity = 1;
/** /**
* 小计金额 * 小计金额
*/ */
@Column(name = "total_price", nullable = false, precision = 10, scale = 2) @Column(name = "total_price", precision = 10, scale = 2)
@Comment("小计金额") @Comment("小计金额")
private BigDecimal totalPrice; private BigDecimal totalPrice;
/** /**
* 创建时间 * 创建时间
*/ */
@Column(name = "created_at", nullable = false) @Column(name = "created_at")
@Comment("创建时间") @Comment("创建时间")
private LocalDateTime createdAt; private LocalDateTime createdAt;
@ -107,7 +106,7 @@ public class OrderItem {
* 所属订单 * 所属订单
*/ */
@ManyToOne(fetch = FetchType.LAZY) @ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "order_id", insertable = false, updatable = false) @JoinColumn(name = "order_id")
private Order order; private Order order;
// ========== 业务方法 ========== // ========== 业务方法 ==========

View file

@ -8,6 +8,7 @@ import lombok.Setter;
import org.hibernate.annotations.Comment; import org.hibernate.annotations.Comment;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.List; import java.util.List;
/** /**
@ -31,7 +32,7 @@ public class Product extends AbstractBaseEntity {
/** /**
* 商品名称 * 商品名称
*/ */
@Column(name = "name", nullable = false, length = 100) @Column(name = "name", length = 100)
@Comment("商品名称") @Comment("商品名称")
private String name; private String name;
@ -52,42 +53,42 @@ public class Product extends AbstractBaseEntity {
/** /**
* 原价 * 原价
*/ */
@Column(name = "original_price", nullable = false, precision = 10, scale = 2) @Column(name = "original_price", precision = 10, scale = 2)
@Comment("原价") @Comment("原价")
private BigDecimal originalPrice; private BigDecimal originalPrice;
/** /**
* 售价 * 售价
*/ */
@Column(name = "sale_price", nullable = false, precision = 10, scale = 2) @Column(name = "sale_price", precision = 10, scale = 2)
@Comment("售价") @Comment("售价")
private BigDecimal salePrice; private BigDecimal salePrice;
/** /**
* 库存-1 表示无限库存 * 库存-1 表示无限库存
*/ */
@Column(name = "stock", nullable = false) @Column(name = "stock")
@Comment("库存,-1表示无限库存") @Comment("库存,-1表示无限库存")
private Integer stock = -1; private Integer stock = -1;
/** /**
* 已售数量 * 已售数量
*/ */
@Column(name = "sold_count", nullable = false) @Column(name = "sold_count")
@Comment("已售数量") @Comment("已售数量")
private Integer soldCount = 0; private Integer soldCount = 0;
/** /**
* 排序值 * 排序值
*/ */
@Column(name = "sort_order", nullable = false) @Column(name = "sort_order")
@Comment("排序值") @Comment("排序值")
private Integer sortOrder = 0; private Integer sortOrder = 0;
/** /**
* 商品状态0-下架 1-上架 * 商品状态0-下架 1-上架
*/ */
@Column(name = "status",columnDefinition = "VARCHAR(20)",length = 20, nullable = false) @Column(name = "status",columnDefinition = "VARCHAR(20)",length = 20)
@Enumerated(EnumType.STRING) @Enumerated(EnumType.STRING)
@Comment("商品状态0下架 1上架") @Comment("商品状态0下架 1上架")
private ProductStatus status = ProductStatus.OFF_SALE; private ProductStatus status = ProductStatus.OFF_SALE;
@ -95,7 +96,7 @@ public class Product extends AbstractBaseEntity {
// ========== 关联关系 ========== // ========== 关联关系 ==========
/** /**
* *
*/ */
@ManyToOne(fetch = FetchType.LAZY) @ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "merchant_id", insertable = false, updatable = false) @JoinColumn(name = "merchant_id", insertable = false, updatable = false)
@ -155,7 +156,7 @@ public class Product extends AbstractBaseEntity {
return 0; return 0;
} }
BigDecimal rate = salePrice BigDecimal rate = salePrice
.divide(originalPrice, 2, BigDecimal.ROUND_HALF_UP) .divide(originalPrice, 2, RoundingMode.HALF_UP)
.multiply(BigDecimal.valueOf(100)); .multiply(BigDecimal.valueOf(100));
return rate.intValue(); return rate.intValue();
} }

View file

@ -29,7 +29,7 @@ public class ProductCategory extends AbstractBaseEntity {
/** /**
* 分类名称 * 分类名称
*/ */
@Column(name = "name", nullable = false, length = 50) @Column(name = "name", length = 50)
@Comment("分类名称") @Comment("分类名称")
private String name; private String name;
@ -43,21 +43,21 @@ public class ProductCategory extends AbstractBaseEntity {
/** /**
* 排序值 * 排序值
*/ */
@Column(name = "sort_order", nullable = false) @Column(name = "sort_order")
@Comment("排序值") @Comment("排序值")
private Integer sortOrder = 0; private Integer sortOrder = 0;
/** /**
* 状态0-禁用 1-启用 * 状态0-禁用 1-启用
*/ */
@Column(name = "status", nullable = false) @Column(name = "status")
@Comment("状态0禁用 1启用") @Comment("状态0禁用 1启用")
private CommonStatus status = CommonStatus.ENABLED; private CommonStatus status = CommonStatus.ENABLED;
// ========== 关联关系 ========== // ========== 关联关系 ==========
/** /**
* *
*/ */
@ManyToOne(fetch = FetchType.LAZY) @ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "merchant_id", insertable = false, updatable = false) @JoinColumn(name = "merchant_id", insertable = false, updatable = false)

View file

@ -1,6 +1,6 @@
package com.xjhs.findmemerchant.entity; package com.xjhs.findmemerchant.entity;
import com.xjhs.findmemerchant.adapter.id.SnowflakeGenerated; import com.xjhs.findmemerchant.common.jpa.id.SnowflakeGenerated;
import com.xjhs.findmemerchant.common.jpa.AbstractBaseEntity; import com.xjhs.findmemerchant.common.jpa.AbstractBaseEntity;
import com.xjhs.findmemerchant.types.CommonStatus; import com.xjhs.findmemerchant.types.CommonStatus;
import jakarta.persistence.*; import jakarta.persistence.*;
@ -32,14 +32,13 @@ public class ProductSKU extends AbstractBaseEntity {
@Id @Id
@GeneratedValue @GeneratedValue
@SnowflakeGenerated @SnowflakeGenerated
@Column(nullable = false)
@Comment("主键ID") @Comment("主键ID")
private Long id; private Long id;
/** /**
* 规格名称大杯/加冰 * 规格名称大杯/加冰
*/ */
@Column(name = "sku_name", nullable = false, length = 100) @Column(name = "sku_name", length = 100)
@Comment("规格名称") @Comment("规格名称")
private String skuName; private String skuName;
@ -53,28 +52,28 @@ public class ProductSKU extends AbstractBaseEntity {
/** /**
* 售价 * 售价
*/ */
@Column(name = "price", nullable = false, precision = 10, scale = 2) @Column(name = "price", precision = 10, scale = 2)
@Comment("规格价格") @Comment("规格价格")
private BigDecimal price; private BigDecimal price;
/** /**
* 库存-1 表示无限库存 * 库存-1 表示无限库存
*/ */
@Column(name = "stock", nullable = false) @Column(name = "stock")
@Comment("库存,-1表示无限库存") @Comment("库存,-1表示无限库存")
private Integer stock = -1; private Integer stock = -1;
/** /**
* 已售数量 * 已售数量
*/ */
@Column(name = "sold_count", nullable = false) @Column(name = "sold_count")
@Comment("已售数量") @Comment("已售数量")
private Integer soldCount = 0; private Integer soldCount = 0;
/** /**
* 状态0-禁用 1-启用 * 状态0-禁用 1-启用
*/ */
@Column(name = "status",columnDefinition = "VARCHAR(20)",length = 20,nullable = false) @Column(name = "status",columnDefinition = "VARCHAR(20)",length = 20)
@Comment("状态0禁用 1启用") @Comment("状态0禁用 1启用")
private CommonStatus status = CommonStatus.ENABLED; private CommonStatus status = CommonStatus.ENABLED;

View file

@ -27,19 +27,12 @@ import org.hibernate.annotations.Comment;
public class Review extends AbstractBaseEntity { public class Review extends AbstractBaseEntity {
/**
* 订单ID
*/
@Column(name = "order_id", nullable = false)
@Comment("订单ID")
private Long orderId;
/** /**
* C端用户ID * C端用户ID
*/ */
@Column(name = "user_id", nullable = false) @Column(name = "user_id")
@Comment("C端用户ID") @Comment("C端用户ID")
private Long userId; private Long userId;
@ -60,7 +53,7 @@ public class Review extends AbstractBaseEntity {
/** /**
* 评分 1-5 * 评分 1-5
*/ */
@Column(name = "rating", nullable = false) @Column(name = "rating")
@Comment("评分 1-5") @Comment("评分 1-5")
private Integer rating; private Integer rating;
@ -81,14 +74,14 @@ public class Review extends AbstractBaseEntity {
/** /**
* 是否匿名 * 是否匿名
*/ */
@Column(name = "is_anonymous", nullable = false) @Column(name = "is_anonymous")
@Comment("是否匿名") @Comment("是否匿名")
private Boolean isAnonymous = Boolean.FALSE; private Boolean isAnonymous = Boolean.FALSE;
/** /**
* 状态1-正常 0-隐藏 * 状态1-正常 0-隐藏
*/ */
@Column(name = "status",columnDefinition = "VARCHAR(20)",length = 20, nullable = false) @Column(name = "status",columnDefinition = "VARCHAR(20)",length = 20)
@Comment("状态1正常 0隐藏") @Comment("状态1正常 0隐藏")
private ReviewStatus status = ReviewStatus.NORMAL; private ReviewStatus status = ReviewStatus.NORMAL;
@ -104,16 +97,25 @@ public class Review extends AbstractBaseEntity {
* 门店 * 门店
*/ */
@ManyToOne(fetch = FetchType.LAZY) @ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "store_id", insertable = false, updatable = false) @JoinColumn(name = "merchant_id")
private Merchant merchant;
/**
* 门店
*/
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "store_id")
private Store store; private Store store;
/** /**
* 订单 * 订单
*/ */
@ManyToOne(fetch = FetchType.LAZY) @ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "order_id", insertable = false, updatable = false) @JoinColumn(name = "order_id")
private Order order; private Order order;
// ========== 业务方法 ========== // ========== 业务方法 ==========
/** /**

View file

@ -1,6 +1,6 @@
package com.xjhs.findmemerchant.entity; package com.xjhs.findmemerchant.entity;
import com.xjhs.findmemerchant.adapter.id.SnowflakeGenerated; import com.xjhs.findmemerchant.common.jpa.id.SnowflakeGenerated;
import jakarta.persistence.*; import jakarta.persistence.*;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
@ -30,35 +30,34 @@ public class ReviewReply{
@Id @Id
@GeneratedValue @GeneratedValue
@SnowflakeGenerated @SnowflakeGenerated
@Column(nullable = false)
@Comment("主键ID") @Comment("主键ID")
private Long id; private Long id;
/** /**
* 评价ID唯一一个评价一条回复 * 评价ID唯一一个评价一条回复
*/ */
@Column(name = "review_id", nullable = false) @Column(name = "review_id")
@Comment("评价ID") @Comment("评价ID")
private Long reviewId; private Long reviewId;
/** /**
* ID * ID
*/ */
@Column(name = "merchant_id", nullable = false) @Column(name = "merchant_id")
@Comment("ID") @Comment("ID")
private Long merchantId; private Long merchantId;
/** /**
* 回复内容 * 回复内容
*/ */
@Column(name = "content", nullable = false, columnDefinition = "text") @Column(name = "content", columnDefinition = "text")
@Comment("回复内容") @Comment("回复内容")
private String content; private String content;
/** /**
* 回复人ID商家或员工 * 回复人ID商家或员工
*/ */
@Column(name = "replier_id", nullable = false) @Column(name = "replier_id")
@Comment("回复人ID商家或员工") @Comment("回复人ID商家或员工")
private Long replierId; private Long replierId;

View file

@ -1,6 +1,6 @@
package com.xjhs.findmemerchant.entity; package com.xjhs.findmemerchant.entity;
import com.xjhs.findmemerchant.adapter.json.StringListJsonConverter; import com.xjhs.findmemerchant.common.jpa.json.StringListJsonConverter;
import com.xjhs.findmemerchant.common.jpa.AbstractBaseEntity; import com.xjhs.findmemerchant.common.jpa.AbstractBaseEntity;
import jakarta.persistence.*; import jakarta.persistence.*;
import lombok.Getter; import lombok.Getter;
@ -32,14 +32,14 @@ public class Role extends AbstractBaseEntity {
/** /**
* 角色名称 * 角色名称
*/ */
@Column(name = "name", nullable = false, length = 50) @Column(name = "name", length = 50)
@Comment("角色名称") @Comment("角色名称")
private String name; private String name;
/** /**
* 角色编码唯一 * 角色编码唯一
*/ */
@Column(name = "code", nullable = false, length = 50) @Column(name = "code", length = 50)
@Comment("角色编码") @Comment("角色编码")
private String code; private String code;
@ -54,14 +54,14 @@ public class Role extends AbstractBaseEntity {
* 权限列表JSON数组 * 权限列表JSON数组
*/ */
@Convert(converter = StringListJsonConverter.class) @Convert(converter = StringListJsonConverter.class)
@Column(name = "permissions", nullable = false, columnDefinition = "json") @Column(name = "permissions", columnDefinition = "json")
@Comment("权限列表JSON数组") @Comment("权限列表JSON数组")
private List<String> permissions = new ArrayList<>(); private List<String> permissions = new ArrayList<>();
/** /**
* 是否系统内置角色1- 0- * 是否系统内置角色1- 0-
*/ */
@Column(name = "is_system", nullable = false) @Column(name = "is_system")
@Comment("是否系统内置角色1是 0否") @Comment("是否系统内置角色1是 0否")
private Byte isSystem = 0; private Byte isSystem = 0;

View file

@ -35,7 +35,7 @@ public class Settlement extends AbstractBaseEntity {
DateTimeFormatter.ofPattern("yyyy-MM-dd"); DateTimeFormatter.ofPattern("yyyy-MM-dd");
/** /**
* *
*/ */
@ManyToOne(fetch = FetchType.LAZY) @ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "merchant_id", insertable = false, updatable = false) @JoinColumn(name = "merchant_id", insertable = false, updatable = false)
@ -45,70 +45,70 @@ public class Settlement extends AbstractBaseEntity {
/** /**
* 结算单号 * 结算单号
*/ */
@Column(name = "settlement_no", nullable = false, length = 32) @Column(name = "settlement_no", length = 32)
@Comment("结算单号") @Comment("结算单号")
private String settlementNo; private String settlementNo;
/** /**
* 结算类型1-日结 2-周结 * 结算类型1-日结 2-周结
*/ */
@Column(name = "type", nullable = false) @Column(name = "type")
@Comment("结算类型1日结 2周结") @Comment("结算类型1日结 2周结")
private SettlementType type; private SettlementType type;
/** /**
* 结算周期开始时间 * 结算周期开始时间
*/ */
@Column(name = "period_start", nullable = false) @Column(name = "period_start")
@Comment("结算周期开始时间") @Comment("结算周期开始时间")
private LocalDateTime periodStart; private LocalDateTime periodStart;
/** /**
* 结算周期结束时间 * 结算周期结束时间
*/ */
@Column(name = "period_end", nullable = false) @Column(name = "period_end")
@Comment("结算周期结束时间") @Comment("结算周期结束时间")
private LocalDateTime periodEnd; private LocalDateTime periodEnd;
/** /**
* 订单数量 * 订单数量
*/ */
@Column(name = "order_count", nullable = false) @Column(name = "order_count")
@Comment("订单数量") @Comment("订单数量")
private Integer orderCount = 0; private Integer orderCount = 0;
/** /**
* 订单总额 * 订单总额
*/ */
@Column(name = "total_amount", nullable = false, precision = 12, scale = 2) @Column(name = "total_amount", precision = 12, scale = 2)
@Comment("订单总额") @Comment("订单总额")
private BigDecimal totalAmount; private BigDecimal totalAmount;
/** /**
* 退款金额 * 退款金额
*/ */
@Column(name = "refund_amount", nullable = false, precision = 12, scale = 2) @Column(name = "refund_amount", precision = 12, scale = 2)
@Comment("退款金额") @Comment("退款金额")
private BigDecimal refundAmount = BigDecimal.ZERO; private BigDecimal refundAmount = BigDecimal.ZERO;
/** /**
* 平台服务费 * 平台服务费
*/ */
@Column(name = "platform_fee", nullable = false, precision = 10, scale = 2) @Column(name = "platform_fee", precision = 10, scale = 2)
@Comment("平台服务费") @Comment("平台服务费")
private BigDecimal platformFee = BigDecimal.ZERO; private BigDecimal platformFee = BigDecimal.ZERO;
/** /**
* 结算金额 * 结算金额
*/ */
@Column(name = "settlement_amount", nullable = false, precision = 12, scale = 2) @Column(name = "settlement_amount", precision = 12, scale = 2)
@Comment("结算金额") @Comment("结算金额")
private BigDecimal settlementAmount; private BigDecimal settlementAmount;
/** /**
* 结算状态0-待结算 1-已结算 * 结算状态0-待结算 1-已结算
*/ */
@Column(name = "status", nullable = false) @Column(name = "status")
@Comment("结算状态0待结算 1已结算") @Comment("结算状态0待结算 1已结算")
private SettlementStatus status = SettlementStatus.PENDING; private SettlementStatus status = SettlementStatus.PENDING;

View file

@ -9,7 +9,9 @@ import lombok.Getter;
import lombok.Setter; import lombok.Setter;
import org.hibernate.annotations.Comment; import org.hibernate.annotations.Comment;
import java.math.BigDecimal;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List; import java.util.List;
/** /**
@ -30,7 +32,7 @@ public class Store extends AbstractBaseEntity {
/** /**
* 门店名称 * 门店名称
*/ */
@Column(name = "name", nullable = false, length = 100) @Column(name = "name", length = 100)
@Comment("门店名称") @Comment("门店名称")
private String name; private String name;
@ -44,35 +46,35 @@ public class Store extends AbstractBaseEntity {
/** /**
* 联系电话 * 联系电话
*/ */
@Column(name = "phone", nullable = false, length = 11) @Column(name = "phone", length = 11)
@Comment("联系电话") @Comment("联系电话")
private String phone; private String phone;
/** /**
* *
*/ */
@Column(name = "province", nullable = false, length = 50) @Column(name = "province", length = 50)
@Comment("") @Comment("")
private String province; private String province;
/** /**
* *
*/ */
@Column(name = "city", nullable = false, length = 50) @Column(name = "city", length = 50)
@Comment("") @Comment("")
private String city; private String city;
/** /**
* / * /
*/ */
@Column(name = "district", nullable = false, length = 50) @Column(name = "district", length = 50)
@Comment("区/县") @Comment("区/县")
private String district; private String district;
/** /**
* 详细地址 * 详细地址
*/ */
@Column(name = "address", nullable = false, length = 200) @Column(name = "address", length = 200)
@Comment("详细地址") @Comment("详细地址")
private String address; private String address;
@ -81,14 +83,14 @@ public class Store extends AbstractBaseEntity {
*/ */
@Column(name = "longitude", precision = 10, scale = 7) @Column(name = "longitude", precision = 10, scale = 7)
@Comment("经度") @Comment("经度")
private Double longitude; private BigDecimal longitude;
/** /**
* 纬度 * 纬度
*/ */
@Column(name = "latitude", precision = 10, scale = 7) @Column(name = "latitude", precision = 10, scale = 7)
@Comment("纬度") @Comment("纬度")
private Double latitude; private BigDecimal latitude;
/** /**
* 营业时间描述 * 营业时间描述
@ -100,7 +102,7 @@ public class Store extends AbstractBaseEntity {
/** /**
* 营业状态0-已打烊 1-营业中 2-临时打烊 * 营业状态0-已打烊 1-营业中 2-临时打烊
*/ */
@Column(name = "business_status",columnDefinition = "VARCHAR(20)", length = 20,nullable = false) @Column(name = "business_status",columnDefinition = "VARCHAR(20)", length = 20)
@Enumerated(EnumType.STRING) @Enumerated(EnumType.STRING)
@Comment("营业状态0已打烊 1营业中 2临时打烊") @Comment("营业状态0已打烊 1营业中 2临时打烊")
private BusinessStatus businessStatus = BusinessStatus.OPEN; private BusinessStatus businessStatus = BusinessStatus.OPEN;
@ -122,7 +124,7 @@ public class Store extends AbstractBaseEntity {
/** /**
* 审核状态 * 审核状态
*/ */
@Column(name = "audit_status",columnDefinition = "VARCHAR(20)", length = 20, nullable = false) @Column(name = "audit_status",columnDefinition = "VARCHAR(20)", length = 20)
@Comment("审核状态0待审核 1已通过 2已拒绝") @Comment("审核状态0待审核 1已通过 2已拒绝")
private StoreAuditStatus auditStatus = StoreAuditStatus.PENDING; private StoreAuditStatus auditStatus = StoreAuditStatus.PENDING;
@ -136,30 +138,41 @@ public class Store extends AbstractBaseEntity {
/** /**
* 启用状态0-禁用 1-启用 * 启用状态0-禁用 1-启用
*/ */
@Column(name = "status",columnDefinition = "VARCHAR(20)", length = 20, nullable = false) @Column(name = "status",columnDefinition = "VARCHAR(20)", length = 20)
@Comment("启用状态0禁用 1启用") @Comment("启用状态0禁用 1启用")
private CommonStatus status = CommonStatus.ENABLED; private CommonStatus status = CommonStatus.ENABLED;
// ========== 关联关系 ========== // ========== 关联关系 ==========
/** /**
* *
*/ */
@ManyToOne(fetch = FetchType.LAZY) @ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "merchant_id", insertable = false, updatable = false) @JoinColumn(name = "merchant_id")
private Merchant merchant; private Merchant merchant;
/** /**
* 员工列表 * 员工列表
*/ */
@OneToMany(mappedBy = "store", fetch = FetchType.LAZY) @OneToMany(mappedBy = "store", fetch = FetchType.LAZY,cascade = CascadeType.ALL,orphanRemoval = true)
private List<Employee> employees; private List<Employee> employees = new ArrayList<>();
public void addEmployee(Employee employee){
employee.setStore(this);
this.employees.add(employee);
}
/** /**
* 营业时间段 * 营业时间段
*/ */
@OneToMany(mappedBy = "store", fetch = FetchType.LAZY) @OneToMany(mappedBy = "store", fetch = FetchType.LAZY,cascade = CascadeType.ALL,orphanRemoval = true)
private List<BusinessPeriod> businessPeriods; private List<BusinessPeriod> businessPeriods = new ArrayList<>();
public void addBusinessPeriods(BusinessPeriod businessPeriod){
businessPeriod.setStore(this);
this.businessPeriods.add(businessPeriod);
}
// ========== 业务方法 ========== // ========== 业务方法 ==========

View file

@ -1,6 +1,6 @@
package com.xjhs.findmemerchant.entity; package com.xjhs.findmemerchant.entity;
import com.xjhs.findmemerchant.adapter.id.SnowflakeGenerated; import com.xjhs.findmemerchant.common.jpa.id.SnowflakeGenerated;
import com.xjhs.findmemerchant.types.TransactionType; import com.xjhs.findmemerchant.types.TransactionType;
import jakarta.persistence.*; import jakarta.persistence.*;
import lombok.Getter; import lombok.Getter;
@ -34,7 +34,6 @@ public class Transaction {
@Id @Id
@GeneratedValue @GeneratedValue
@SnowflakeGenerated @SnowflakeGenerated
@Column(nullable = false)
@Comment("主键ID") @Comment("主键ID")
private Long id; private Long id;
@ -42,28 +41,28 @@ public class Transaction {
/** /**
* 交易类型1-收入 2-支出 3-冻结 4-解冻 5-提现 * 交易类型1-收入 2-支出 3-冻结 4-解冻 5-提现
*/ */
@Column(name = "type",columnDefinition = "VARCHAR(20)",length = 20, nullable = false) @Column(name = "type",columnDefinition = "VARCHAR(20)",length = 20)
@Comment("交易类型1收入 2支出 3冻结 4解冻 5提现") @Comment("交易类型1收入 2支出 3冻结 4解冻 5提现")
private TransactionType type; private TransactionType type;
/** /**
* 交易金额 * 交易金额
*/ */
@Column(name = "amount", nullable = false, precision = 12, scale = 2) @Column(name = "amount", precision = 12, scale = 2)
@Comment("交易金额") @Comment("交易金额")
private BigDecimal amount; private BigDecimal amount;
/** /**
* 交易前余额 * 交易前余额
*/ */
@Column(name = "balance_before", nullable = false, precision = 12, scale = 2) @Column(name = "balance_before", precision = 12, scale = 2)
@Comment("交易前余额") @Comment("交易前余额")
private BigDecimal balanceBefore; private BigDecimal balanceBefore;
/** /**
* 交易后余额 * 交易后余额
*/ */
@Column(name = "balance_after", nullable = false, precision = 12, scale = 2) @Column(name = "balance_after", precision = 12, scale = 2)
@Comment("交易后余额") @Comment("交易后余额")
private BigDecimal balanceAfter; private BigDecimal balanceAfter;
@ -91,7 +90,7 @@ public class Transaction {
/** /**
* 创建时间 * 创建时间
*/ */
@Column(name = "created_at", nullable = false) @Column(name = "created_at")
@Comment("创建时间") @Comment("创建时间")
private LocalDateTime createdAt; private LocalDateTime createdAt;
@ -104,7 +103,7 @@ public class Transaction {
/** /**
* *
*/ */
@ManyToOne(fetch = FetchType.LAZY) @ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "merchant_id", insertable = false, updatable = false) @JoinColumn(name = "merchant_id", insertable = false, updatable = false)

View file

@ -1,6 +1,5 @@
package com.xjhs.findmemerchant.entity; package com.xjhs.findmemerchant.entity;
import com.xjhs.findmemerchant.adapter.id.SnowflakeGenerated;
import com.xjhs.findmemerchant.common.jpa.AbstractBaseEntity; import com.xjhs.findmemerchant.common.jpa.AbstractBaseEntity;
import jakarta.persistence.*; import jakarta.persistence.*;
import lombok.Getter; import lombok.Getter;
@ -10,7 +9,7 @@ import org.hibernate.annotations.Comment;
import java.math.BigDecimal; import java.math.BigDecimal;
/** /**
* 钱包 * 钱包
* 对应表wallets * 对应表wallets
*/ */
@Getter @Getter
@ -24,58 +23,47 @@ import java.math.BigDecimal;
) )
public class Wallet extends AbstractBaseEntity { public class Wallet extends AbstractBaseEntity {
/**
* 主键雪花ID
*/
@Id
@GeneratedValue
@SnowflakeGenerated
@Column(nullable = false)
@Comment("主键ID")
private Long id;
/** /**
* 可用余额 * 可用余额
*/ */
@Column(name = "balance", nullable = false, precision = 12, scale = 2) @Column(name = "balance", precision = 12, scale = 2)
@Comment("可用余额") @Comment("可用余额")
private BigDecimal balance = BigDecimal.ZERO; private BigDecimal balance = BigDecimal.ZERO;
/** /**
* 冻结余额提现中 * 冻结余额提现中
*/ */
@Column(name = "frozen_balance", nullable = false, precision = 12, scale = 2) @Column(name = "frozen_balance", precision = 12, scale = 2)
@Comment("冻结余额(提现中)") @Comment("冻结余额(提现中)")
private BigDecimal frozenBalance = BigDecimal.ZERO; private BigDecimal frozenBalance = BigDecimal.ZERO;
/** /**
* 累计收入 * 累计收入
*/ */
@Column(name = "total_income", nullable = false, precision = 12, scale = 2) @Column(name = "total_income", precision = 12, scale = 2)
@Comment("累计收入") @Comment("累计收入")
private BigDecimal totalIncome = BigDecimal.ZERO; private BigDecimal totalIncome = BigDecimal.ZERO;
/** /**
* 累计提现 * 累计提现
*/ */
@Column(name = "total_withdrawn", nullable = false, precision = 12, scale = 2) @Column(name = "total_withdrawn", precision = 12, scale = 2)
@Comment("累计提现") @Comment("累计提现")
private BigDecimal totalWithdrawn = BigDecimal.ZERO; private BigDecimal totalWithdrawn = BigDecimal.ZERO;
/** /**
* 待结算金额 * 待结算金额
*/ */
@Column(name = "pending_settlement", nullable = false, precision = 12, scale = 2) @Column(name = "pending_settlement", precision = 12, scale = 2)
@Comment("待结算金额") @Comment("待结算金额")
private BigDecimal pendingSettlement = BigDecimal.ZERO; private BigDecimal pendingSettlement = BigDecimal.ZERO;
/** /**
* *
*/ */
@ManyToOne(fetch = FetchType.LAZY) @ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "merchant_id", insertable = false, updatable = false) @JoinColumn(name = "merchant_id")
private Merchant merchant; private Merchant merchant;
// ========== 业务方法 ========== // ========== 业务方法 ==========

View file

@ -32,49 +32,49 @@ public class Withdrawal extends AbstractBaseEntity {
/** /**
* 提现金额 * 提现金额
*/ */
@Column(name = "amount", nullable = false, precision = 12, scale = 2) @Column(name = "amount", precision = 12, scale = 2)
@Comment("提现金额") @Comment("提现金额")
private BigDecimal amount; private BigDecimal amount;
/** /**
* 手续费 * 手续费
*/ */
@Column(name = "fee", nullable = false, precision = 10, scale = 2) @Column(name = "fee", precision = 10, scale = 2)
@Comment("提现手续费") @Comment("提现手续费")
private BigDecimal fee = BigDecimal.ZERO; private BigDecimal fee = BigDecimal.ZERO;
/** /**
* 实际到账金额 * 实际到账金额
*/ */
@Column(name = "actual_amount", nullable = false, precision = 12, scale = 2) @Column(name = "actual_amount", precision = 12, scale = 2)
@Comment("实际到账金额") @Comment("实际到账金额")
private BigDecimal actualAmount; private BigDecimal actualAmount;
/** /**
* 银行名称 * 银行名称
*/ */
@Column(name = "bank_name", nullable = false, length = 50) @Column(name = "bank_name", length = 50)
@Comment("银行名称") @Comment("银行名称")
private String bankName; private String bankName;
/** /**
* 银行账号加密存储 * 银行账号加密存储
*/ */
@Column(name = "bank_account", nullable = false, length = 30) @Column(name = "bank_account", length = 30)
@Comment("银行账号(加密)") @Comment("银行账号(加密)")
private String bankAccount; private String bankAccount;
/** /**
* 户名 * 户名
*/ */
@Column(name = "account_name", nullable = false, length = 50) @Column(name = "account_name", length = 50)
@Comment("开户人姓名") @Comment("开户人姓名")
private String accountName; private String accountName;
/** /**
* 状态0-待审核 1-处理中 2-已完成 3-已拒绝 4-已取消 * 状态0-待审核 1-处理中 2-已完成 3-已拒绝 4-已取消
*/ */
@Column(name = "status", nullable = false) @Column(name = "status")
@Comment("提现状态") @Comment("提现状态")
private Byte status = 0; private Byte status = 0;
@ -114,7 +114,7 @@ public class Withdrawal extends AbstractBaseEntity {
private String remark; private String remark;
/** /**
* *
*/ */
@ManyToOne(fetch = FetchType.LAZY) @ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "merchant_id", insertable = false, updatable = false) @JoinColumn(name = "merchant_id", insertable = false, updatable = false)

View file

@ -1,4 +1,20 @@
package com.xjhs.findmemerchant.mapper; package com.xjhs.findmemerchant.mapper;
public class EmployeeMapper { import com.xjhs.findmemerchant.dto.member.EmployeeDto;
import com.xjhs.findmemerchant.entity.Employee;
import com.xjhs.findmemerchant.vo.member.EmployeeCreateVo;
import com.xjhs.findmemerchant.vo.member.EmployeeUpdateVo;
import org.mapstruct.*;
@Mapper(componentModel = "spring",unmappedTargetPolicy = ReportingPolicy.IGNORE,unmappedSourcePolicy = ReportingPolicy.IGNORE)
public interface EmployeeMapper {
@Mapping(target = "storeId",source = "store.id")
@Mapping(target = "roleId",source = "role.id")
EmployeeDto toDto(Employee employee);
Employee toEntity(EmployeeCreateVo createVo);
@BeanMapping(nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.IGNORE)
void updateEntityFormUpdateVo(EmployeeUpdateVo updateVo, @MappingTarget Employee employee);
} }

View file

@ -3,10 +3,13 @@ package com.xjhs.findmemerchant.mapper;
import com.xjhs.findmemerchant.dto.MerchantDto; import com.xjhs.findmemerchant.dto.MerchantDto;
import com.xjhs.findmemerchant.entity.Merchant; import com.xjhs.findmemerchant.entity.Merchant;
import org.mapstruct.Mapper; import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.ReportingPolicy; import org.mapstruct.ReportingPolicy;
@Mapper(componentModel = "spring",unmappedTargetPolicy = ReportingPolicy.IGNORE,unmappedSourcePolicy = ReportingPolicy.IGNORE) @Mapper(componentModel = "spring",unmappedTargetPolicy = ReportingPolicy.IGNORE,unmappedSourcePolicy = ReportingPolicy.IGNORE)
public interface MerchantMapper { public interface MerchantMapper {
@Mapping(target = "authStatusDesc",source = "authStatus.desc")
MerchantDto toDto(Merchant merchant); MerchantDto toDto(Merchant merchant);
} }

View file

@ -1,17 +1,32 @@
package com.xjhs.findmemerchant.mapper; package com.xjhs.findmemerchant.mapper;
import com.xjhs.findmemerchant.dto.store.BusinessPeriodDto;
import com.xjhs.findmemerchant.dto.store.StoreBusinessStatusDto;
import com.xjhs.findmemerchant.dto.store.StoreDto; import com.xjhs.findmemerchant.dto.store.StoreDto;
import com.xjhs.findmemerchant.entity.BusinessPeriod;
import com.xjhs.findmemerchant.entity.Store; import com.xjhs.findmemerchant.entity.Store;
import com.xjhs.findmemerchant.vo.store.BusinessPeriodVo;
import com.xjhs.findmemerchant.vo.store.StoreBusinessStatusUpdateVo;
import com.xjhs.findmemerchant.vo.store.StoreCreateVo; import com.xjhs.findmemerchant.vo.store.StoreCreateVo;
import com.xjhs.findmemerchant.vo.store.StoreUpdateVo; import com.xjhs.findmemerchant.vo.store.StoreUpdateVo;
import org.mapstruct.*; import org.mapstruct.*;
import java.util.List;
@Mapper(componentModel = "spring",unmappedTargetPolicy = ReportingPolicy.IGNORE,unmappedSourcePolicy = ReportingPolicy.IGNORE) @Mapper(componentModel = "spring",unmappedTargetPolicy = ReportingPolicy.IGNORE,unmappedSourcePolicy = ReportingPolicy.IGNORE)
public interface StoreMapper { public interface StoreMapper {
StoreDto toDto(Store store); StoreDto toDto(Store store);
StoreBusinessStatusDto toBusinessStatusDto(Store store);
Store toEntity(StoreCreateVo createVo); Store toEntity(StoreCreateVo createVo);
Store toEntity(StoreUpdateVo updateVo); Store toEntity(StoreUpdateVo updateVo);
@BeanMapping(nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.IGNORE) @BeanMapping(nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.IGNORE)
void updateFromVo(StoreUpdateVo vo, @MappingTarget Store entity); void updateFromVo(StoreUpdateVo vo, @MappingTarget Store entity);
@BeanMapping(nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.IGNORE)
void updateFromBusinessUpdateVo(StoreBusinessStatusUpdateVo updateVo,@MappingTarget Store store);
BusinessPeriod toEntity(BusinessPeriodVo vo);
@Mapping(source = "store.id",target = "storeId")
BusinessPeriodDto toDto(BusinessPeriod entity);
List<BusinessPeriodDto> toDtoList(List<BusinessPeriod> entityList);
} }

View file

@ -1,13 +1,14 @@
package com.xjhs.findmemerchant.repository; package com.xjhs.findmemerchant.repository;
import com.xjhs.findmemerchant.entity.Activity; import com.xjhs.findmemerchant.entity.Activity;
import com.xjhs.findmemerchant.types.ActivityStatus;
import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.JpaRepository;
import java.util.List; import java.util.List;
public interface ActivityRepository extends JpaRepository<Activity, Long> { public interface ActivityRepository extends JpaRepository<Activity, Long> {
List<Activity> findByMerchantId(Long merchantId); List<Activity> findByMerchant_Id(Long merchantId);
List<Activity> findByStatus(Byte status); List<Activity> findByStatus(ActivityStatus status);
} }

View file

@ -8,18 +8,18 @@ import java.util.List;
import java.util.Optional; import java.util.Optional;
/** /**
* 银行卡仓储 * 银行卡仓储
*/ */
public interface BankCardRepository extends JpaRepository<BankCard, Long>, public interface BankCardRepository extends JpaRepository<BankCard, Long>,
JpaSpecificationExecutor<BankCard> { JpaSpecificationExecutor<BankCard> {
/** /**
* 按商查询所有银行卡 * 按商查询所有银行卡
*/ */
List<BankCard> findByMerchantId(Long merchantId); List<BankCard> findByMerchant_Id(Long merchantId);
/** /**
* 查询商的默认卡 * 查询商的默认卡
*/ */
Optional<BankCard> findByMerchantIdAndIsDefaultTrue(Long merchantId); Optional<BankCard> findByMerchant_IdAndIsDefaultTrue(Long merchantId);
} }

View file

@ -10,7 +10,7 @@ import java.util.Optional;
public interface BusinessLicenseRepository extends JpaRepository<BusinessLicense, Long>, public interface BusinessLicenseRepository extends JpaRepository<BusinessLicense, Long>,
JpaSpecificationExecutor<BusinessLicense> { JpaSpecificationExecutor<BusinessLicense> {
List<BusinessLicense> findByMerchantId(Long merchantId); List<BusinessLicense> findByMerchant_Id(Long merchantId);
Optional<BusinessLicense> findTopByMerchantIdOrderByCreatedAtDesc(Long merchantId); Optional<BusinessLicense> findTopByMerchant_IdOrderByCreatedAtDesc(Long merchantId);
} }

View file

@ -15,10 +15,10 @@ public interface BusinessPeriodRepository extends JpaRepository<BusinessPeriod,
/** /**
* 按门店查询所有营业时间段 * 按门店查询所有营业时间段
*/ */
List<BusinessPeriod> findByStoreId(Long storeId); List<BusinessPeriod> findByStore_Id(Long storeId);
/** /**
* 按门店 + 周几查询启用的时间段 * 按门店 + 周几查询启用的时间段
*/ */
List<BusinessPeriod> findByStoreIdAndDayOfWeekAndIsEnabledTrue(Long storeId, Byte dayOfWeek); List<BusinessPeriod> findByStore_IdAndDayOfWeekAndIsEnabledTrue(Long storeId, Byte dayOfWeek);
} }

View file

@ -16,12 +16,12 @@ public interface CouponCodeRepository extends JpaRepository<CouponCode, Long>,
/** /**
* 按券模板查询券码 * 按券模板查询券码
*/ */
List<CouponCode> findByCouponId(Long couponId); List<CouponCode> findByCoupon_Id(Long couponId);
/** /**
* 按会员查询券码 * 按会员查询券码
*/ */
List<CouponCode> findByMemberId(Long memberId); List<CouponCode> findByMember_Id(Long memberId);
/** /**
* 按券码查询 * 按券码查询

View file

@ -1,6 +1,7 @@
package com.xjhs.findmemerchant.repository; package com.xjhs.findmemerchant.repository;
import com.xjhs.findmemerchant.entity.Coupon; import com.xjhs.findmemerchant.entity.Coupon;
import com.xjhs.findmemerchant.types.CouponStatus;
import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.JpaRepository;
import java.util.List; import java.util.List;
@ -12,17 +13,17 @@ import java.util.Optional;
public interface CouponRepository extends JpaRepository<Coupon, Long> { public interface CouponRepository extends JpaRepository<Coupon, Long> {
/** /**
* 按商查询优惠券 * 按商查询优惠券
*/ */
List<Coupon> findByMerchantId(Long merchantId); List<Coupon> findByMerchant_Id(Long merchantId);
/** /**
* 按状态查询优惠券 * 按状态查询优惠券
*/ */
List<Coupon> findByStatus(Byte status); List<Coupon> findByStatus(CouponStatus status);
/** /**
* 按ID + ID 查询防越权 * 按ID + ID 查询防越权
*/ */
Optional<Coupon> findByIdAndMerchantId(Long id, Long merchantId); Optional<Coupon> findByIdAndMerchant_Id(Long id, Long merchantId);
} }

View file

@ -12,9 +12,9 @@ import java.util.Optional;
*/ */
public interface CouponStoreRepository extends JpaSpecificationExecutor<CouponStore>,JpaRepository<CouponStore, Long> { public interface CouponStoreRepository extends JpaSpecificationExecutor<CouponStore>,JpaRepository<CouponStore, Long> {
List<CouponStore> findByCouponId(Long couponId); List<CouponStore> findByCoupon_Id(Long couponId);
List<CouponStore> findByStoreId(Long storeId); List<CouponStore> findByStore_Id(Long storeId);
Optional<CouponStore> findByCouponIdAndStoreId(Long couponId, Long storeId); Optional<CouponStore> findByCoupon_IdAndStore_Id(Long couponId, Long storeId);
} }

View file

@ -13,18 +13,5 @@ import java.util.Optional;
public interface EmployeeRepository extends JpaRepository<Employee, Long>, public interface EmployeeRepository extends JpaRepository<Employee, Long>,
JpaSpecificationExecutor<Employee> { JpaSpecificationExecutor<Employee> {
/**
* 按商户查询员工
*/
List<Employee> findByMerchantId(Long merchantId);
/**
* 按门店查询员工
*/
List<Employee> findByStoreId(Long storeId); List<Employee> findByStoreId(Long storeId);
/**
* 按手机号与商户查询防止跨商户重复
*/
Optional<Employee> findByMerchantIdAndPhone(Long merchantId, String phone);
} }

View file

@ -9,7 +9,7 @@ import java.util.List;
public interface HealthCertificateRepository extends JpaRepository<HealthCertificate, Long>, public interface HealthCertificateRepository extends JpaRepository<HealthCertificate, Long>,
JpaSpecificationExecutor<HealthCertificate> { JpaSpecificationExecutor<HealthCertificate> {
List<HealthCertificate> findByStoreId(Long storeId); List<HealthCertificate> findByStore_Id(Long storeId);
List<HealthCertificate> findByEmployeeId(Long employeeId); List<HealthCertificate> findByEmployee_Id(Long employeeId);
} }

View file

@ -14,12 +14,12 @@ public interface MemberRepository extends JpaRepository<Member, Long>,
JpaSpecificationExecutor<Member> { JpaSpecificationExecutor<Member> {
/** /**
* 按商查询会员 * 按商查询会员
*/ */
List<Member> findByMerchantId(Long merchantId); List<Member> findByMerchant_Id(Long merchantId);
/** /**
* 按商 + 手机号查询唯一 * 按商 + 手机号查询唯一
*/ */
Optional<Member> findByPhone(String phone); Optional<Member> findByPhone(String phone);

View file

@ -7,7 +7,7 @@ import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import java.util.Optional; import java.util.Optional;
/** /**
* 仓储 * 仓储
*/ */
public interface MerchantRepository extends JpaRepository<Merchant, Long>, public interface MerchantRepository extends JpaRepository<Merchant, Long>,
JpaSpecificationExecutor<Merchant> { JpaSpecificationExecutor<Merchant> {

View file

@ -13,17 +13,14 @@ public interface MessageRepository extends JpaRepository<Message, Long>,
JpaSpecificationExecutor<Message> { JpaSpecificationExecutor<Message> {
/** /**
* 按商查询消息 * 按商查询消息
*/ */
List<Message> findByMerchantId(Long merchantId); List<Message> findByMerchant_Id(Long merchantId);
/** List<Message> findByMerchant_IdAndIsRead(Long merchantId, Boolean isRead);
* 按商户 + 是否已读查询
*/
List<Message> findByMerchantIdAndIsRead(Long merchantId, Byte isRead);
/** /**
* 统计未读消息数量 * 统计未读消息数量
*/ */
long countByMerchantIdAndIsRead(Long merchantId, Byte isRead); long countByMerchant_IdAndIsRead(Long merchantId, Boolean isRead);
} }

View file

@ -15,10 +15,7 @@ public interface OrderItemRepository extends JpaRepository<OrderItem, Long>,
/** /**
* 按订单查询订单明细 * 按订单查询订单明细
*/ */
List<OrderItem> findByOrderId(Long orderId); List<OrderItem> findByOrder_Id(Long orderId);
/**
* 按商品查询订单明细
*/
List<OrderItem> findByProductId(Long productId); List<OrderItem> findByProductId(Long productId);
} }

View file

@ -21,10 +21,7 @@ public interface OrderRepository extends JpaRepository<Order, Long>,
/** /**
* 按门店查询订单 * 按门店查询订单
*/ */
List<Order> findByStoreId(Long storeId); List<Order> findByStore_Id(Long storeId);
/** List<Order> findByMember_Id(Long memberId);
* 按会员查询订单
*/
List<Order> findByMemberId(Long memberId);
} }

View file

@ -13,12 +13,12 @@ public interface ProductCategoryRepository extends JpaRepository<ProductCategory
JpaSpecificationExecutor<ProductCategory> { JpaSpecificationExecutor<ProductCategory> {
/** /**
* 按商查询所有分类 * 按商查询所有分类
*/ */
List<ProductCategory> findByMerchantId(Long merchantId); List<ProductCategory> findByMerchant_Id(Long merchantId);
/** /**
* 查询某商下指定父分类的子分类 * 查询某商下指定父分类的子分类
*/ */
List<ProductCategory> findByMerchantIdAndParentId(Long merchantId, Long parentId); List<ProductCategory> findByMerchantIdAndParentId(Long merchantId, Long parentId);
} }

View file

@ -1,6 +1,7 @@
package com.xjhs.findmemerchant.repository; package com.xjhs.findmemerchant.repository;
import com.xjhs.findmemerchant.entity.Product; import com.xjhs.findmemerchant.entity.Product;
import com.xjhs.findmemerchant.types.ProductStatus;
import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor; import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
@ -12,10 +13,7 @@ import java.util.List;
public interface ProductRepository extends JpaRepository<Product, Long>, public interface ProductRepository extends JpaRepository<Product, Long>,
JpaSpecificationExecutor<Product> { JpaSpecificationExecutor<Product> {
/** List<Product> findByMerchant_Id(Long merchantId);
* 按商户查询商品
*/
List<Product> findByMerchantId(Long merchantId);
/** /**
* 按门店查询商品 * 按门店查询商品
@ -30,5 +28,5 @@ public interface ProductRepository extends JpaRepository<Product, Long>,
/** /**
* 按状态查询商品 * 按状态查询商品
*/ */
List<Product> findByStatus(Byte status); List<Product> findByStatus(ProductStatus status);
} }

View file

@ -12,7 +12,7 @@ import java.util.List;
public interface ReviewRepository extends JpaRepository<Review, Long>, public interface ReviewRepository extends JpaRepository<Review, Long>,
JpaSpecificationExecutor<Review> { JpaSpecificationExecutor<Review> {
List<Review> findByMerchantId(Long merchantId); List<Review> findByMerchant_Id(Long merchantId);
List<Review> findByStoreId(Long storeId); List<Review> findByStoreId(Long storeId);

View file

@ -19,7 +19,7 @@ public interface SettlementRepository extends JpaRepository<Settlement, Long>,
Optional<Settlement> findBySettlementNo(String settlementNo); Optional<Settlement> findBySettlementNo(String settlementNo);
/** /**
* 按商查询结算记录 * 按商查询结算记录
*/ */
List<Settlement> findByMerchantId(Long merchantId); List<Settlement> findByMerchantId(Long merchantId);
} }

View file

@ -14,7 +14,7 @@ public interface StoreRepository extends JpaRepository<Store, Long>,
JpaSpecificationExecutor<Store> { JpaSpecificationExecutor<Store> {
/** /**
* 按商查询门店 * 按商查询门店
*/ */
List<Store> findByMerchantId(Long merchantId); List<Store> findByMerchantId(Long merchantId);

View file

@ -18,7 +18,7 @@ public interface TransactionRepository extends JpaRepository<Transaction, Long>,
List<Transaction> findByWalletId(Long walletId); List<Transaction> findByWalletId(Long walletId);
/** /**
* 按商查询流水 * 按商查询流水
*/ */
List<Transaction> findByMerchantId(Long merchantId); List<Transaction> findByMerchantId(Long merchantId);
} }

View file

@ -7,13 +7,13 @@ import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import java.util.Optional; import java.util.Optional;
/** /**
* 钱包仓储 * 钱包仓储
*/ */
public interface WalletRepository extends JpaRepository<Wallet, Long>, public interface WalletRepository extends JpaRepository<Wallet, Long>,
JpaSpecificationExecutor<Wallet> { JpaSpecificationExecutor<Wallet> {
/** /**
* 根据商ID查询钱包唯一 * 根据商ID查询钱包唯一
*/ */
Optional<Wallet> findByMerchantId(Long merchantId); Optional<Wallet> findByMerchantId(Long merchantId);
} }

View file

@ -13,7 +13,7 @@ public interface WithdrawalRepository extends JpaRepository<Withdrawal, Long>,
JpaSpecificationExecutor<Withdrawal> { JpaSpecificationExecutor<Withdrawal> {
/** /**
* 按商查提现记录 * 按商查提现记录
*/ */
List<Withdrawal> findByMerchantId(Long merchantId); List<Withdrawal> findByMerchantId(Long merchantId);

View file

@ -29,7 +29,7 @@ public class JwtAuthenticationFilter extends OncePerRequestFilter {
private SmsAuthenticationToken getAuthenticationToken(String phone) throws Exception { private SmsAuthenticationToken getAuthenticationToken(String phone) throws Exception {
// 手机号查商 // 手机号查商
var merchant = merchantRepository.findByPhone(phone).orElse(null); var merchant = merchantRepository.findByPhone(phone).orElse(null);
if(merchant != null){ if(merchant != null){
var authorities = List.of(new SimpleGrantedAuthority("ROLE_USER")); var authorities = List.of(new SimpleGrantedAuthority("ROLE_USER"));

View file

@ -14,7 +14,7 @@ import java.nio.charset.StandardCharsets;
public class JwtTokenService { public class JwtTokenService {
// 建议改成配置application.yml // 建议改成配置application.yml
private final String secret = "secret-key-1234567890"; private final String secret = "secret-key-123456789012345678901234567890";
private final long expireMillis = 30 * 24 * 60 * 60 * 1000L; // 30 private final long expireMillis = 30 * 24 * 60 * 60 * 1000L; // 30
/** /**
@ -33,7 +33,6 @@ public class JwtTokenService {
)); ));
jws.setAlgorithmHeaderValue(AlgorithmIdentifiers.HMAC_SHA256); jws.setAlgorithmHeaderValue(AlgorithmIdentifiers.HMAC_SHA256);
return jws.getCompactSerialization(); return jws.getCompactSerialization();
} }

View file

@ -29,7 +29,7 @@ public class SmsAuthenticationProvider implements AuthenticationProvider {
} catch (Exception e) { } catch (Exception e) {
throw new UsernameNotFoundException(e.getMessage()); throw new UsernameNotFoundException(e.getMessage());
} }
// 手机号查商 // 手机号查商
var merchant = merchantRepository.findByPhone(phone).orElse(null); var merchant = merchantRepository.findByPhone(phone).orElse(null);
if(merchant != null){ if(merchant != null){
var authorities = List.of(new SimpleGrantedAuthority("ROLE_USER")); var authorities = List.of(new SimpleGrantedAuthority("ROLE_USER"));

View file

@ -20,9 +20,9 @@ public class MerchantService {
public final MerchantMapper merchantMapper; public final MerchantMapper merchantMapper;
/** /**
* 根据商户id获取商户信息 * 根据商家id获取商家信息
* @param id id * @param id id
* @return 信息 * @return 信息
*/ */
public Optional<MerchantDto> getById(Long id) { public Optional<MerchantDto> getById(Long id) {
return this.merchantRepository.findById(id) return this.merchantRepository.findById(id)
@ -30,25 +30,25 @@ public class MerchantService {
} }
/** /**
* 更新商信息 * 更新商信息
* @param id id * @param id id
* @param merchantUpdateVo 更新信息 * @param merchantUpdateVo 更新信息
* @return 信息 * @return 信息
* @throws Exception 错误信息 * @throws Exception 错误信息
*/ */
@Transactional(rollbackOn = Exception.class) @Transactional(rollbackOn = Exception.class)
public MerchantDto updateMerchant(Long id, MerchantUpdateVo merchantUpdateVo) throws Exception { public MerchantDto updateMerchant(Long id, MerchantUpdateVo merchantUpdateVo) throws Exception {
var entity = this.merchantRepository.findById(id) var entity = this.merchantRepository.findById(id)
.orElseThrow(() -> new Exception("信息不存在")); .orElseThrow(() -> new Exception("信息不存在"));
entity.setRealName(merchantUpdateVo.getRealName()); entity.setRealName(merchantUpdateVo.getRealName());
this.merchantRepository.save(entity); this.merchantRepository.save(entity);
return this.merchantMapper.toDto(entity); return this.merchantMapper.toDto(entity);
} }
/** /**
* 身份证信息验证 * 身份证信息验证
* *
* @param id id * @param id id
* @param idCardNo 身份证号 * @param idCardNo 身份证号
* @param realName 真实姓名 * @param realName 真实姓名
* @throws Exception 验证异常信息 * @throws Exception 验证异常信息
@ -56,9 +56,9 @@ public class MerchantService {
@Transactional(rollbackOn = Exception.class) @Transactional(rollbackOn = Exception.class)
public MerchantDto verifyMerchant(Long id, String idCardNo, String realName) throws Exception { public MerchantDto verifyMerchant(Long id, String idCardNo, String realName) throws Exception {
var entity = this.merchantRepository.findById(id) var entity = this.merchantRepository.findById(id)
.orElseThrow(() -> new Exception("信息不存在")); .orElseThrow(() -> new Exception("信息不存在"));
if (entity.getAuthStatus() == AuthStatus.VERIFIED) { if (entity.getAuthStatus() == AuthStatus.VERIFIED) {
throw new Exception("信息已认证"); throw new Exception("信息已认证");
} }
this.idCardVerify(idCardNo, realName); this.idCardVerify(idCardNo, realName);
entity.setAuthStatus(AuthStatus.VERIFIED); entity.setAuthStatus(AuthStatus.VERIFIED);

View file

@ -23,7 +23,7 @@ public class StoreService {
* 分页查询 * 分页查询
* *
* @param pageable 分页参数 * @param pageable 分页参数
* @param merchantId id * @param merchantId id
* @return 分页数据 * @return 分页数据
*/ */
public Page<StoreDto> findPage(Pageable pageable, Long merchantId) { public Page<StoreDto> findPage(Pageable pageable, Long merchantId) {

View file

@ -10,10 +10,21 @@ import lombok.Getter;
@Getter @Getter
@AllArgsConstructor @AllArgsConstructor
public enum ActivityStatus { public enum ActivityStatus {
/**
* 未开始
*/
NOT_STARTED("未开始"), NOT_STARTED("未开始"),
/**
* 进行中
*/
ONGOING("进行中"), ONGOING("进行中"),
/**
* 已结束
*/
ENDED("已结束"), ENDED("已结束"),
/**
* 已下架
*/
OFFLINE("已下架"); OFFLINE("已下架");
private final String desc; private final String desc;

View file

@ -7,8 +7,17 @@ import lombok.Getter;
@AllArgsConstructor @AllArgsConstructor
public enum ActivityType { public enum ActivityType {
/**
* 团购
*/
GROUP_BUY("团购"), GROUP_BUY("团购"),
/**
* 折扣
*/
DISCOUNT("折扣"), DISCOUNT("折扣"),
/**
* 限时优惠
*/
FLASH_SALE("限时优惠"); FLASH_SALE("限时优惠");
private final String desc; private final String desc;

View file

@ -4,14 +4,20 @@ import lombok.AllArgsConstructor;
import lombok.Getter; import lombok.Getter;
/** /**
* 实名认证状态 * 实名认证状态
* 0-未认证 1-已认证 * 0-未认证 1-已认证
*/ */
@Getter @Getter
@AllArgsConstructor @AllArgsConstructor
public enum AuthStatus { public enum AuthStatus {
/**
* 未认证
*/
NOT_VERIFIED("未认证"), NOT_VERIFIED("未认证"),
/**
* 已认证
*/
VERIFIED("已认证"); VERIFIED("已认证");
private final String desc; private final String desc;

View file

@ -11,8 +11,17 @@ import lombok.Getter;
@AllArgsConstructor @AllArgsConstructor
public enum BusinessLicenseStatus { public enum BusinessLicenseStatus {
/**
* 待审核
*/
PENDING("待审核"), PENDING("待审核"),
/**
* 已通过
*/
APPROVED("已通过"), APPROVED("已通过"),
/**
* 已拒绝
*/
REJECTED("已拒绝"); REJECTED("已拒绝");
private final String desc; private final String desc;

View file

@ -11,8 +11,17 @@ import lombok.Getter;
@AllArgsConstructor @AllArgsConstructor
public enum BusinessStatus { public enum BusinessStatus {
/**
* 已打烊
*/
CLOSED("已打烊"), // 0 CLOSED("已打烊"), // 0
/**
* 营业中
*/
OPEN("营业中"), // 1 OPEN("营业中"), // 1
/**
* 临时打烊
*/
TEMP_CLOSED("临时打烊"); // 2 TEMP_CLOSED("临时打烊"); // 2
private final String desc; private final String desc;

View file

@ -11,7 +11,13 @@ import lombok.Getter;
@AllArgsConstructor @AllArgsConstructor
public enum CommonStatus { public enum CommonStatus {
/**
* 禁用
*/
DISABLED("禁用"), DISABLED("禁用"),
/**
* 启用
*/
ENABLED("启用"); ENABLED("启用");
private final String desc; private final String desc;

View file

@ -11,13 +11,25 @@ import lombok.Getter;
@AllArgsConstructor @AllArgsConstructor
public enum CouponCodeStatus { public enum CouponCodeStatus {
UNCLAIMED("未领取", (byte) 0), /**
CLAIMED("已领取", (byte) 1), * 未领取
VERIFIED("已核销", (byte) 2), */
EXPIRED("已过期", (byte) 3); UNCLAIMED("未领取"),
/**
* 已领取
*/
CLAIMED("已领取"),
/**
* 已核销
*/
VERIFIED("已核销"),
/**
* 已过期
*/
EXPIRED("已过期");
private final String desc; private final String desc;
private final byte code;
public static CouponCodeStatus fromCode(Byte code) { public static CouponCodeStatus fromCode(Byte code) {
if (code == null) return null; if (code == null) return null;
@ -30,14 +42,5 @@ public enum CouponCodeStatus {
}; };
} }
public byte code() {
return code;
}
/**
* 为了 isClaimed 方便比较给一个 int 形式
*/
public int getCodeValue() {
return code;
}
} }

View file

@ -11,8 +11,17 @@ import lombok.Getter;
@AllArgsConstructor @AllArgsConstructor
public enum CouponStatus { public enum CouponStatus {
/**
* 下架
*/
OFFLINE("下架"), OFFLINE("下架"),
/**
* 进行中
*/
ONLINE("进行中"), ONLINE("进行中"),
/**
* 已结束
*/
ENDED("已结束"); ENDED("已结束");
private final String desc; private final String desc;

View file

@ -11,9 +11,21 @@ import lombok.Getter;
@AllArgsConstructor @AllArgsConstructor
public enum CouponType { public enum CouponType {
/**
* 折扣券
*/
DISCOUNT("折扣券"), DISCOUNT("折扣券"),
/**
* 满减券
*/
REDUCE("满减券"), REDUCE("满减券"),
/**
* 现金券
*/
CASH("现金券"), CASH("现金券"),
/**
* 赠品券
*/
GIFT("赠品券"); GIFT("赠品券");
private final String desc; private final String desc;

View file

@ -11,8 +11,17 @@ import lombok.Getter;
@AllArgsConstructor @AllArgsConstructor
public enum HealthCertificateStatus { public enum HealthCertificateStatus {
/**
* 待审核
*/
PENDING("待审核"), PENDING("待审核"),
/**
* 有效
*/
VALID("有效"), VALID("有效"),
/**
* 已过期
*/
EXPIRED("已过期"); EXPIRED("已过期");
private final String desc; private final String desc;

View file

@ -11,8 +11,17 @@ import lombok.Getter;
@AllArgsConstructor @AllArgsConstructor
public enum MessageType { public enum MessageType {
/**
* 系统通知
*/
SYSTEM("系统通知"), SYSTEM("系统通知"),
/**
* 活动提醒
*/
ACTIVITY("活动提醒"), ACTIVITY("活动提醒"),
/**
* 私信
*/
PRIVATE("私信"); PRIVATE("私信");
private final String desc; private final String desc;

View file

@ -11,10 +11,25 @@ import lombok.Getter;
@AllArgsConstructor @AllArgsConstructor
public enum OrderStatus { public enum OrderStatus {
/**
* 待支付
*/
PENDING("待支付"), // 1 PENDING("待支付"), // 1
/**
* 已支付
*/
PAID("已支付"), // 2 PAID("已支付"), // 2
/**
* 已完成
*/
COMPLETED("已完成"), // 3 COMPLETED("已完成"), // 3
/**
* 已退款
*/
REFUNDED("已退款"), // 4 REFUNDED("已退款"), // 4
/**
* 已取消
*/
CANCELLED("已取消"); // 5 CANCELLED("已取消"); // 5
private final String desc; private final String desc;

View file

@ -11,7 +11,13 @@ import lombok.Getter;
@AllArgsConstructor @AllArgsConstructor
public enum ProductStatus { public enum ProductStatus {
/**
* 已下架
*/
OFF_SALE("已下架"), OFF_SALE("已下架"),
/**
* 已上架
*/
ON_SALE("已上架"); ON_SALE("已上架");
private final String desc; private final String desc;

View file

@ -11,7 +11,13 @@ import lombok.Getter;
@AllArgsConstructor @AllArgsConstructor
public enum ReviewStatus { public enum ReviewStatus {
/**
* 隐藏
*/
HIDDEN("隐藏"), HIDDEN("隐藏"),
/**
* 正常
*/
NORMAL("正常"); NORMAL("正常");
private final String desc; private final String desc;

View file

@ -11,7 +11,13 @@ import lombok.Getter;
@AllArgsConstructor @AllArgsConstructor
public enum SettlementStatus { public enum SettlementStatus {
/**
* 待结算
*/
PENDING("待结算"), PENDING("待结算"),
/**
* 已结算
*/
SETTLED("已结算"); SETTLED("已结算");
private final String desc; private final String desc;

View file

@ -11,7 +11,13 @@ import lombok.Getter;
@AllArgsConstructor @AllArgsConstructor
public enum SettlementType { public enum SettlementType {
/**
* 日结
*/
DAILY("日结"), DAILY("日结"),
/**
* 周结
*/
WEEKLY("周结"); WEEKLY("周结");
private final String desc; private final String desc;

View file

@ -11,8 +11,17 @@ import lombok.Getter;
@AllArgsConstructor @AllArgsConstructor
public enum StoreAuditStatus { public enum StoreAuditStatus {
/**
* 待审核
*/
PENDING("待审核"), PENDING("待审核"),
/**
* 已通过
*/
APPROVED("已通过"), APPROVED("已通过"),
/**
* 已拒绝
*/
REJECTED("已拒绝"); REJECTED("已拒绝");
private final String desc; private final String desc;

View file

@ -11,10 +11,25 @@ import lombok.Getter;
@AllArgsConstructor @AllArgsConstructor
public enum TransactionType { public enum TransactionType {
/**
* 收入
*/
INCOME("收入"), // 1 INCOME("收入"), // 1
/**
* 支出
*/
EXPENSE("支出"), // 2 EXPENSE("支出"), // 2
/**
* 冻结
*/
FREEZE("冻结"), // 3 FREEZE("冻结"), // 3
/**
* 解冻
*/
UNFREEZE("解冻"), // 4 UNFREEZE("解冻"), // 4
/**
* 提现
*/
WITHDRAW("提现"); // 5 WITHDRAW("提现"); // 5
private final String desc; private final String desc;

View file

@ -11,10 +11,25 @@ import lombok.Getter;
@AllArgsConstructor @AllArgsConstructor
public enum WithdrawalStatus { public enum WithdrawalStatus {
/**
* 待审核
*/
PENDING("待审核"), PENDING("待审核"),
/**
* 处理中
*/
PROCESSING("处理中"), PROCESSING("处理中"),
/**
* 已完成
*/
COMPLETED("已完成"), COMPLETED("已完成"),
/**
* 已拒绝
*/
REJECTED("已拒绝"), REJECTED("已拒绝"),
/**
* 已取消
*/
CANCELLED("已取消"); CANCELLED("已取消");
private final String desc; private final String desc;

View file

@ -1,4 +1,4 @@
package com.xjhs.findmemerchant.security.sms; package com.xjhs.findmemerchant.vo.auth;
import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.NotBlank;

View file

@ -1,4 +1,4 @@
package com.xjhs.findmemerchant.security.sms; package com.xjhs.findmemerchant.vo.auth;
import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.Size; import jakarta.validation.constraints.Size;

View file

@ -1,4 +1,37 @@
package com.xjhs.findmemerchant.vo.member; package com.xjhs.findmemerchant.vo.member;
import com.xjhs.findmemerchant.common.jackson.JsonLong;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Pattern;
import jakarta.validation.constraints.Size;
import lombok.Data;
@Data
public class EmployeeCreateVo { public class EmployeeCreateVo {
/**
* 员工姓名
*/
@NotBlank(message = "name 不能为空")
@Size(min = 2, max = 50, message = "name 长度必须在 2~50 之间")
private String name;
/**
* 员工手机号
*/
@NotBlank(message = "phone 不能为空")
@Pattern(regexp = "^\\d{11}$", message = "phone 必须是 11 位数字")
private String phone;
/**
* 角色id(前端传递请使用 string 类型)
*/
@NotNull(message = "roleId 不能为空")
@JsonLong
private Long roleId;
/**
* 角色id(前端传递请使用 string 类型)
*/
@NotNull(message = "storeId 不能为空")
@JsonLong
@Deprecated(since = "多余的")
private Long storeId;
} }

Some files were not shown because too many files have changed in this diff Show more