首次提交

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

76
pom.xml
View file

@ -5,44 +5,43 @@
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>4.0.1</version>
<version>3.5.9</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.xjhs.findme.merchant</groupId>
<artifactId>findme-merchant</artifactId>
<groupId>com.xjhs.findmemerchant</groupId>
<artifactId>findme-backend-merchant-java</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>findme-backend-merchant-java</name>
<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-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</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>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
@ -54,19 +53,28 @@
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator-test</artifactId>
<scope>test</scope>
<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-jpa-test</artifactId>
<scope>test</scope>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webmvc-test</artifactId>
<scope>test</scope>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.18.0</version>
</dependency>
</dependencies>
@ -77,10 +85,20 @@
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<annotationProcessorPaths>
<path>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
<version>1.6.3</version>
</path>
<path>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</path>
<path>
<groupId>org.projectlombok</groupId>
<artifactId>lombok-mapstruct-binding</artifactId>
<version>0.2.0</version>
</path>
</annotationProcessorPaths>
</configuration>
</plugin>

View file

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

View file

@ -11,10 +11,18 @@ import lombok.Getter;
@AllArgsConstructor
@Getter
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
@JacksonAnnotationsInside
@JsonDeserialize(using = SafeLongDeserializer.class)
public @interface JsonDeserializeToLong {
public @interface JsonLong {
}

View file

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

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.id.IdentifierGenerator;

View file

@ -1,4 +1,4 @@
package com.xjhs.findmemerchant.adapter.id;
package com.xjhs.findmemerchant.common.jpa.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;

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.databind.ObjectMapper;

View file

@ -1,4 +1,72 @@
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;
import lombok.Data;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
/**
* 分页请求参数
*/
@Data
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;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer;

View file

@ -1,4 +1,30 @@
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 {
@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.auth.RegisterDto;
import com.xjhs.findmemerchant.entity.Merchant;
import com.xjhs.findmemerchant.mapper.MerchantMapper;
import com.xjhs.findmemerchant.redis.TokenBlacklistRedisService;
import com.xjhs.findmemerchant.repository.MerchantRepository;
import com.xjhs.findmemerchant.security.JwtTokenService;
import com.xjhs.findmemerchant.security.RefreshTokenService;
import com.xjhs.findmemerchant.security.sms.SmsAuthenticationToken;
import com.xjhs.findmemerchant.security.sms.SmsCodeService;
import com.xjhs.findmemerchant.security.sms.SmsLoginVo;
import com.xjhs.findmemerchant.security.sms.SmsSendVo;
import com.xjhs.findmemerchant.vo.auth.SmsLoginVo;
import com.xjhs.findmemerchant.vo.auth.SmsSendVo;
import com.xjhs.findmemerchant.service.MerchantService;
import com.xjhs.findmemerchant.vo.merchant.MerchantUpdateVo;
import com.xjhs.findmemerchant.vo.auth.RegisterVo;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.http.HttpHeaders;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.web.bind.annotation.*;
import java.security.Principal;
import java.util.Map;
/**
* 登录授权管理接口
*/
@Slf4j
@RestController
@RequiredArgsConstructor
@RequestMapping("/auth")
@ -39,13 +39,14 @@ public class AuthController {
private final AuthenticationManager authenticationManager;
private final RefreshTokenService refreshTokenService;
private final MerchantRepository merchantRepository;
private final MerchantMapper merchantMapper;
private final StringRedisTemplate stringRedisTemplate;
private final TokenBlacklistRedisService tokenBlacklistRedisService;
private final MerchantService merchantService;
/**
* 发送短信验证码
*
* @param sendVo 请求参数
* @return 发送结果
*/
@PostMapping("/sms/send")
public ApiResult<Void> sendCode(@Valid @RequestBody SmsSendVo sendVo) {
@ -55,6 +56,7 @@ public class AuthController {
/**
* 短信验证码登录
*
* @param vo 登录信息
* @return 令牌信息
*/
@ -67,6 +69,7 @@ public class AuthController {
var refreshToken = refreshTokenService.create(vo.getPhone());
return ApiResult.returnToken(accessToken, refreshToken);
} catch (Exception e) {
log.error("登录失败", e);
return ApiResult.fail("登录失败:" + e.getMessage());
}
}
@ -93,6 +96,7 @@ public class AuthController {
/**
* 注销登录
*
* @param authHeader @ignore 认证头信息
* @return 注销结果
*/
@ -136,34 +140,37 @@ public class AuthController {
)
);
} catch (Exception e) {
log.error("注册失败", e);
return ApiResult.fail("注册失败:" + e.getMessage());
}
}
/**
* 获取当前登录的商户基本信息
* @param principal @ignore 登录信息对象
* @return 商户信息
* 获取当前登录的商家基本信息
*
* @param merchant @ignore 当前商家
* @return 商家信息
*/
@GetMapping("/profile")
public ApiResult<MerchantDto> getProfile(Principal principal) {
if (principal instanceof Merchant merchant) {
public ApiResult<MerchantDto> getProfile(@AuthenticationPrincipal Merchant merchant) {
if (merchant == null) {
return ApiResult.fail("商家信息不存在");
}
return this.merchantService.getById(merchant.getId())
.map(ApiResult::data)
.orElse(ApiResult.fail("商户信息不存在"));
}
return ApiResult.fail("商户信息不存在");
.orElse(ApiResult.fail("商家信息不存在"));
}
/**
* 更新当前登录的商户基本信息
* @param principal @ignore 登录信息对象
* 更新当前登录的商家基本信息
*
* @param merchant @ignore 当前商家
* @param merchantUpdateVo 更新信息对象
* @return 信息
* @return 信息
*/
@PutMapping("/profile")
public ApiResult<MerchantDto> updateProfile(Principal principal,@Valid @RequestBody MerchantUpdateVo merchantUpdateVo) {
if (principal instanceof Merchant merchant) {
public ApiResult<MerchantDto> updateProfile(@AuthenticationPrincipal Merchant merchant,
@Valid @RequestBody MerchantUpdateVo merchantUpdateVo) {
try {
var result = this.merchantService.updateMerchant(merchant.getId(), merchantUpdateVo);
return ApiResult.data(result);
@ -171,7 +178,5 @@ public class AuthController {
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 lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.web.bind.annotation.*;
import java.security.Principal;
/**
* 商家管理接口
*/
@Slf4j
@RestController
@RequestMapping("/merchant")
@ -20,19 +24,29 @@ import java.security.Principal;
public class MerchantController {
private final MerchantService merchantService;
/**
* 查询当前登录商家详情
*
* @param merchant @ignore 当前商家
* @return 商家详情信息
*/
@GetMapping
public ApiResult<MerchantDto> getMerchant(Principal principal) {
if (principal instanceof Merchant merchant) {
public ApiResult<MerchantDto> getMerchant(@AuthenticationPrincipal Merchant merchant) {
return this.merchantService.getById(merchant.getId())
.map(ApiResult::data)
.orElse(ApiResult.fail("商户信息不存在"));
}
return ApiResult.fail("商户信息不存在");
.orElse(ApiResult.fail("商家信息不存在"));
}
/**
* 更新当前登录商家信息
*
* @param merchant @ignore 当前商家
* @param merchantUpdateVo 更新参数
* @return 商家信息
*/
@PutMapping
public ApiResult<MerchantDto> updateMerchant(Principal principal,@Valid @RequestBody MerchantUpdateVo merchantUpdateVo) {
if (principal instanceof Merchant merchant) {
public ApiResult<MerchantDto> updateMerchant(@AuthenticationPrincipal Merchant merchant,
@Valid @RequestBody MerchantUpdateVo merchantUpdateVo) {
try {
var dto = this.merchantService.updateMerchant(merchant.getId(), merchantUpdateVo);
return ApiResult.data(dto);
@ -40,12 +54,17 @@ public class MerchantController {
return ApiResult.fail(e.getMessage());
}
}
return ApiResult.fail("商户信息不存在");
}
/**
* 当前商家验证
*
* @param merchant @ignore 当前商家
* @param merchantVerifyVo 验证参数
* @return 商家信息
*/
@PostMapping("/verify")
public ApiResult<MerchantDto> verifyMerchant(Principal principal,@Valid @RequestBody MerchantVerifyVo merchantVerifyVo) {
if (principal instanceof Merchant merchant) {
public ApiResult<MerchantDto> verifyMerchant(@AuthenticationPrincipal Merchant merchant,
@Valid @RequestBody MerchantVerifyVo merchantVerifyVo) {
try {
var dto = this.merchantService.verifyMerchant(merchant.getId(), merchantVerifyVo.getIdCardNo(), merchantVerifyVo.getRealName());
return ApiResult.data(dto);
@ -53,6 +72,4 @@ public class MerchantController {
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.PageData;
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.entity.BusinessPeriod;
import com.xjhs.findmemerchant.entity.Merchant;
import com.xjhs.findmemerchant.entity.Store;
import com.xjhs.findmemerchant.mapper.StoreMapper;
import com.xjhs.findmemerchant.repository.BusinessPeriodRepository;
import com.xjhs.findmemerchant.repository.MerchantRepository;
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.StoreUpdateVo;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;
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.security.Principal;
import java.util.List;
import java.util.Objects;
/**
* 门店管理接口
*/
@Slf4j
@RestController
@RequestMapping("/stores")
@ -30,38 +42,36 @@ public class StoreController {
private final MerchantRepository merchantRepository;
private final StoreRepository storeRepository;
private final StoreMapper storeMapper;
private final BusinessPeriodRepository businessPeriodRepository;
/**
* 门店信息(分页查询)
*
* @param pageable 分页参数
* @param principal @ignore 当前登录门店
* @param pageVo 分页参数
* @param merchant @ignore 当前登录商家
* @return 分页数据信息
*/
@GetMapping
@Transactional(readOnly = true)
public ApiResult<PageData<StoreDto>> findPage(Pageable pageable, Principal principal) {
var merchant = (Merchant) principal;
public ApiResult<PageData<StoreDto>> findPage(@AuthenticationPrincipal Merchant merchant, PageVo pageVo) {
var pageData = this.storeRepository.findAll(Specification.allOf(
JpaSpecs.eq("merchant.id", merchant.getId())
), pageable).map(this.storeMapper::toDto);
), pageVo.getPageable()).map(this.storeMapper::toDto);
return ApiResult.page(pageData.getTotalElements(), pageData.getContent());
}
/**
* 创建商的门店
* 创建商的门店
*
* @param vo 门店信息
* @param principal @ignore 当前登录的商户
* @param merchant @ignore 当前登录的商家
* @return 门店信息
*/
@PostMapping
@Transactional(rollbackFor = Exception.class)
public ApiResult<StoreDto> create(@Valid @RequestBody StoreCreateVo vo, Principal principal) {
var merchant = (Merchant) principal;
if (Objects.isNull(merchant)) {
return ApiResult.fail("商家信息错误");
}
public ApiResult<StoreDto> create(@AuthenticationPrincipal Merchant merchant,
@Valid @RequestBody StoreCreateVo vo) {
var store = this.storeMapper.toEntity(vo);
merchant.addStore(store);
this.storeRepository.save(store);
@ -73,16 +83,13 @@ public class StoreController {
* 查询门店详情
*
* @param storeId 门店id
* @param principal @ignore 当前登录的商户
* @param merchant @ignore 当前登录的商家
* @return 门店详情
*/
@GetMapping("/{storeId}")
@Transactional(readOnly = true)
public ApiResult<StoreDto> findById(@PathVariable("storeId") String storeId, Principal principal) {
var merchant = (Merchant) principal;
if (Objects.isNull(merchant)) {
return ApiResult.fail("商家信息错误");
}
public ApiResult<StoreDto> findById(@AuthenticationPrincipal Merchant merchant,
@PathVariable("storeId") String storeId) {
var storeIdLong = Long.parseLong(storeId);
return merchant.getStores().stream()
.filter(x -> Objects.equals(x.getId(), storeIdLong))
@ -96,17 +103,15 @@ public class StoreController {
* 更新门店信息
*
* @param storeId 门店id
* @param principal @ignore 当前登录的商户
* @param merchant @ignore 当前登录的商家
* @param vo 更新对象
* @return 门店信息
*/
@PutMapping("/{storeId}")
@Transactional(rollbackFor = Exception.class)
public ApiResult<StoreDto> updateById(@PathVariable("storeId") String storeId, Principal principal, @Valid @RequestBody StoreUpdateVo vo) {
var merchant = (Merchant) principal;
if (Objects.isNull(merchant)) {
return ApiResult.fail("商家信息错误");
}
public ApiResult<StoreDto> updateById(@AuthenticationPrincipal Merchant merchant,
@PathVariable("storeId") String storeId,
@Valid @RequestBody StoreUpdateVo vo) {
var storeIdLong = Long.parseLong(storeId);
for (Store store : merchant.getStores()) {
if (Objects.equals(storeIdLong, store.getId())) {
@ -122,18 +127,111 @@ public class StoreController {
* 删除门店
*
* @param storeId 门店id
* @param principal @ignore 当前登录的商户
* @param merchant @ignore 当前登录的商家
*/
@DeleteMapping("/{storeId}")
@Transactional(rollbackFor = Exception.class)
public ApiResult<Void> delteById(@PathVariable("storeId") String storeId, Principal principal) {
var merchant = (Merchant) principal;
if (Objects.isNull(merchant)) {
return ApiResult.fail("商家信息错误");
}
public ApiResult<Void> delteById(@AuthenticationPrincipal Merchant merchant,
@PathVariable("storeId") String storeId) {
var storeIdLong = Long.parseLong(storeId);
merchant.getStores().removeIf(x -> Objects.equals(storeIdLong, x.getId()));
this.merchantRepository.save(merchant);
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;
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 {
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;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import com.xjhs.findmemerchant.types.AuthStatus;
import lombok.Data;
import java.time.LocalDateTime;
/**
* 商户信息
* 信息
*/
@Data
public class MerchantDto {
/**
* id
* id
*/
private String id;
@JsonSerialize(using = ToStringSerializer.class)
private Long id;
/**
* 手机号码
* 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;
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(
Long merchantId,
String accessToken,
String refreshToken
) {
@Data
@AllArgsConstructor
@NoArgsConstructor
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;
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 {
@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 jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Size;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import lombok.Data;
@Data
public class BusinessPeriodVo {
public class BusinessPeriodDto {
/**
* 门店id
*/
@JsonSerialize(using = ToStringSerializer.class)
private Long storeId;
/**
* 周几周天0,...
*/
@Size(max = 6)
@NotNull
private Integer dayOfWeek;
/**
* 开始营业时间 HH:mm 格式
*/
@NotBlank
private String startTime;
/**
* 结束营业时间 HH:mm 格式
*/
@NotBlank
private String endTime;
/**
* 是否启用

View file

@ -1,4 +1,36 @@
package com.xjhs.findmemerchant.dto.store;
import lombok.Data;
import java.time.LocalDateTime;
/**
* 门店营业状态
*/
@Data
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;
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.CommonStatus;
import com.xjhs.findmemerchant.types.StoreAuditStatus;
@ -12,11 +14,13 @@ public class StoreDto {
/**
* 门店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;
/**
* 提现银行卡
* 提现银行卡
* 对应表bank_cards
*/
@Getter
@ -23,7 +23,7 @@ import org.hibernate.annotations.Comment;
public class BankCard extends AbstractBaseEntity {
/**
*
*
*/
@ManyToOne(fetch = FetchType.LAZY)
@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("是否默认卡")
private Boolean isDefault = false;
/**
* 状态0-禁用 1-启用
*/
@Column(name = "status",columnDefinition = "VARCHAR(15)",length = 15, nullable = false)
@Column(name = "status",columnDefinition = "VARCHAR(15)",length = 15)
@Enumerated(EnumType.STRING)
@Comment("状态0禁用 1启用")
private CommonStatus status = CommonStatus.ENABLED;

View file

@ -1,7 +1,7 @@
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.types.BusinessLicenseStatus;
import jakarta.persistence.*;
@ -30,7 +30,7 @@ public class BusinessLicense extends AbstractBaseEntity {
@JoinColumn(name = "merchant_id", insertable = false, updatable = false)
private Merchant merchant;
@Column(name = "image_url", nullable = false, length = 500)
@Column(name = "image_url", length = 500)
@Comment("营业执照图片URL")
private String imageUrl;
@ -47,7 +47,7 @@ public class BusinessLicense extends AbstractBaseEntity {
@Comment("OCR原始结果")
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)
@Comment("状态0待审核 1已通过 2已拒绝")
private BusinessLicenseStatus status = BusinessLicenseStatus.PENDING;

View file

@ -32,28 +32,28 @@ public class BusinessPeriod extends AbstractBaseEntity {
/**
* 周几0=周日 ... 6=周六
*/
@Column(name = "day_of_week", nullable = false)
@Column(name = "day_of_week")
@Comment("周几0周日 1周一 ... 6周六")
private Byte dayOfWeek;
private Integer dayOfWeek;
/**
* 开始时间HH:MM
*/
@Column(name = "start_time", nullable = false, length = 5)
@Column(name = "start_time", length = 5)
@Comment("开始时间HH:MM")
private String startTime;
/**
* 结束时间HH:MM
*/
@Column(name = "end_time", nullable = false, length = 5)
@Column(name = "end_time", length = 5)
@Comment("结束时间HH:MM")
private String endTime;
/**
* 是否启用
*/
@Column(name = "is_enabled", nullable = false)
@Column(name = "is_enabled")
@Comment("是否启用")
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("优惠券名称")
private String name;
/**
* 优惠券类型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赠品券")
private CouponType type;
@ -74,49 +74,49 @@ public class Coupon extends AbstractBaseEntity {
/**
* 赠品数量默认 1
*/
@Column(name = "gift_quantity", nullable = false)
@Column(name = "gift_quantity")
@Comment("赠品数量")
private Integer giftQuantity = 1;
/**
* 发放总量
*/
@Column(name = "total_count", nullable = false)
@Column(name = "total_count")
@Comment("发放总量")
private Integer totalCount;
/**
* 已领取数量
*/
@Column(name = "claimed_count", nullable = false)
@Column(name = "claimed_count")
@Comment("已领取数量")
private Integer claimedCount = 0;
/**
* 每人限领数量0 表示不限
*/
@Column(name = "per_user_limit", nullable = false)
@Column(name = "per_user_limit")
@Comment("每人限领数量0表示不限")
private Integer perUserLimit = 1;
/**
* 领取后有效天数
*/
@Column(name = "valid_days", nullable = false)
@Column(name = "valid_days")
@Comment("领取后有效天数")
private Integer validDays;
/**
* 活动开始时间
*/
@Column(name = "start_time", nullable = false)
@Column(name = "start_time")
@Comment("活动开始时间")
private LocalDateTime startTime;
/**
* 活动结束时间
*/
@Column(name = "end_time", nullable = false)
@Column(name = "end_time")
@Comment("活动结束时间")
private LocalDateTime endTime;
@ -130,7 +130,7 @@ public class Coupon extends AbstractBaseEntity {
/**
* 状态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已结束")
private CouponStatus status = CouponStatus.ONLINE;
@ -138,7 +138,7 @@ public class Coupon extends AbstractBaseEntity {
// ================= 关联关系 =================
/**
* 所属商
* 所属商
*/
@ManyToOne(fetch = FetchType.LAZY)
@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("优惠券码")
private String code;
/**
* 状态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已过期")
private CouponCodeStatus status = CouponCodeStatus.UNCLAIMED;
@ -117,7 +117,7 @@ public class CouponCode extends AbstractBaseEntity {
*/
public boolean isClaimed() {
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("手机号")
private String phone;
/**
* 员工姓名
*/
@Column(name = "name", nullable = false, length = 50)
@Column(name = "name", length = 50)
@Comment("员工姓名")
private String name;
/**
* 状态0-禁用 1-启用
*/
@Column(name = "status",columnDefinition = "VARCHAR(15)",length = 15, nullable = false)
@Comment("状态0禁用 1启用")
@Column(name = "status",columnDefinition = "VARCHAR(15)",length = 15)
@Comment("状态")
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;
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.types.HealthCertificateStatus;
import jakarta.persistence.*;
@ -27,7 +27,7 @@ import java.util.HashMap;
)
public class HealthCertificate extends AbstractBaseEntity {
@Column(name = "image_url", nullable = false, length = 500)
@Column(name = "image_url", length = 500)
@Comment("健康证图片URL")
private String imageUrl;
@ -48,7 +48,7 @@ public class HealthCertificate extends AbstractBaseEntity {
@Comment("OCR原始结果")
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过期")
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("手机号")
private String phone;
@ -55,14 +55,14 @@ public class Member extends AbstractBaseEntity {
/**
* 累计订单数
*/
@Column(name = "total_orders", nullable = false)
@Column(name = "total_orders")
@Comment("累计订单数")
private Integer totalOrders = 0;
/**
* 累计消费金额
*/
@Column(name = "total_amount", nullable = false, precision = 12, scale = 2)
@Column(name = "total_amount", precision = 12, scale = 2)
@Comment("累计消费金额")
private BigDecimal totalAmount = BigDecimal.ZERO;
@ -75,7 +75,7 @@ public class Member extends AbstractBaseEntity {
// ============ 关联关系 ============
/**
*
*
*/
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "merchant_id", insertable = false, updatable = false)

View file

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

View file

@ -28,7 +28,7 @@ public class Message extends AbstractBaseEntity {
/**
* 消息类型1-系统通知 2-活动提醒 3-私信
*/
@Column(name = "type",columnDefinition = "VARCHAR(20)",length = 20,nullable = false)
@Column(name = "type",columnDefinition = "VARCHAR(20)",length = 20)
@Enumerated(EnumType.STRING)
@Comment("消息类型1系统通知 2活动提醒 3私信")
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("消息标题")
private String title;
/**
* 内容
*/
@Column(name = "content", nullable = false, columnDefinition = "text")
@Column(name = "content", columnDefinition = "text")
@Comment("消息内容")
private String content;
/**
* 是否已读0-未读 1-已读
*/
@Column(name = "is_read", nullable = false)
@Column(name = "is_read")
@Comment("是否已读0未读 1已读")
private Byte isRead = 0;
private Boolean isRead = false;
/**
* 创建时间
*/
@Column(name = "created_at", nullable = false)
@Column(name = "created_at")
@Comment("创建时间")
private LocalDateTime createdAt;
@ -69,7 +69,7 @@ public class Message extends AbstractBaseEntity {
private LocalDateTime readAt;
/**
*
*
*/
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "merchant_id", insertable = false, updatable = false)
@ -81,7 +81,7 @@ public class Message extends AbstractBaseEntity {
* 标记为已读
*/
public void markAsRead() {
this.isRead = 1;
this.isRead = true;
this.readAt = LocalDateTime.now();
}
@ -89,7 +89,7 @@ public class Message extends AbstractBaseEntity {
* 是否未读
*/
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("订单号")
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("订单总金额")
private BigDecimal totalAmount;
/**
* 优惠金额
*/
@Column(name = "discount_amount", nullable = false, precision = 10, scale = 2)
@Column(name = "discount_amount", precision = 10, scale = 2)
@Comment("优惠金额")
private BigDecimal discountAmount = BigDecimal.ZERO;
/**
* 实付金额
*/
@Column(name = "pay_amount", nullable = false, precision = 10, scale = 2)
@Column(name = "pay_amount", precision = 10, scale = 2)
@Comment("实付金额")
private BigDecimal payAmount;
@ -69,7 +69,7 @@ public class Order extends AbstractBaseEntity {
/**
* 订单状态1-待支付 2-已支付 3-已完成 4-已退款 5-已取消
*/
@Column(name = "status", nullable = false)
@Column(name = "status")
@Comment("订单状态1待支付 2已支付 3已完成 4已退款 5已取消")
private OrderStatus status;

View file

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

View file

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

View file

@ -1,6 +1,6 @@
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.types.CommonStatus;
import jakarta.persistence.*;
@ -32,14 +32,13 @@ public class ProductSKU extends AbstractBaseEntity {
@Id
@GeneratedValue
@SnowflakeGenerated
@Column(nullable = false)
@Comment("主键ID")
private Long id;
/**
* 规格名称大杯/加冰
*/
@Column(name = "sku_name", nullable = false, length = 100)
@Column(name = "sku_name", length = 100)
@Comment("规格名称")
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("规格价格")
private BigDecimal price;
/**
* 库存-1 表示无限库存
*/
@Column(name = "stock", nullable = false)
@Column(name = "stock")
@Comment("库存,-1表示无限库存")
private Integer stock = -1;
/**
* 已售数量
*/
@Column(name = "sold_count", nullable = false)
@Column(name = "sold_count")
@Comment("已售数量")
private Integer soldCount = 0;
/**
* 状态0-禁用 1-启用
*/
@Column(name = "status",columnDefinition = "VARCHAR(20)",length = 20,nullable = false)
@Column(name = "status",columnDefinition = "VARCHAR(20)",length = 20)
@Comment("状态0禁用 1启用")
private CommonStatus status = CommonStatus.ENABLED;

View file

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

View file

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

View file

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

View file

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

View file

@ -9,7 +9,9 @@ import lombok.Getter;
import lombok.Setter;
import org.hibernate.annotations.Comment;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ArrayList;
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("门店名称")
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("联系电话")
private String phone;
/**
*
*/
@Column(name = "province", nullable = false, length = 50)
@Column(name = "province", length = 50)
@Comment("")
private String province;
/**
*
*/
@Column(name = "city", nullable = false, length = 50)
@Column(name = "city", length = 50)
@Comment("")
private String city;
/**
* /
*/
@Column(name = "district", nullable = false, length = 50)
@Column(name = "district", length = 50)
@Comment("区/县")
private String district;
/**
* 详细地址
*/
@Column(name = "address", nullable = false, length = 200)
@Column(name = "address", length = 200)
@Comment("详细地址")
private String address;
@ -81,14 +83,14 @@ public class Store extends AbstractBaseEntity {
*/
@Column(name = "longitude", precision = 10, scale = 7)
@Comment("经度")
private Double longitude;
private BigDecimal longitude;
/**
* 纬度
*/
@Column(name = "latitude", precision = 10, scale = 7)
@Comment("纬度")
private Double latitude;
private BigDecimal latitude;
/**
* 营业时间描述
@ -100,7 +102,7 @@ public class Store extends AbstractBaseEntity {
/**
* 营业状态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)
@Comment("营业状态0已打烊 1营业中 2临时打烊")
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已拒绝")
private StoreAuditStatus auditStatus = StoreAuditStatus.PENDING;
@ -136,30 +138,41 @@ public class Store extends AbstractBaseEntity {
/**
* 启用状态0-禁用 1-启用
*/
@Column(name = "status",columnDefinition = "VARCHAR(20)", length = 20, nullable = false)
@Column(name = "status",columnDefinition = "VARCHAR(20)", length = 20)
@Comment("启用状态0禁用 1启用")
private CommonStatus status = CommonStatus.ENABLED;
// ========== 关联关系 ==========
/**
*
*
*/
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "merchant_id", insertable = false, updatable = false)
@JoinColumn(name = "merchant_id")
private Merchant merchant;
/**
* 员工列表
*/
@OneToMany(mappedBy = "store", fetch = FetchType.LAZY)
private List<Employee> employees;
@OneToMany(mappedBy = "store", fetch = FetchType.LAZY,cascade = CascadeType.ALL,orphanRemoval = true)
private List<Employee> employees = new ArrayList<>();
public void addEmployee(Employee employee){
employee.setStore(this);
this.employees.add(employee);
}
/**
* 营业时间段
*/
@OneToMany(mappedBy = "store", fetch = FetchType.LAZY)
private List<BusinessPeriod> businessPeriods;
@OneToMany(mappedBy = "store", fetch = FetchType.LAZY,cascade = CascadeType.ALL,orphanRemoval = true)
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;
import com.xjhs.findmemerchant.adapter.id.SnowflakeGenerated;
import com.xjhs.findmemerchant.common.jpa.id.SnowflakeGenerated;
import com.xjhs.findmemerchant.types.TransactionType;
import jakarta.persistence.*;
import lombok.Getter;
@ -34,7 +34,6 @@ public class Transaction {
@Id
@GeneratedValue
@SnowflakeGenerated
@Column(nullable = false)
@Comment("主键ID")
private Long id;
@ -42,28 +41,28 @@ public class Transaction {
/**
* 交易类型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提现")
private TransactionType type;
/**
* 交易金额
*/
@Column(name = "amount", nullable = false, precision = 12, scale = 2)
@Column(name = "amount", precision = 12, scale = 2)
@Comment("交易金额")
private BigDecimal amount;
/**
* 交易前余额
*/
@Column(name = "balance_before", nullable = false, precision = 12, scale = 2)
@Column(name = "balance_before", precision = 12, scale = 2)
@Comment("交易前余额")
private BigDecimal balanceBefore;
/**
* 交易后余额
*/
@Column(name = "balance_after", nullable = false, precision = 12, scale = 2)
@Column(name = "balance_after", precision = 12, scale = 2)
@Comment("交易后余额")
private BigDecimal balanceAfter;
@ -91,7 +90,7 @@ public class Transaction {
/**
* 创建时间
*/
@Column(name = "created_at", nullable = false)
@Column(name = "created_at")
@Comment("创建时间")
private LocalDateTime createdAt;
@ -104,7 +103,7 @@ public class Transaction {
/**
*
*
*/
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "merchant_id", insertable = false, updatable = false)

View file

@ -1,6 +1,5 @@
package com.xjhs.findmemerchant.entity;
import com.xjhs.findmemerchant.adapter.id.SnowflakeGenerated;
import com.xjhs.findmemerchant.common.jpa.AbstractBaseEntity;
import jakarta.persistence.*;
import lombok.Getter;
@ -10,7 +9,7 @@ import org.hibernate.annotations.Comment;
import java.math.BigDecimal;
/**
* 钱包
* 钱包
* 对应表wallets
*/
@Getter
@ -24,58 +23,47 @@ import java.math.BigDecimal;
)
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("可用余额")
private BigDecimal balance = BigDecimal.ZERO;
/**
* 冻结余额提现中
*/
@Column(name = "frozen_balance", nullable = false, precision = 12, scale = 2)
@Column(name = "frozen_balance", precision = 12, scale = 2)
@Comment("冻结余额(提现中)")
private BigDecimal frozenBalance = BigDecimal.ZERO;
/**
* 累计收入
*/
@Column(name = "total_income", nullable = false, precision = 12, scale = 2)
@Column(name = "total_income", precision = 12, scale = 2)
@Comment("累计收入")
private BigDecimal totalIncome = BigDecimal.ZERO;
/**
* 累计提现
*/
@Column(name = "total_withdrawn", nullable = false, precision = 12, scale = 2)
@Column(name = "total_withdrawn", precision = 12, scale = 2)
@Comment("累计提现")
private BigDecimal totalWithdrawn = BigDecimal.ZERO;
/**
* 待结算金额
*/
@Column(name = "pending_settlement", nullable = false, precision = 12, scale = 2)
@Column(name = "pending_settlement", precision = 12, scale = 2)
@Comment("待结算金额")
private BigDecimal pendingSettlement = BigDecimal.ZERO;
/**
*
*
*/
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "merchant_id", insertable = false, updatable = false)
@JoinColumn(name = "merchant_id")
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("提现金额")
private BigDecimal amount;
/**
* 手续费
*/
@Column(name = "fee", nullable = false, precision = 10, scale = 2)
@Column(name = "fee", precision = 10, scale = 2)
@Comment("提现手续费")
private BigDecimal fee = BigDecimal.ZERO;
/**
* 实际到账金额
*/
@Column(name = "actual_amount", nullable = false, precision = 12, scale = 2)
@Column(name = "actual_amount", precision = 12, scale = 2)
@Comment("实际到账金额")
private BigDecimal actualAmount;
/**
* 银行名称
*/
@Column(name = "bank_name", nullable = false, length = 50)
@Column(name = "bank_name", length = 50)
@Comment("银行名称")
private String bankName;
/**
* 银行账号加密存储
*/
@Column(name = "bank_account", nullable = false, length = 30)
@Column(name = "bank_account", length = 30)
@Comment("银行账号(加密)")
private String bankAccount;
/**
* 户名
*/
@Column(name = "account_name", nullable = false, length = 50)
@Column(name = "account_name", length = 50)
@Comment("开户人姓名")
private String accountName;
/**
* 状态0-待审核 1-处理中 2-已完成 3-已拒绝 4-已取消
*/
@Column(name = "status", nullable = false)
@Column(name = "status")
@Comment("提现状态")
private Byte status = 0;
@ -114,7 +114,7 @@ public class Withdrawal extends AbstractBaseEntity {
private String remark;
/**
*
*
*/
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "merchant_id", insertable = false, updatable = false)

View file

@ -1,4 +1,20 @@
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.entity.Merchant;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.ReportingPolicy;
@Mapper(componentModel = "spring",unmappedTargetPolicy = ReportingPolicy.IGNORE,unmappedSourcePolicy = ReportingPolicy.IGNORE)
public interface MerchantMapper {
@Mapping(target = "authStatusDesc",source = "authStatus.desc")
MerchantDto toDto(Merchant merchant);
}

View file

@ -1,17 +1,32 @@
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.entity.BusinessPeriod;
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.StoreUpdateVo;
import org.mapstruct.*;
import java.util.List;
@Mapper(componentModel = "spring",unmappedTargetPolicy = ReportingPolicy.IGNORE,unmappedSourcePolicy = ReportingPolicy.IGNORE)
public interface StoreMapper {
StoreDto toDto(Store store);
StoreBusinessStatusDto toBusinessStatusDto(Store store);
Store toEntity(StoreCreateVo createVo);
Store toEntity(StoreUpdateVo updateVo);
@BeanMapping(nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.IGNORE)
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;
import com.xjhs.findmemerchant.entity.Activity;
import com.xjhs.findmemerchant.types.ActivityStatus;
import org.springframework.data.jpa.repository.JpaRepository;
import java.util.List;
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;
/**
* 银行卡仓储
* 银行卡仓储
*/
public interface BankCardRepository extends JpaRepository<BankCard, Long>,
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>,
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;
import com.xjhs.findmemerchant.entity.Coupon;
import com.xjhs.findmemerchant.types.CouponStatus;
import org.springframework.data.jpa.repository.JpaRepository;
import java.util.List;
@ -12,17 +13,17 @@ import java.util.Optional;
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> {
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>,
JpaSpecificationExecutor<Employee> {
/**
* 按商户查询员工
*/
List<Employee> findByMerchantId(Long merchantId);
/**
* 按门店查询员工
*/
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>,
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> {
/**
* 按商查询会员
* 按商查询会员
*/
List<Member> findByMerchantId(Long merchantId);
List<Member> findByMerchant_Id(Long merchantId);
/**
* 按商 + 手机号查询唯一
* 按商 + 手机号查询唯一
*/
Optional<Member> findByPhone(String phone);

View file

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

View file

@ -13,17 +13,14 @@ public interface MessageRepository extends JpaRepository<Message, Long>,
JpaSpecificationExecutor<Message> {
/**
* 按商查询消息
* 按商查询消息
*/
List<Message> findByMerchantId(Long merchantId);
List<Message> findByMerchant_Id(Long merchantId);
/**
* 按商户 + 是否已读查询
*/
List<Message> findByMerchantIdAndIsRead(Long merchantId, Byte isRead);
List<Message> findByMerchant_IdAndIsRead(Long merchantId, Boolean 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);
}

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> findByMemberId(Long memberId);
List<Order> findByMember_Id(Long memberId);
}

View file

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

View file

@ -1,6 +1,7 @@
package com.xjhs.findmemerchant.repository;
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.JpaSpecificationExecutor;
@ -12,10 +13,7 @@ import java.util.List;
public interface ProductRepository extends JpaRepository<Product, Long>,
JpaSpecificationExecutor<Product> {
/**
* 按商户查询商品
*/
List<Product> findByMerchantId(Long merchantId);
List<Product> findByMerchant_Id(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>,
JpaSpecificationExecutor<Review> {
List<Review> findByMerchantId(Long merchantId);
List<Review> findByMerchant_Id(Long merchantId);
List<Review> findByStoreId(Long storeId);

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -14,7 +14,7 @@ import java.nio.charset.StandardCharsets;
public class JwtTokenService {
// 建议改成配置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
/**
@ -33,7 +33,6 @@ public class JwtTokenService {
));
jws.setAlgorithmHeaderValue(AlgorithmIdentifiers.HMAC_SHA256);
return jws.getCompactSerialization();
}

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -11,13 +11,25 @@ import lombok.Getter;
@AllArgsConstructor
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 byte code;
public static CouponCodeStatus fromCode(Byte code) {
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
public enum CouponStatus {
/**
* 下架
*/
OFFLINE("下架"),
/**
* 进行中
*/
ONLINE("进行中"),
/**
* 已结束
*/
ENDED("已结束");
private final String desc;

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -11,10 +11,25 @@ import lombok.Getter;
@AllArgsConstructor
public enum WithdrawalStatus {
/**
* 待审核
*/
PENDING("待审核"),
/**
* 处理中
*/
PROCESSING("处理中"),
/**
* 已完成
*/
COMPLETED("已完成"),
/**
* 已拒绝
*/
REJECTED("已拒绝"),
/**
* 已取消
*/
CANCELLED("已取消");
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;

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.Size;

View file

@ -1,4 +1,37 @@
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 {
/**
* 员工姓名
*/
@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