Compare commits
7 commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c150c74206 | ||
|
|
78d47cf363 | ||
|
|
cf2295b85f | ||
|
|
39953cca84 | ||
|
|
0edffa145b | ||
|
|
f14f45faf5 | ||
|
|
b6a678b874 |
119 changed files with 1002 additions and 6059 deletions
34
pom.xml
34
pom.xml
|
|
@ -17,7 +17,25 @@
|
||||||
<properties>
|
<properties>
|
||||||
<java.version>25</java.version>
|
<java.version>25</java.version>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
|
|
||||||
|
<dependencyManagement>
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.cloud</groupId>
|
||||||
|
<artifactId>spring-cloud-dependencies</artifactId>
|
||||||
|
<version>2025.0.1</version>
|
||||||
|
<type>pom</type>
|
||||||
|
<scope>import</scope>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
</dependencyManagement>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.cloud</groupId>
|
||||||
|
<artifactId>spring-cloud-starter-openfeign</artifactId>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
<artifactId>spring-boot-starter-web</artifactId>
|
<artifactId>spring-boot-starter-web</artifactId>
|
||||||
|
|
@ -76,6 +94,22 @@
|
||||||
<artifactId>commons-lang3</artifactId>
|
<artifactId>commons-lang3</artifactId>
|
||||||
<version>3.18.0</version>
|
<version>3.18.0</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<!--腾讯云SDK-->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.tencentcloudapi</groupId>
|
||||||
|
<artifactId>tencentcloud-sdk-java</artifactId>
|
||||||
|
<version>3.1.1396</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.qcloud</groupId>
|
||||||
|
<artifactId>cos_api</artifactId>
|
||||||
|
<version>5.6.246</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.tika</groupId>
|
||||||
|
<artifactId>tika-core</artifactId>
|
||||||
|
<version>3.2.3</version>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,7 @@ public class AbstractBaseEntity {
|
||||||
@CreatedDate
|
@CreatedDate
|
||||||
@Column(name = "created_at", nullable = false, updatable = false)
|
@Column(name = "created_at", nullable = false, updatable = false)
|
||||||
@Comment("创建时间")
|
@Comment("创建时间")
|
||||||
private LocalDateTime createdAt;
|
private LocalDateTime createTime;
|
||||||
/**
|
/**
|
||||||
* 创建人
|
* 创建人
|
||||||
*/
|
*/
|
||||||
|
|
@ -49,7 +49,7 @@ public class AbstractBaseEntity {
|
||||||
@LastModifiedDate
|
@LastModifiedDate
|
||||||
@Column(name = "updated_at", nullable = false)
|
@Column(name = "updated_at", nullable = false)
|
||||||
@Comment("更新时间")
|
@Comment("更新时间")
|
||||||
private LocalDateTime updatedAt;
|
private LocalDateTime updateTime;
|
||||||
/**
|
/**
|
||||||
* 更新人
|
* 更新人
|
||||||
*/
|
*/
|
||||||
|
|
@ -62,20 +62,20 @@ public class AbstractBaseEntity {
|
||||||
*/
|
*/
|
||||||
@Column(name = "deleted_at")
|
@Column(name = "deleted_at")
|
||||||
@Comment("软删除时间")
|
@Comment("软删除时间")
|
||||||
private LocalDateTime deletedAt;
|
private LocalDateTime deleteTime;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 是否已删除
|
* 是否已删除
|
||||||
*/
|
*/
|
||||||
public boolean isDeleted() {
|
public boolean isDeleted() {
|
||||||
return deletedAt != null;
|
return deleteTime != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 标记删除
|
* 标记删除
|
||||||
*/
|
*/
|
||||||
public void markDeleted() {
|
public void markDeleted() {
|
||||||
this.deletedAt = LocalDateTime.now();
|
this.deleteTime = LocalDateTime.now();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,75 @@
|
||||||
|
package com.xjhs.findmemerchant.common.openapi;
|
||||||
|
|
||||||
|
import com.qcloud.cos.COSClient;
|
||||||
|
import com.qcloud.cos.exception.CosClientException;
|
||||||
|
import com.qcloud.cos.model.GetObjectRequest;
|
||||||
|
import com.qcloud.cos.model.PutObjectRequest;
|
||||||
|
import com.xjhs.findmemerchant.common.openapi.dto.CosPutObjectResult;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
@Service
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class TencentCOSService {
|
||||||
|
@Value("${appconfig.tencentCos.bucketName}")
|
||||||
|
private String bucketName;
|
||||||
|
private final COSClient tencentCosClient;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 文件上传到Cos存储桶
|
||||||
|
*
|
||||||
|
* @param file 文件
|
||||||
|
* @return 存储对象信息
|
||||||
|
*/
|
||||||
|
public CosPutObjectResult putObject(File file) throws Exception {
|
||||||
|
try {
|
||||||
|
var key = UUID.randomUUID().toString();
|
||||||
|
var req = new PutObjectRequest(this.bucketName, key, file);
|
||||||
|
var result = tencentCosClient.putObject(req);
|
||||||
|
return new CosPutObjectResult(key, result.getETag());
|
||||||
|
} catch (CosClientException e) {
|
||||||
|
log.error("文件上传到对象存储失败", e);
|
||||||
|
throw new Exception("文件上传到对象存储失败");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取文件输入流(下载文件)
|
||||||
|
* @param key 对象key
|
||||||
|
* @return 输入流
|
||||||
|
* @throws Exception 下载失败
|
||||||
|
*/
|
||||||
|
public InputStream getObject(String key) throws Exception{
|
||||||
|
try {
|
||||||
|
var req = new GetObjectRequest(this.bucketName, key);
|
||||||
|
var cosObject = this.tencentCosClient.getObject(req);
|
||||||
|
return cosObject.getObjectContent();
|
||||||
|
} catch (CosClientException e) {
|
||||||
|
log.error("从对象存储下载文件失败",e);
|
||||||
|
throw new Exception("从对象存储下载文件失败");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除存储对象
|
||||||
|
*
|
||||||
|
* @param key 对象key
|
||||||
|
* @throws Exception 删除失败
|
||||||
|
*/
|
||||||
|
public void deleteObject(String key) throws Exception {
|
||||||
|
try {
|
||||||
|
this.tencentCosClient.deleteObject(this.bucketName, key);
|
||||||
|
} catch (CosClientException e) {
|
||||||
|
log.error("文件上传到对象存储失败", e);
|
||||||
|
throw new Exception("文件上传到对象存储失败");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,57 @@
|
||||||
|
package com.xjhs.findmemerchant.common.openapi;
|
||||||
|
|
||||||
|
|
||||||
|
import com.tencentcloudapi.common.exception.TencentCloudSDKException;
|
||||||
|
import com.tencentcloudapi.sms.v20190711.models.SendSmsRequest;
|
||||||
|
import com.tencentcloudapi.sms.v20190711.SmsClient;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
@Service
|
||||||
|
@RequiredArgsConstructor()
|
||||||
|
public class TencentCloudSMSService {
|
||||||
|
@Value("${appconfig.tencentSms.sdkAppId}")
|
||||||
|
private String sdkAppid;
|
||||||
|
@Value("${appconfig.tencentSms.templateId}")
|
||||||
|
private String templateId;
|
||||||
|
@Value("${appconfig.tencentSms.signName}")
|
||||||
|
private String signName;
|
||||||
|
private final SmsClient tencentSmsClient;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 发送短信验证码
|
||||||
|
*
|
||||||
|
* @param phone 11位国内手机号码
|
||||||
|
* @param code 验证码
|
||||||
|
* @return 验证码值
|
||||||
|
* @throws Exception 发送失败
|
||||||
|
*/
|
||||||
|
public String sendVerifyCode(String phone, String code) throws Exception {
|
||||||
|
try {
|
||||||
|
if (!phone.startsWith("+86")) {
|
||||||
|
phone = "+86" + phone;
|
||||||
|
}
|
||||||
|
var req = new SendSmsRequest();
|
||||||
|
req.setSmsSdkAppid(this.sdkAppid);
|
||||||
|
req.setTemplateID(this.templateId);
|
||||||
|
req.setSign(this.signName);
|
||||||
|
req.setPhoneNumberSet(new String[]{phone});
|
||||||
|
req.setTemplateParamSet(new String[]{code});
|
||||||
|
var resp = this.tencentSmsClient.SendSms(req);
|
||||||
|
if (resp.getSendStatusSet().length == 0){
|
||||||
|
throw new Exception("取回短信发送结果失败");
|
||||||
|
}
|
||||||
|
if (!"ok".equalsIgnoreCase(resp.getSendStatusSet()[0].getCode())){
|
||||||
|
throw new Exception(resp.getSendStatusSet()[0].getMessage());
|
||||||
|
}
|
||||||
|
return code;
|
||||||
|
} catch (TencentCloudSDKException e) {
|
||||||
|
log.error("验证码发送失败", e);
|
||||||
|
throw new Exception("系统错误,验证码发送失败");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,35 @@
|
||||||
|
package com.xjhs.findmemerchant.common.openapi.amap;
|
||||||
|
|
||||||
|
|
||||||
|
import com.xjhs.findmemerchant.common.openapi.amap.response.AmapGeocodeResponse;
|
||||||
|
import com.xjhs.findmemerchant.common.openapi.amap.response.AmapReGeocodeResponse;
|
||||||
|
import org.springframework.cloud.openfeign.FeignClient;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestParam;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 高德地图服务接口
|
||||||
|
*/
|
||||||
|
@FeignClient(name = "amapFeignClient", url = "https://restapi.amap.com")
|
||||||
|
public interface AmapFeignClient {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 地理编码 API 服务
|
||||||
|
* @param key 高德Key
|
||||||
|
* @param address 结构化地址信息,规则遵循:国家、省份、城市、区县、城镇、乡村、街道、门牌号码、屋邨、大厦,如:北京市朝阳区阜通东大街6号。
|
||||||
|
* @return 响应信息
|
||||||
|
*/
|
||||||
|
@GetMapping("/v3/geocode/geo")
|
||||||
|
AmapGeocodeResponse getGeo(@RequestParam(name = "key") String key,
|
||||||
|
@RequestParam(name = "address") String address);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 逆地理编码 API 服务地址
|
||||||
|
* @param key 高德Key
|
||||||
|
* @param location 经纬度坐标 传入内容规则:经度在前,纬度在后,经纬度间以“,”分割,经纬度小数点后不要超过 6 位。
|
||||||
|
*/
|
||||||
|
@GetMapping("/v3/geocode/regeo")
|
||||||
|
AmapReGeocodeResponse getReGeo(@RequestParam(name = "key") String key,
|
||||||
|
@RequestParam(name = "location") String location);
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,39 @@
|
||||||
|
package com.xjhs.findmemerchant.common.openapi.amap;
|
||||||
|
|
||||||
|
import com.xjhs.findmemerchant.common.openapi.amap.response.AmapGeocodeResponse;
|
||||||
|
import com.xjhs.findmemerchant.common.openapi.amap.response.AmapReGeocodeResponse;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
@Service
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class AmapService {
|
||||||
|
|
||||||
|
@Value("${appconfig.amapKey}")
|
||||||
|
private String amapKey = "c618de6e686c43095a8593db836c7de2";
|
||||||
|
private final AmapFeignClient amapFeignClient;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 地址转经纬度
|
||||||
|
*
|
||||||
|
* @param address 地址信息
|
||||||
|
* @return 经纬度信息结果
|
||||||
|
*/
|
||||||
|
public AmapGeocodeResponse getGeo(String address) {
|
||||||
|
return this.amapFeignClient.getGeo(this.amapKey, address);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 经纬度转地理位置信息
|
||||||
|
*
|
||||||
|
* @param lng 经度
|
||||||
|
* @param lat 纬度
|
||||||
|
* @return 位置信息
|
||||||
|
*/
|
||||||
|
public AmapReGeocodeResponse getRegeo(double lng, double lat) {
|
||||||
|
return this.amapFeignClient.getReGeo(this.amapKey, lng + "," + lat);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,95 @@
|
||||||
|
package com.xjhs.findmemerchant.common.openapi.amap.response;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 地理编码 API 服务响应内容
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class AmapGeocodeResponse {
|
||||||
|
/**
|
||||||
|
* 请求状态值,0 表示请求失败,1 表示请求成功
|
||||||
|
*/
|
||||||
|
private int status;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 返回结果的数量
|
||||||
|
*/
|
||||||
|
private int count;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 返回结果的详细说明,当 status 为 0 时,info 会包含错误原因;否则返回 "OK"
|
||||||
|
*/
|
||||||
|
private String info;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 地理编码信息列表,包含多个地址组件
|
||||||
|
*/
|
||||||
|
private List<GeocodeDetails> geocodes = new ArrayList<>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 地理编码信息的详细字段
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public static class GeocodeDetails {
|
||||||
|
|
||||||
|
@JsonProperty("formatted_address")
|
||||||
|
private String address;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 国家,默认返回中国
|
||||||
|
*/
|
||||||
|
private String country;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 省份名称,例如:北京市
|
||||||
|
*/
|
||||||
|
private String province;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 城市名称,例如:北京市
|
||||||
|
*/
|
||||||
|
private String city;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 城市编码,例如:010
|
||||||
|
*/
|
||||||
|
private String citycode;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 区域名称,例如:朝阳区
|
||||||
|
*/
|
||||||
|
private String district;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 街道名称,例如:单通东大街
|
||||||
|
*/
|
||||||
|
private String street;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 门牌号,例如:6号
|
||||||
|
*/
|
||||||
|
private String number;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 区域编码,例如:110101
|
||||||
|
*/
|
||||||
|
private String adcode;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 经纬度坐标,逗号分隔
|
||||||
|
*/
|
||||||
|
private String location;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 匹配级别,用于地理匹配的精确度
|
||||||
|
*/
|
||||||
|
private String level;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,207 @@
|
||||||
|
package com.xjhs.findmemerchant.common.openapi.amap.response;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 逆地理位置服务响应内容
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class AmapReGeocodeResponse {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 请求状态,1 表示请求成功
|
||||||
|
*/
|
||||||
|
private String status;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 地址组件信息
|
||||||
|
*/
|
||||||
|
private Regeocode regeocode;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 返回的状态信息
|
||||||
|
*/
|
||||||
|
private String info;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 状态码,10000 表示成功
|
||||||
|
*/
|
||||||
|
private String infocode;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 地址组件类,包含具体的地理信息
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public static class Regeocode {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 地址组件,包含城市、区、街道等信息
|
||||||
|
*/
|
||||||
|
private AddressComponent addressComponent;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 格式化后的地址,整合了详细信息
|
||||||
|
*/
|
||||||
|
@JsonProperty("formatted_address")
|
||||||
|
private String address;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 地址组件,包含详细的地理信息
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public static class AddressComponent {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 城市名称,可能为空
|
||||||
|
*/
|
||||||
|
private List<String> city = new ArrayList<>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 省份名称
|
||||||
|
*/
|
||||||
|
private String province;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 区域编码
|
||||||
|
*/
|
||||||
|
private String adcode;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 区域名称
|
||||||
|
*/
|
||||||
|
private String district;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 城镇编码
|
||||||
|
*/
|
||||||
|
private String towncode;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 街道信息
|
||||||
|
*/
|
||||||
|
private StreetNumber streetNumber;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 国家名称
|
||||||
|
*/
|
||||||
|
private String country;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 街道所属乡镇名称
|
||||||
|
*/
|
||||||
|
private String township;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 商圈信息,包含多个商圈
|
||||||
|
*/
|
||||||
|
private List<BusinessArea> businessAreas;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 建筑信息
|
||||||
|
*/
|
||||||
|
private Building building;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 邻里信息
|
||||||
|
*/
|
||||||
|
private Neighborhood neighborhood;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 城市编码
|
||||||
|
*/
|
||||||
|
private String citycode;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 街道信息,包括街道名称、位置、方向等
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public static class StreetNumber {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 门牌号
|
||||||
|
*/
|
||||||
|
private String number;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 经纬度位置
|
||||||
|
*/
|
||||||
|
private String location;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 方向
|
||||||
|
*/
|
||||||
|
private String direction;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 距离
|
||||||
|
*/
|
||||||
|
private String distance;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 街道名称
|
||||||
|
*/
|
||||||
|
private String street;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 商圈信息
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public static class BusinessArea {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 商圈位置(经纬度)
|
||||||
|
*/
|
||||||
|
private String location;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 商圈名称
|
||||||
|
*/
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 商圈ID
|
||||||
|
*/
|
||||||
|
private String id;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 建筑信息,包括建筑名称和类型
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public static class Building {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 建筑名称
|
||||||
|
*/
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 建筑类型
|
||||||
|
*/
|
||||||
|
private String type;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 邻里信息
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public static class Neighborhood {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 邻里名称
|
||||||
|
*/
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 邻里类型
|
||||||
|
*/
|
||||||
|
private String type;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,13 @@
|
||||||
|
package com.xjhs.findmemerchant.common.openapi.dto;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@AllArgsConstructor
|
||||||
|
@NoArgsConstructor
|
||||||
|
public class CosPutObjectResult {
|
||||||
|
private String key;
|
||||||
|
private String eTag;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,13 @@
|
||||||
|
package com.xjhs.findmemerchant.config;
|
||||||
|
|
||||||
|
import com.xjhs.findmemerchant.common.openapi.amap.AmapFeignClient;
|
||||||
|
import org.springframework.cloud.openfeign.EnableFeignClients;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
@EnableFeignClients(basePackageClasses = {
|
||||||
|
AmapFeignClient.class,
|
||||||
|
})
|
||||||
|
public class FeignConfig {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
package com.xjhs.findmemerchant.config;
|
package com.xjhs.findmemerchant.config;
|
||||||
|
|
||||||
import com.xjhs.findmemerchant.entity.Merchant;
|
import com.xjhs.findmemerchant.security.LoginUser;
|
||||||
import com.xjhs.findmemerchant.security.sms.SmsAuthenticationToken;
|
import com.xjhs.findmemerchant.security.sms.SmsAuthenticationToken;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
|
@ -20,8 +20,8 @@ public class JpaConfig {
|
||||||
var auth = SecurityContextHolder.getContext().getAuthentication();
|
var auth = SecurityContextHolder.getContext().getAuthentication();
|
||||||
if (auth instanceof SmsAuthenticationToken){
|
if (auth instanceof SmsAuthenticationToken){
|
||||||
var principal = auth.getPrincipal();
|
var principal = auth.getPrincipal();
|
||||||
if (principal instanceof Merchant merchant){
|
if (principal instanceof LoginUser loginUser){
|
||||||
return Optional.of(merchant.getId());
|
return Optional.of(loginUser.getUserId());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return Optional.of(0L);
|
return Optional.of(0L);
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,36 @@
|
||||||
|
package com.xjhs.findmemerchant.config;
|
||||||
|
|
||||||
|
import com.qcloud.cos.COSClient;
|
||||||
|
import com.qcloud.cos.ClientConfig;
|
||||||
|
import com.qcloud.cos.auth.BasicCOSCredentials;
|
||||||
|
import com.tencentcloudapi.common.Credential;
|
||||||
|
import com.tencentcloudapi.common.profile.ClientProfile;
|
||||||
|
import com.tencentcloudapi.common.profile.HttpProfile;
|
||||||
|
import com.tencentcloudapi.common.profile.Region;
|
||||||
|
import com.tencentcloudapi.sms.v20190711.SmsClient;
|
||||||
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
public class ThirdOpenApiConfig {
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public SmsClient tencentSmsClient(@Value("${appconfig.tencentSms.secretId}") String secretId,
|
||||||
|
@Value("${appconfig.tencentSms.secretKey}") String secretKey) {
|
||||||
|
var cred = new Credential(secretId, secretKey);
|
||||||
|
var httpProfile = new HttpProfile();
|
||||||
|
httpProfile.setEndpoint("sms.tencentcloudapi.com");
|
||||||
|
var clientProfile = new ClientProfile();
|
||||||
|
clientProfile.setHttpProfile(httpProfile);
|
||||||
|
return new SmsClient(cred, "ap-guangzhou", clientProfile);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public COSClient tencentCosClient(@Value("${appconfig.tencentCos.secretId}") String secretId,
|
||||||
|
@Value("${appconfig.tencentCos.secretKey}") String secretKey){
|
||||||
|
var cred = new BasicCOSCredentials(secretId,secretKey);
|
||||||
|
ClientConfig clientConfig = new ClientConfig(new com.qcloud.cos.region.Region("ap-guangzhou"));
|
||||||
|
return new COSClient(cred, clientConfig);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,20 +1,22 @@
|
||||||
package com.xjhs.findmemerchant.controller;
|
package com.xjhs.findmemerchant.controller;
|
||||||
|
|
||||||
import com.xjhs.findmemerchant.common.ApiResult;
|
import com.xjhs.findmemerchant.common.ApiResult;
|
||||||
import com.xjhs.findmemerchant.dto.MerchantDto;
|
|
||||||
import com.xjhs.findmemerchant.dto.auth.RegisterDto;
|
import com.xjhs.findmemerchant.dto.auth.RegisterDto;
|
||||||
|
import com.xjhs.findmemerchant.dto.merchant.MerchantDto;
|
||||||
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.LoginUser;
|
||||||
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.system.SystemUserService;
|
||||||
import com.xjhs.findmemerchant.vo.auth.SmsLoginVo;
|
import com.xjhs.findmemerchant.vo.auth.SmsLoginVo;
|
||||||
import com.xjhs.findmemerchant.vo.auth.SmsSendVo;
|
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 com.xjhs.findmemerchant.vo.auth.RegisterVo;
|
||||||
|
import com.xjhs.findmemerchant.vo.merchant.MerchantUpdateVo;
|
||||||
import jakarta.validation.Valid;
|
import jakarta.validation.Valid;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
@ -22,6 +24,7 @@ import org.apache.commons.lang3.StringUtils;
|
||||||
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.security.core.annotation.AuthenticationPrincipal;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
@ -40,7 +43,8 @@ public class AuthController {
|
||||||
private final RefreshTokenService refreshTokenService;
|
private final RefreshTokenService refreshTokenService;
|
||||||
private final MerchantRepository merchantRepository;
|
private final MerchantRepository merchantRepository;
|
||||||
private final TokenBlacklistRedisService tokenBlacklistRedisService;
|
private final TokenBlacklistRedisService tokenBlacklistRedisService;
|
||||||
private final MerchantService merchantService;
|
private final SystemUserService systemUserService;
|
||||||
|
private final MerchantMapper merchantMapper;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 发送短信验证码
|
* 发送短信验证码
|
||||||
|
|
@ -122,41 +126,46 @@ public class AuthController {
|
||||||
* @return 注册成功返回登录令牌信息
|
* @return 注册成功返回登录令牌信息
|
||||||
*/
|
*/
|
||||||
@PostMapping("/register")
|
@PostMapping("/register")
|
||||||
public ApiResult<RegisterDto> register(@Valid @RequestBody RegisterVo registerVo) {
|
@Transactional
|
||||||
|
public ApiResult<RegisterDto> register(@Valid @RequestBody RegisterVo registerVo) throws Exception {
|
||||||
try {
|
try {
|
||||||
this.smsCodeService.verifyCode(registerVo.getPhone(), "register", registerVo.getCode());
|
this.smsCodeService.verifyCode(registerVo.getPhone(), "register", registerVo.getCode());
|
||||||
var exists = merchantRepository.existsByPhone(registerVo.getPhone());
|
var systemUser = this.systemUserService.getAndRegisterByPhone(registerVo.getPhone());
|
||||||
if (exists) {
|
if (systemUser.getMerchant() != null){
|
||||||
return ApiResult.fail("手机号已被注册");
|
throw new Exception("手机号已被注册");
|
||||||
}
|
}
|
||||||
|
|
||||||
var merchant = new Merchant();
|
var merchant = new Merchant();
|
||||||
merchant.setPhone(registerVo.getPhone());
|
merchant.setSystemUser(systemUser);
|
||||||
|
systemUser.setMerchant(merchant);
|
||||||
this.merchantRepository.save(merchant);
|
this.merchantRepository.save(merchant);
|
||||||
return ApiResult.data(
|
return ApiResult.data(
|
||||||
new RegisterDto(
|
new RegisterDto(
|
||||||
merchant.getId(),
|
merchant.getId().toString(),
|
||||||
this.jwtTokenService.generateToken(registerVo.getPhone()),
|
this.jwtTokenService.generateToken(registerVo.getPhone()),
|
||||||
this.refreshTokenService.create(registerVo.getPhone())
|
this.refreshTokenService.create(registerVo.getPhone())
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.error("注册失败", e);
|
log.error("注册失败", e);
|
||||||
return ApiResult.fail("注册失败:" + e.getMessage());
|
throw e;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取当前登录的商家基本信息
|
* 获取当前登录的商家基本信息
|
||||||
*
|
*
|
||||||
* @param merchant @ignore 当前商家
|
* @param loginUser @ignore 当前登录用户
|
||||||
* @return 商家信息
|
* @return 商家信息
|
||||||
*/
|
*/
|
||||||
@GetMapping("/profile")
|
@GetMapping("/profile")
|
||||||
public ApiResult<MerchantDto> getProfile(@AuthenticationPrincipal Merchant merchant) {
|
@Transactional(readOnly = true)
|
||||||
if (merchant == null) {
|
public ApiResult<MerchantDto> getProfile(@AuthenticationPrincipal LoginUser loginUser) {
|
||||||
|
if (loginUser.getMerchantId() == null) {
|
||||||
return ApiResult.fail("商家信息不存在");
|
return ApiResult.fail("商家信息不存在");
|
||||||
}
|
}
|
||||||
return this.merchantService.getById(merchant.getId())
|
return this.merchantRepository.findById(loginUser.getMerchantId())
|
||||||
|
.map(this.merchantMapper::toDto)
|
||||||
.map(ApiResult::data)
|
.map(ApiResult::data)
|
||||||
.orElse(ApiResult.fail("商家信息不存在"));
|
.orElse(ApiResult.fail("商家信息不存在"));
|
||||||
}
|
}
|
||||||
|
|
@ -172,8 +181,8 @@ public class AuthController {
|
||||||
public ApiResult<MerchantDto> updateProfile(@AuthenticationPrincipal Merchant merchant,
|
public ApiResult<MerchantDto> updateProfile(@AuthenticationPrincipal Merchant merchant,
|
||||||
@Valid @RequestBody MerchantUpdateVo merchantUpdateVo) {
|
@Valid @RequestBody MerchantUpdateVo merchantUpdateVo) {
|
||||||
try {
|
try {
|
||||||
var result = this.merchantService.updateMerchant(merchant.getId(), merchantUpdateVo);
|
// TODO : 待完成
|
||||||
return ApiResult.data(result);
|
return ApiResult.data(null);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
return ApiResult.fail(e.getMessage());
|
return ApiResult.fail(e.getMessage());
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,75 +0,0 @@
|
||||||
package com.xjhs.findmemerchant.controller;
|
|
||||||
|
|
||||||
import com.xjhs.findmemerchant.common.ApiResult;
|
|
||||||
import com.xjhs.findmemerchant.dto.MerchantDto;
|
|
||||||
import com.xjhs.findmemerchant.entity.Merchant;
|
|
||||||
import com.xjhs.findmemerchant.service.MerchantService;
|
|
||||||
import com.xjhs.findmemerchant.vo.merchant.MerchantUpdateVo;
|
|
||||||
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")
|
|
||||||
@RequiredArgsConstructor
|
|
||||||
public class MerchantController {
|
|
||||||
private final MerchantService merchantService;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 查询当前登录商家详情
|
|
||||||
*
|
|
||||||
* @param merchant @ignore 当前商家
|
|
||||||
* @return 商家详情信息
|
|
||||||
*/
|
|
||||||
@GetMapping
|
|
||||||
public ApiResult<MerchantDto> getMerchant(@AuthenticationPrincipal Merchant merchant) {
|
|
||||||
return this.merchantService.getById(merchant.getId())
|
|
||||||
.map(ApiResult::data)
|
|
||||||
.orElse(ApiResult.fail("商家信息不存在"));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 更新当前登录商家信息
|
|
||||||
*
|
|
||||||
* @param merchant @ignore 当前商家
|
|
||||||
* @param merchantUpdateVo 更新参数
|
|
||||||
* @return 商家信息
|
|
||||||
*/
|
|
||||||
@PutMapping
|
|
||||||
public ApiResult<MerchantDto> updateMerchant(@AuthenticationPrincipal Merchant merchant,
|
|
||||||
@Valid @RequestBody MerchantUpdateVo merchantUpdateVo) {
|
|
||||||
try {
|
|
||||||
var dto = this.merchantService.updateMerchant(merchant.getId(), merchantUpdateVo);
|
|
||||||
return ApiResult.data(dto);
|
|
||||||
} catch (Exception e) {
|
|
||||||
return ApiResult.fail(e.getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 当前商家验证
|
|
||||||
*
|
|
||||||
* @param merchant @ignore 当前商家
|
|
||||||
* @param merchantVerifyVo 验证参数
|
|
||||||
* @return 商家信息
|
|
||||||
*/
|
|
||||||
@PostMapping("/verify")
|
|
||||||
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);
|
|
||||||
} catch (Exception e) {
|
|
||||||
return ApiResult.fail(e.getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,237 +0,0 @@
|
||||||
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.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")
|
|
||||||
@RequiredArgsConstructor
|
|
||||||
public class StoreController {
|
|
||||||
private final MerchantRepository merchantRepository;
|
|
||||||
private final StoreRepository storeRepository;
|
|
||||||
private final StoreMapper storeMapper;
|
|
||||||
private final BusinessPeriodRepository businessPeriodRepository;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 门店信息(分页查询)
|
|
||||||
*
|
|
||||||
* @param pageVo 分页参数
|
|
||||||
* @param merchant @ignore 当前登录商家
|
|
||||||
* @return 分页数据信息
|
|
||||||
*/
|
|
||||||
@GetMapping
|
|
||||||
@Transactional(readOnly = true)
|
|
||||||
public ApiResult<PageData<StoreDto>> findPage(@AuthenticationPrincipal Merchant merchant, PageVo pageVo) {
|
|
||||||
var pageData = this.storeRepository.findAll(Specification.allOf(
|
|
||||||
JpaSpecs.eq("merchant.id", merchant.getId())
|
|
||||||
), pageVo.getPageable()).map(this.storeMapper::toDto);
|
|
||||||
return ApiResult.page(pageData.getTotalElements(), pageData.getContent());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 创建商家的门店
|
|
||||||
*
|
|
||||||
* @param vo 门店信息
|
|
||||||
* @param merchant @ignore 当前登录的商家
|
|
||||||
* @return 门店信息
|
|
||||||
*/
|
|
||||||
@PostMapping
|
|
||||||
@Transactional(rollbackFor = Exception.class)
|
|
||||||
public ApiResult<StoreDto> create(@AuthenticationPrincipal Merchant merchant,
|
|
||||||
@Valid @RequestBody StoreCreateVo vo) {
|
|
||||||
var store = this.storeMapper.toEntity(vo);
|
|
||||||
merchant.addStore(store);
|
|
||||||
this.storeRepository.save(store);
|
|
||||||
var dto = this.storeMapper.toDto(store);
|
|
||||||
return ApiResult.data(dto);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 查询门店详情
|
|
||||||
*
|
|
||||||
* @param storeId 门店id
|
|
||||||
* @param merchant @ignore 当前登录的商家
|
|
||||||
* @return 门店详情
|
|
||||||
*/
|
|
||||||
@GetMapping("/{storeId}")
|
|
||||||
@Transactional(readOnly = true)
|
|
||||||
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))
|
|
||||||
.map(this.storeMapper::toDto)
|
|
||||||
.map(ApiResult::data)
|
|
||||||
.findFirst()
|
|
||||||
.orElse(ApiResult.fail("门店信息不存在"));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 更新门店信息
|
|
||||||
*
|
|
||||||
* @param storeId 门店id
|
|
||||||
* @param merchant @ignore 当前登录的商家
|
|
||||||
* @param vo 更新对象
|
|
||||||
* @return 门店信息
|
|
||||||
*/
|
|
||||||
@PutMapping("/{storeId}")
|
|
||||||
@Transactional(rollbackFor = Exception.class)
|
|
||||||
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())) {
|
|
||||||
this.storeMapper.updateFromVo(vo, store);
|
|
||||||
this.storeRepository.save(store);
|
|
||||||
return ApiResult.data(this.storeMapper.toDto(store));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return ApiResult.fail("门店信息不存在");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 删除门店
|
|
||||||
*
|
|
||||||
* @param storeId 门店id
|
|
||||||
* @param merchant @ignore 当前登录的商家
|
|
||||||
*/
|
|
||||||
@DeleteMapping("/{storeId}")
|
|
||||||
@Transactional(rollbackFor = Exception.class)
|
|
||||||
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("门店信息不存在"));
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,157 +0,0 @@
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -1,45 +0,0 @@
|
||||||
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
|
|
||||||
*/
|
|
||||||
@JsonSerialize(using = ToStringSerializer.class)
|
|
||||||
private Long id;
|
|
||||||
/**
|
|
||||||
* 手机号码
|
|
||||||
* TODO: 手机号码需要脱敏
|
|
||||||
*/
|
|
||||||
private String phone;
|
|
||||||
/**
|
|
||||||
* 真实姓名
|
|
||||||
*/
|
|
||||||
private String realName;
|
|
||||||
/**
|
|
||||||
* 身份证号(明文)
|
|
||||||
*/
|
|
||||||
private String idCardNo;
|
|
||||||
/**
|
|
||||||
* 认证状态
|
|
||||||
*/
|
|
||||||
private AuthStatus authStatus;
|
|
||||||
/**
|
|
||||||
* 认证状态(说明)
|
|
||||||
*/
|
|
||||||
private String authStatusDesc;
|
|
||||||
/**
|
|
||||||
* 创建时间
|
|
||||||
*/
|
|
||||||
private LocalDateTime createdAt;
|
|
||||||
}
|
|
||||||
|
|
@ -16,8 +16,7 @@ public class RegisterDto {
|
||||||
/**
|
/**
|
||||||
* 商家id
|
* 商家id
|
||||||
*/
|
*/
|
||||||
@JsonSerialize(using = ToStringSerializer.class)
|
private String merchantId;
|
||||||
private Long merchantId;
|
|
||||||
/**
|
/**
|
||||||
* 访问令牌
|
* 访问令牌
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -1,40 +0,0 @@
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
@ -0,0 +1,9 @@
|
||||||
|
package com.xjhs.findmemerchant.dto.merchant;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class MerchantDto {
|
||||||
|
private String id;
|
||||||
|
private String merchantName;
|
||||||
|
}
|
||||||
|
|
@ -1,30 +0,0 @@
|
||||||
package com.xjhs.findmemerchant.dto.store;
|
|
||||||
|
|
||||||
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
|
|
||||||
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
|
|
||||||
import lombok.Data;
|
|
||||||
|
|
||||||
@Data
|
|
||||||
public class BusinessPeriodDto {
|
|
||||||
/**
|
|
||||||
* 门店id
|
|
||||||
*/
|
|
||||||
@JsonSerialize(using = ToStringSerializer.class)
|
|
||||||
private Long storeId;
|
|
||||||
/**
|
|
||||||
* 周几,周天0,...
|
|
||||||
*/
|
|
||||||
private Integer dayOfWeek;
|
|
||||||
/**
|
|
||||||
* 开始营业时间 HH:mm 格式
|
|
||||||
*/
|
|
||||||
private String startTime;
|
|
||||||
/**
|
|
||||||
* 结束营业时间 HH:mm 格式
|
|
||||||
*/
|
|
||||||
private String endTime;
|
|
||||||
/**
|
|
||||||
* 是否启用
|
|
||||||
*/
|
|
||||||
private Boolean enabled;
|
|
||||||
}
|
|
||||||
|
|
@ -1,36 +0,0 @@
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
@ -1,110 +0,0 @@
|
||||||
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;
|
|
||||||
import lombok.Data;
|
|
||||||
|
|
||||||
import java.math.BigDecimal;
|
|
||||||
|
|
||||||
@Data
|
|
||||||
public class StoreDto {
|
|
||||||
/**
|
|
||||||
* 门店id
|
|
||||||
*/
|
|
||||||
@JsonSerialize(using = ToStringSerializer.class)
|
|
||||||
private Long id;
|
|
||||||
/**
|
|
||||||
* 商家id
|
|
||||||
*/
|
|
||||||
@JsonSerialize(using = ToStringSerializer.class)
|
|
||||||
private Long merchantId;
|
|
||||||
/**
|
|
||||||
* 门店名称
|
|
||||||
*/
|
|
||||||
private String name;
|
|
||||||
/**
|
|
||||||
* 门店logo
|
|
||||||
*/
|
|
||||||
private String logo;
|
|
||||||
/**
|
|
||||||
* 联系电话
|
|
||||||
*/
|
|
||||||
private String phone;
|
|
||||||
/**
|
|
||||||
* 省
|
|
||||||
*/
|
|
||||||
private String province;
|
|
||||||
/**
|
|
||||||
* 市
|
|
||||||
*/
|
|
||||||
private String city;
|
|
||||||
/**
|
|
||||||
* 区/县
|
|
||||||
*/
|
|
||||||
private String district;
|
|
||||||
/**
|
|
||||||
* 详细地址
|
|
||||||
*/
|
|
||||||
private String address;
|
|
||||||
/**
|
|
||||||
* 完整地址
|
|
||||||
*/
|
|
||||||
private String fullAddress;
|
|
||||||
|
|
||||||
// TODO: 后续改为 Point location
|
|
||||||
/**
|
|
||||||
* 经度
|
|
||||||
*/
|
|
||||||
private BigDecimal longitude;
|
|
||||||
/**
|
|
||||||
* 纬度
|
|
||||||
*/
|
|
||||||
private BigDecimal latitude;
|
|
||||||
/**
|
|
||||||
* 营业时间描述
|
|
||||||
*/
|
|
||||||
private String businessHours;
|
|
||||||
/**
|
|
||||||
* 营业状态
|
|
||||||
*/
|
|
||||||
private BusinessStatus businessStatus;
|
|
||||||
/**
|
|
||||||
* 营业状态(说明)
|
|
||||||
*/
|
|
||||||
private String businessStatusDesc;
|
|
||||||
/**
|
|
||||||
* 临时打烊原因
|
|
||||||
*/
|
|
||||||
private String tempCloseReason;
|
|
||||||
/**
|
|
||||||
* 临时打烊结束时间
|
|
||||||
*/
|
|
||||||
private String tempCloseUntil;
|
|
||||||
/**
|
|
||||||
* 审核状态
|
|
||||||
*/
|
|
||||||
private StoreAuditStatus auditStatus;
|
|
||||||
/**
|
|
||||||
* 审核状态(说明)
|
|
||||||
*/
|
|
||||||
private String auditStatusDesc;
|
|
||||||
/**
|
|
||||||
* 审核备注
|
|
||||||
*/
|
|
||||||
private String auditRemark;
|
|
||||||
/**
|
|
||||||
* 启用状态
|
|
||||||
*/
|
|
||||||
private CommonStatus status;
|
|
||||||
/**
|
|
||||||
* 启用状态(说明)
|
|
||||||
*/
|
|
||||||
private String statusDesc;
|
|
||||||
/**
|
|
||||||
* 创建时间
|
|
||||||
*/
|
|
||||||
private String createdAt;
|
|
||||||
}
|
|
||||||
|
|
@ -1,137 +0,0 @@
|
||||||
package com.xjhs.findmemerchant.entity;
|
|
||||||
|
|
||||||
import com.xjhs.findmemerchant.common.jpa.AbstractBaseEntity;
|
|
||||||
import com.xjhs.findmemerchant.types.ActivityStatus;
|
|
||||||
import com.xjhs.findmemerchant.types.ActivityType;
|
|
||||||
import jakarta.persistence.*;
|
|
||||||
import lombok.Getter;
|
|
||||||
import lombok.Setter;
|
|
||||||
import org.hibernate.annotations.Comment;
|
|
||||||
|
|
||||||
import java.time.LocalDateTime;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 活动 / 营销活动实体
|
|
||||||
* 对应表:activities
|
|
||||||
*/
|
|
||||||
@Getter
|
|
||||||
@Setter
|
|
||||||
@Entity
|
|
||||||
@Table(
|
|
||||||
name = "activities",
|
|
||||||
indexes = {
|
|
||||||
@Index(name = "idx_activities_merchant_id", columnList = "merchant_id"),
|
|
||||||
@Index(name = "idx_activities_time", columnList = "start_time,end_time"),
|
|
||||||
@Index(name = "idx_activities_status", columnList = "status")
|
|
||||||
}
|
|
||||||
)
|
|
||||||
public class Activity extends AbstractBaseEntity {
|
|
||||||
|
|
||||||
@ManyToOne(fetch = FetchType.LAZY)
|
|
||||||
@JoinColumn(name = "merchant_id")
|
|
||||||
private Merchant merchant;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 活动名称
|
|
||||||
*/
|
|
||||||
@Column(name = "name", length = 100)
|
|
||||||
@Comment("活动名称")
|
|
||||||
private String name;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 活动类型 (1团购 2折扣 3限时优惠)
|
|
||||||
*/
|
|
||||||
@Column(name = "type", length = 15, columnDefinition = "VARCHAR(15)")
|
|
||||||
@Enumerated(EnumType.STRING)
|
|
||||||
@Comment("活动类型")
|
|
||||||
private ActivityType type;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 开始时间
|
|
||||||
*/
|
|
||||||
@Column(name = "start_time")
|
|
||||||
@Comment("开始时间")
|
|
||||||
private LocalDateTime startTime;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 结束时间
|
|
||||||
*/
|
|
||||||
@Column(name = "end_time")
|
|
||||||
@Comment("结束时间")
|
|
||||||
private LocalDateTime endTime;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 库存
|
|
||||||
*/
|
|
||||||
@Column(name = "stock")
|
|
||||||
@Comment("库存总数")
|
|
||||||
private Integer stock = 0;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 已售数量
|
|
||||||
*/
|
|
||||||
@Column(name = "sold_count")
|
|
||||||
@Comment("已售数量")
|
|
||||||
private Integer soldCount = 0;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 库存告警阈值
|
|
||||||
*/
|
|
||||||
@Column(name = "alert_threshold")
|
|
||||||
@Comment("库存告警阈值")
|
|
||||||
private Integer alertThreshold;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 活动状态
|
|
||||||
*/
|
|
||||||
@Column(name = "status", columnDefinition = "VARCHAR(20)")
|
|
||||||
@Enumerated(EnumType.STRING)
|
|
||||||
@Comment("活动状态:0未开始 1进行中 2已结束 3已下架")
|
|
||||||
private ActivityStatus status = ActivityStatus.NOT_STARTED;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// ================= 业务逻辑 =================
|
|
||||||
|
|
||||||
public boolean isOngoing() {
|
|
||||||
var now = LocalDateTime.now();
|
|
||||||
return this.status == ActivityStatus.ONGOING
|
|
||||||
&& now.isAfter(startTime)
|
|
||||||
&& now.isBefore(endTime);
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean hasStock() {
|
|
||||||
return stock != null && soldCount != null && soldCount < stock;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int remainingStock() {
|
|
||||||
if (stock == null || soldCount == null) return 0;
|
|
||||||
return stock - soldCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isLowStock() {
|
|
||||||
return alertThreshold != null && remainingStock() <= alertThreshold;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getTypeText() {
|
|
||||||
var e = this.type;
|
|
||||||
return e != null ? e.getDesc() : "未知";
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getStatusText() {
|
|
||||||
var e = this.status;
|
|
||||||
return e != null ? e.getDesc() : "未知";
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean canEdit() {
|
|
||||||
return this.status == ActivityStatus.NOT_STARTED;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean canOffline() {
|
|
||||||
var s = this.status;
|
|
||||||
return s == ActivityStatus.NOT_STARTED || s == ActivityStatus.ONGOING;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -1,109 +0,0 @@
|
||||||
package com.xjhs.findmemerchant.entity;
|
|
||||||
|
|
||||||
import com.xjhs.findmemerchant.common.jpa.AbstractBaseEntity;
|
|
||||||
import com.xjhs.findmemerchant.types.CommonStatus;
|
|
||||||
import jakarta.persistence.*;
|
|
||||||
import lombok.Getter;
|
|
||||||
import lombok.Setter;
|
|
||||||
import org.hibernate.annotations.Comment;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 商家提现银行卡
|
|
||||||
* 对应表:bank_cards
|
|
||||||
*/
|
|
||||||
@Getter
|
|
||||||
@Setter
|
|
||||||
@Entity
|
|
||||||
@Table(
|
|
||||||
name = "bank_cards",
|
|
||||||
indexes = {
|
|
||||||
@Index(name = "idx_bank_cards_merchant_id", columnList = "merchant_id")
|
|
||||||
}
|
|
||||||
)
|
|
||||||
public class BankCard extends AbstractBaseEntity {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 商家
|
|
||||||
*/
|
|
||||||
@ManyToOne(fetch = FetchType.LAZY)
|
|
||||||
@JoinColumn(name = "merchant_id", insertable = false, updatable = false)
|
|
||||||
private Merchant merchant;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 银行名称
|
|
||||||
*/
|
|
||||||
@Column(name = "bank_name", length = 50)
|
|
||||||
@Comment("银行名称")
|
|
||||||
private String bankName;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 银行代码
|
|
||||||
*/
|
|
||||||
@Column(name = "bank_code", length = 20)
|
|
||||||
@Comment("银行代码")
|
|
||||||
private String bankCode;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 支行名称
|
|
||||||
*/
|
|
||||||
@Column(name = "branch_name", length = 100)
|
|
||||||
@Comment("支行名称")
|
|
||||||
private String branchName;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 银行账号(建议加密存储)
|
|
||||||
*/
|
|
||||||
@Column(name = "account_no", length = 30)
|
|
||||||
@Comment("银行卡号(加密存储)")
|
|
||||||
private String accountNo;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 开户名
|
|
||||||
*/
|
|
||||||
@Column(name = "account_name", length = 50)
|
|
||||||
@Comment("开户名")
|
|
||||||
private String accountName;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 是否默认卡
|
|
||||||
*/
|
|
||||||
@Column(name = "is_default")
|
|
||||||
@Comment("是否默认卡")
|
|
||||||
private Boolean isDefault = false;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 状态:0-禁用 1-启用
|
|
||||||
*/
|
|
||||||
@Column(name = "status",columnDefinition = "VARCHAR(15)",length = 15)
|
|
||||||
@Enumerated(EnumType.STRING)
|
|
||||||
@Comment("状态:0禁用 1启用")
|
|
||||||
private CommonStatus status = CommonStatus.ENABLED;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// ========== 业务方法 ==========
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 脱敏账号,例如:6222****1234
|
|
||||||
*/
|
|
||||||
public String maskAccountNo() {
|
|
||||||
if (accountNo == null || accountNo.length() <= 8) {
|
|
||||||
return accountNo;
|
|
||||||
}
|
|
||||||
return accountNo.substring(0, 4)
|
|
||||||
+ "****"
|
|
||||||
+ accountNo.substring(accountNo.length() - 4);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 是否启用
|
|
||||||
*/
|
|
||||||
public boolean isActive() {
|
|
||||||
return this.status == CommonStatus.ENABLED;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getStatusText() {
|
|
||||||
CommonStatus e = this.status;
|
|
||||||
return e != null ? e.getDesc() : "未知";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,67 +0,0 @@
|
||||||
package com.xjhs.findmemerchant.entity;
|
|
||||||
|
|
||||||
|
|
||||||
import com.xjhs.findmemerchant.common.jpa.json.HashMapJsonConverter;
|
|
||||||
import com.xjhs.findmemerchant.common.jpa.AbstractBaseEntity;
|
|
||||||
import com.xjhs.findmemerchant.types.BusinessLicenseStatus;
|
|
||||||
import jakarta.persistence.*;
|
|
||||||
import lombok.Getter;
|
|
||||||
import lombok.Setter;
|
|
||||||
import org.hibernate.annotations.Comment;
|
|
||||||
|
|
||||||
import java.util.HashMap;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 营业执照资质
|
|
||||||
* 对应表:business_licenses
|
|
||||||
*/
|
|
||||||
@Getter
|
|
||||||
@Setter
|
|
||||||
@Entity
|
|
||||||
@Table(
|
|
||||||
name = "business_licenses",
|
|
||||||
indexes = {
|
|
||||||
@Index(name = "idx_business_licenses_merchant_id", columnList = "merchant_id")
|
|
||||||
}
|
|
||||||
)
|
|
||||||
public class BusinessLicense extends AbstractBaseEntity {
|
|
||||||
|
|
||||||
@ManyToOne(fetch = FetchType.LAZY)
|
|
||||||
@JoinColumn(name = "merchant_id", insertable = false, updatable = false)
|
|
||||||
private Merchant merchant;
|
|
||||||
|
|
||||||
@Column(name = "image_url", length = 500)
|
|
||||||
@Comment("营业执照图片URL")
|
|
||||||
private String imageUrl;
|
|
||||||
|
|
||||||
@Column(name = "company_name", length = 200)
|
|
||||||
@Comment("公司名称(OCR识别)")
|
|
||||||
private String companyName;
|
|
||||||
|
|
||||||
@Column(name = "license_no", length = 50)
|
|
||||||
@Comment("营业执照号(OCR识别)")
|
|
||||||
private String licenseNo;
|
|
||||||
|
|
||||||
@Convert(converter = HashMapJsonConverter.class)
|
|
||||||
@Column(name = "ocr_raw", columnDefinition = "json")
|
|
||||||
@Comment("OCR原始结果")
|
|
||||||
private HashMap<String, Object> ocrRaw;
|
|
||||||
|
|
||||||
@Column(name = "status",length = 15,columnDefinition = "VARCHAR(15)")
|
|
||||||
@Enumerated(EnumType.STRING)
|
|
||||||
@Comment("状态:0待审核 1已通过 2已拒绝")
|
|
||||||
private BusinessLicenseStatus status = BusinessLicenseStatus.PENDING;
|
|
||||||
|
|
||||||
|
|
||||||
// ===== 业务方法 =====
|
|
||||||
|
|
||||||
public boolean isApproved() {
|
|
||||||
return this.status == BusinessLicenseStatus.APPROVED;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public String getStatusText() {
|
|
||||||
var e = this.status;
|
|
||||||
return e != null ? e.getDesc() : "未知";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,81 +0,0 @@
|
||||||
package com.xjhs.findmemerchant.entity;
|
|
||||||
|
|
||||||
import com.xjhs.findmemerchant.common.jpa.AbstractBaseEntity;
|
|
||||||
import jakarta.persistence.*;
|
|
||||||
import lombok.Getter;
|
|
||||||
import lombok.Setter;
|
|
||||||
import org.hibernate.annotations.Comment;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 门店营业时间段
|
|
||||||
* 对应表:business_periods
|
|
||||||
*/
|
|
||||||
@Getter
|
|
||||||
@Setter
|
|
||||||
@Entity
|
|
||||||
@Table(
|
|
||||||
name = "business_periods",
|
|
||||||
indexes = {
|
|
||||||
@Index(name = "idx_business_periods_store_id", columnList = "store_id")
|
|
||||||
}
|
|
||||||
)
|
|
||||||
public class BusinessPeriod extends AbstractBaseEntity {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 门店
|
|
||||||
*/
|
|
||||||
@ManyToOne(fetch = FetchType.LAZY)
|
|
||||||
@JoinColumn(name = "store_id", insertable = false, updatable = false)
|
|
||||||
@Comment("门店Id")
|
|
||||||
private Store store;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 周几:0=周日 ... 6=周六
|
|
||||||
*/
|
|
||||||
@Column(name = "day_of_week")
|
|
||||||
@Comment("周几:0周日 1周一 ... 6周六")
|
|
||||||
private Integer dayOfWeek;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 开始时间,HH:MM
|
|
||||||
*/
|
|
||||||
@Column(name = "start_time", length = 5)
|
|
||||||
@Comment("开始时间,HH:MM")
|
|
||||||
private String startTime;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 结束时间,HH:MM
|
|
||||||
*/
|
|
||||||
@Column(name = "end_time", length = 5)
|
|
||||||
@Comment("结束时间,HH:MM")
|
|
||||||
private String endTime;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 是否启用
|
|
||||||
*/
|
|
||||||
@Column(name = "is_enabled")
|
|
||||||
@Comment("是否启用")
|
|
||||||
private Boolean isEnabled = Boolean.TRUE;
|
|
||||||
|
|
||||||
|
|
||||||
// ========== 业务方法 ==========
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 中文周几,比如:周一
|
|
||||||
*/
|
|
||||||
public String getDayName() {
|
|
||||||
if (dayOfWeek == null) {
|
|
||||||
return "未知";
|
|
||||||
}
|
|
||||||
return switch (dayOfWeek) {
|
|
||||||
case 0 -> "周日";
|
|
||||||
case 1 -> "周一";
|
|
||||||
case 2 -> "周二";
|
|
||||||
case 3 -> "周三";
|
|
||||||
case 4 -> "周四";
|
|
||||||
case 5 -> "周五";
|
|
||||||
case 6 -> "周六";
|
|
||||||
default -> "未知";
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,211 +0,0 @@
|
||||||
package com.xjhs.findmemerchant.entity;
|
|
||||||
|
|
||||||
import com.xjhs.findmemerchant.common.jpa.AbstractBaseEntity;
|
|
||||||
import com.xjhs.findmemerchant.types.CouponStatus;
|
|
||||||
import com.xjhs.findmemerchant.types.CouponType;
|
|
||||||
import jakarta.persistence.*;
|
|
||||||
import lombok.Getter;
|
|
||||||
import lombok.Setter;
|
|
||||||
import org.hibernate.annotations.Comment;
|
|
||||||
|
|
||||||
import java.math.BigDecimal;
|
|
||||||
import java.time.LocalDateTime;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 优惠券模板实体
|
|
||||||
* 对应表:coupons
|
|
||||||
*/
|
|
||||||
@Getter
|
|
||||||
@Setter
|
|
||||||
@Entity
|
|
||||||
@Table(
|
|
||||||
name = "coupons",
|
|
||||||
indexes = {
|
|
||||||
@Index(name = "idx_coupons_merchant_id", columnList = "merchant_id"),
|
|
||||||
@Index(name = "idx_coupons_status", columnList = "status"),
|
|
||||||
@Index(name = "idx_coupons_gift_product_id", columnList = "gift_product_id")
|
|
||||||
}
|
|
||||||
)
|
|
||||||
public class Coupon extends AbstractBaseEntity {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 优惠券名称
|
|
||||||
*/
|
|
||||||
@Column(name = "name", length = 100)
|
|
||||||
@Comment("优惠券名称")
|
|
||||||
private String name;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 优惠券类型:1-折扣券 2-满减券 3-现金券 4-赠品券
|
|
||||||
*/
|
|
||||||
@Column(name = "type",length = 15,columnDefinition = "VARCHAR(15)")
|
|
||||||
@Comment("优惠券类型:1折扣券 2满减券 3现金券 4赠品券")
|
|
||||||
private CouponType type;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 折扣率 0.01-0.99,decimal(3,2)
|
|
||||||
*/
|
|
||||||
@Column(name = "discount_rate", precision = 3, scale = 2)
|
|
||||||
@Comment("折扣率 0.01-0.99")
|
|
||||||
private BigDecimal discountRate;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 满减门槛,decimal(10,2)
|
|
||||||
*/
|
|
||||||
@Column(name = "min_amount", precision = 10, scale = 2)
|
|
||||||
@Comment("满减门槛")
|
|
||||||
private BigDecimal minAmount;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 减免金额,decimal(10,2)
|
|
||||||
*/
|
|
||||||
@Column(name = "reduce_amount", precision = 10, scale = 2)
|
|
||||||
@Comment("减免金额")
|
|
||||||
private BigDecimal reduceAmount;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 赠品商品ID
|
|
||||||
*/
|
|
||||||
@Column(name = "gift_product_id")
|
|
||||||
@Comment("赠品商品ID")
|
|
||||||
private Long giftProductId;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 赠品数量,默认 1
|
|
||||||
*/
|
|
||||||
@Column(name = "gift_quantity")
|
|
||||||
@Comment("赠品数量")
|
|
||||||
private Integer giftQuantity = 1;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 发放总量
|
|
||||||
*/
|
|
||||||
@Column(name = "total_count")
|
|
||||||
@Comment("发放总量")
|
|
||||||
private Integer totalCount;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 已领取数量
|
|
||||||
*/
|
|
||||||
@Column(name = "claimed_count")
|
|
||||||
@Comment("已领取数量")
|
|
||||||
private Integer claimedCount = 0;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 每人限领数量,0 表示不限
|
|
||||||
*/
|
|
||||||
@Column(name = "per_user_limit")
|
|
||||||
@Comment("每人限领数量,0表示不限")
|
|
||||||
private Integer perUserLimit = 1;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 领取后有效天数
|
|
||||||
*/
|
|
||||||
@Column(name = "valid_days")
|
|
||||||
@Comment("领取后有效天数")
|
|
||||||
private Integer validDays;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 活动开始时间
|
|
||||||
*/
|
|
||||||
@Column(name = "start_time")
|
|
||||||
@Comment("活动开始时间")
|
|
||||||
private LocalDateTime startTime;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 活动结束时间
|
|
||||||
*/
|
|
||||||
@Column(name = "end_time")
|
|
||||||
@Comment("活动结束时间")
|
|
||||||
private LocalDateTime endTime;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 使用规则
|
|
||||||
*/
|
|
||||||
@Column(name = "rules", columnDefinition = "text")
|
|
||||||
@Comment("使用规则")
|
|
||||||
private String rules;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 状态:0-下架 1-进行中 2-已结束
|
|
||||||
*/
|
|
||||||
@Column(name = "status",columnDefinition = "VARCHAR(15)",length = 15)
|
|
||||||
@Comment("状态:0下架 1进行中 2已结束")
|
|
||||||
private CouponStatus status = CouponStatus.ONLINE;
|
|
||||||
|
|
||||||
|
|
||||||
// ================= 关联关系 =================
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 所属商家
|
|
||||||
*/
|
|
||||||
@ManyToOne(fetch = FetchType.LAZY)
|
|
||||||
@JoinColumn(name = "merchant_id", insertable = false, updatable = false)
|
|
||||||
private Merchant merchant;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 可用门店关联
|
|
||||||
*/
|
|
||||||
@OneToMany(mappedBy = "coupon", fetch = FetchType.LAZY)
|
|
||||||
private List<CouponStore> stores;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 所有券码
|
|
||||||
*/
|
|
||||||
@OneToMany(mappedBy = "coupon", fetch = FetchType.LAZY)
|
|
||||||
private List<CouponCode> codes;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 赠品商品
|
|
||||||
*/
|
|
||||||
@ManyToOne(fetch = FetchType.LAZY)
|
|
||||||
@JoinColumn(name = "gift_product_id", insertable = false, updatable = false)
|
|
||||||
private Product giftProduct;
|
|
||||||
|
|
||||||
// ================= 业务方法 =================
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 是否当前有效(进行中 + 时间范围内)
|
|
||||||
*/
|
|
||||||
public boolean isActive() {
|
|
||||||
LocalDateTime now = LocalDateTime.now();
|
|
||||||
return this.status == CouponStatus.ONLINE
|
|
||||||
&& now.isAfter(startTime)
|
|
||||||
&& now.isBefore(endTime);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 是否还有库存可领取
|
|
||||||
*/
|
|
||||||
public boolean hasStock() {
|
|
||||||
return claimedCount != null && totalCount != null && claimedCount < totalCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 剩余可领取数量
|
|
||||||
*/
|
|
||||||
public int remainingCount() {
|
|
||||||
if (totalCount == null || claimedCount == null) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return totalCount - claimedCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 优惠券类型文案
|
|
||||||
*/
|
|
||||||
public String getTypeText() {
|
|
||||||
CouponType typeEnum = this.type;
|
|
||||||
return typeEnum != null ? typeEnum.getDesc() : "未知";
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 是否为赠品券
|
|
||||||
*/
|
|
||||||
public boolean isGiftCoupon() {
|
|
||||||
return this.type == CouponType.GIFT;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -1,172 +0,0 @@
|
||||||
package com.xjhs.findmemerchant.entity;
|
|
||||||
|
|
||||||
import com.xjhs.findmemerchant.common.jpa.AbstractBaseEntity;
|
|
||||||
import com.xjhs.findmemerchant.types.CouponCodeStatus;
|
|
||||||
import jakarta.persistence.*;
|
|
||||||
import lombok.Getter;
|
|
||||||
import lombok.Setter;
|
|
||||||
import org.hibernate.annotations.Comment;
|
|
||||||
|
|
||||||
import java.time.LocalDateTime;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 优惠券码实例
|
|
||||||
* 对应表:coupon_codes
|
|
||||||
*/
|
|
||||||
@Getter
|
|
||||||
@Setter
|
|
||||||
@Entity
|
|
||||||
@Table(
|
|
||||||
name = "coupon_codes",
|
|
||||||
indexes = {
|
|
||||||
@Index(name = "idx_coupon_codes_coupon_id", columnList = "coupon_id"),
|
|
||||||
@Index(name = "idx_coupon_codes_member_id", columnList = "member_id"),
|
|
||||||
@Index(name = "idx_coupon_codes_status", columnList = "status")
|
|
||||||
},
|
|
||||||
uniqueConstraints = {
|
|
||||||
@UniqueConstraint(name = "uk_coupon_codes_code", columnNames = "code")
|
|
||||||
}
|
|
||||||
)
|
|
||||||
public class CouponCode extends AbstractBaseEntity {
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 券码
|
|
||||||
*/
|
|
||||||
@Column(name = "code", length = 32)
|
|
||||||
@Comment("优惠券码")
|
|
||||||
private String code;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 状态:0-未领取 1-已领取 2-已核销 3-已过期
|
|
||||||
*/
|
|
||||||
@Column(name = "status",columnDefinition = "VARCHAR(20)",length = 20)
|
|
||||||
@Comment("状态:0未领取 1已领取 2已核销 3已过期")
|
|
||||||
private CouponCodeStatus status = CouponCodeStatus.UNCLAIMED;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 领取时间
|
|
||||||
*/
|
|
||||||
@Column(name = "claimed_at")
|
|
||||||
@Comment("领取时间")
|
|
||||||
private LocalDateTime claimedAt;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 有效期至
|
|
||||||
*/
|
|
||||||
@Column(name = "valid_until")
|
|
||||||
@Comment("有效期至")
|
|
||||||
private LocalDateTime validUntil;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 核销时间
|
|
||||||
*/
|
|
||||||
@Column(name = "verified_at")
|
|
||||||
@Comment("核销时间")
|
|
||||||
private LocalDateTime verifiedAt;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 核销人ID(员工)
|
|
||||||
*/
|
|
||||||
@Column(name = "verified_by")
|
|
||||||
@Comment("核销人ID(员工)")
|
|
||||||
private Long verifiedBy;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 核销门店ID
|
|
||||||
*/
|
|
||||||
@Column(name = "verify_store_id")
|
|
||||||
@Comment("核销门店ID")
|
|
||||||
private Long verifyStoreId;
|
|
||||||
|
|
||||||
|
|
||||||
// =============== 关联关系 ===============
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 所属优惠券模板
|
|
||||||
*/
|
|
||||||
@ManyToOne(fetch = FetchType.LAZY)
|
|
||||||
@JoinColumn(name = "coupon_id", insertable = false, updatable = false)
|
|
||||||
private Coupon coupon;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 会员
|
|
||||||
*/
|
|
||||||
@ManyToOne(fetch = FetchType.LAZY)
|
|
||||||
@JoinColumn(name = "member_id", insertable = false, updatable = false)
|
|
||||||
private Member member;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 核销员工
|
|
||||||
*/
|
|
||||||
@ManyToOne(fetch = FetchType.LAZY)
|
|
||||||
@JoinColumn(name = "verified_by", insertable = false, updatable = false)
|
|
||||||
private Employee verifier;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 核销门店
|
|
||||||
*/
|
|
||||||
@ManyToOne(fetch = FetchType.LAZY)
|
|
||||||
@JoinColumn(name = "verify_store_id", insertable = false, updatable = false)
|
|
||||||
private Store verifyStore;
|
|
||||||
|
|
||||||
// =============== 业务方法 ===============
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 是否已领取
|
|
||||||
*/
|
|
||||||
public boolean isClaimed() {
|
|
||||||
return this.status != null &&
|
|
||||||
this.status.ordinal() >= CouponCodeStatus.CLAIMED.ordinal();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 是否已核销
|
|
||||||
*/
|
|
||||||
public boolean isVerified() {
|
|
||||||
return this.status == CouponCodeStatus.VERIFIED;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 是否已过期
|
|
||||||
*/
|
|
||||||
public boolean isExpired() {
|
|
||||||
CouponCodeStatus statusEnum = this.status;
|
|
||||||
if (statusEnum == CouponCodeStatus.EXPIRED) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (validUntil != null && LocalDateTime.now().isAfter(validUntil)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 是否可核销
|
|
||||||
*/
|
|
||||||
public boolean canVerify() {
|
|
||||||
return this.status == CouponCodeStatus.CLAIMED && !isExpired();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 状态文案
|
|
||||||
*/
|
|
||||||
public String getStatusText() {
|
|
||||||
CouponCodeStatus statusEnum = this.status;
|
|
||||||
return statusEnum != null ? statusEnum.getDesc() : "未知";
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 脱敏券码,例如:ABC***XYZ
|
|
||||||
*/
|
|
||||||
public String maskCode() {
|
|
||||||
if (code == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
if (code.length() <= 6) {
|
|
||||||
return code;
|
|
||||||
}
|
|
||||||
return code.substring(0, 3) + "***" + code.substring(code.length() - 3);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -1,40 +0,0 @@
|
||||||
package com.xjhs.findmemerchant.entity;
|
|
||||||
|
|
||||||
import com.xjhs.findmemerchant.common.jpa.AbstractBaseEntity;
|
|
||||||
import jakarta.persistence.*;
|
|
||||||
import lombok.Getter;
|
|
||||||
import lombok.Setter;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 优惠券与门店的关联关系
|
|
||||||
* 对应表:coupon_stores
|
|
||||||
*/
|
|
||||||
@Getter
|
|
||||||
@Setter
|
|
||||||
@Entity
|
|
||||||
@Table(
|
|
||||||
name = "coupon_stores",
|
|
||||||
uniqueConstraints = {
|
|
||||||
@UniqueConstraint(
|
|
||||||
name = "idx_coupon_store",
|
|
||||||
columnNames = {"coupon_id", "store_id"}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
)
|
|
||||||
public class CouponStore extends AbstractBaseEntity {
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 优惠券
|
|
||||||
*/
|
|
||||||
@ManyToOne(fetch = FetchType.LAZY)
|
|
||||||
@JoinColumn(name = "coupon_id", insertable = false, updatable = false)
|
|
||||||
private Coupon coupon;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 门店
|
|
||||||
*/
|
|
||||||
@ManyToOne(fetch = FetchType.LAZY)
|
|
||||||
@JoinColumn(name = "store_id", insertable = false, updatable = false)
|
|
||||||
private Store store;
|
|
||||||
}
|
|
||||||
|
|
@ -1,95 +0,0 @@
|
||||||
package com.xjhs.findmemerchant.entity;
|
|
||||||
|
|
||||||
import com.xjhs.findmemerchant.common.jpa.AbstractBaseEntity;
|
|
||||||
import com.xjhs.findmemerchant.types.CommonStatus;
|
|
||||||
import jakarta.persistence.*;
|
|
||||||
import lombok.Getter;
|
|
||||||
import lombok.Setter;
|
|
||||||
import org.hibernate.annotations.Comment;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 员工实体
|
|
||||||
* 对应表:employees
|
|
||||||
*/
|
|
||||||
@Getter
|
|
||||||
@Setter
|
|
||||||
@Entity
|
|
||||||
@Table(
|
|
||||||
name = "employees",
|
|
||||||
indexes = {
|
|
||||||
@Index(name = "idx_employees_merchant_id", columnList = "merchant_id"),
|
|
||||||
@Index(name = "idx_employees_store_id", columnList = "store_id"),
|
|
||||||
@Index(name = "idx_employees_role_id", columnList = "role_id"),
|
|
||||||
@Index(name = "idx_employees_phone", columnList = "phone")
|
|
||||||
}
|
|
||||||
)
|
|
||||||
public class Employee extends AbstractBaseEntity {
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 手机号
|
|
||||||
*/
|
|
||||||
@Column(name = "phone", length = 11)
|
|
||||||
@Comment("手机号")
|
|
||||||
private String phone;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 员工姓名
|
|
||||||
*/
|
|
||||||
@Column(name = "name", length = 50)
|
|
||||||
@Comment("员工姓名")
|
|
||||||
private String name;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 状态:0-禁用 1-启用
|
|
||||||
*/
|
|
||||||
@Column(name = "status",columnDefinition = "VARCHAR(15)",length = 15)
|
|
||||||
@Comment("状态")
|
|
||||||
private CommonStatus status = CommonStatus.ENABLED;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// ===== 关联关系 =====
|
|
||||||
/**
|
|
||||||
* 门店
|
|
||||||
*/
|
|
||||||
@ManyToOne(fetch = FetchType.LAZY)
|
|
||||||
@JoinColumn(name = "store_id", insertable = false, updatable = false)
|
|
||||||
private Store store;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 角色
|
|
||||||
*/
|
|
||||||
@ManyToOne(fetch = FetchType.LAZY)
|
|
||||||
@JoinColumn(name = "role_id", insertable = false, updatable = false)
|
|
||||||
private Role role;
|
|
||||||
|
|
||||||
// ===== 业务方法 =====
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 是否为启用状态
|
|
||||||
*/
|
|
||||||
public boolean isActive() {
|
|
||||||
return this.status == CommonStatus.ENABLED;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 状态文案
|
|
||||||
*/
|
|
||||||
public String getStatusText() {
|
|
||||||
CommonStatus e = this.status;
|
|
||||||
return e != null ? e.getDesc() : "未知";
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 返回脱敏手机号,例如:138****1234
|
|
||||||
*/
|
|
||||||
public String maskPhone() {
|
|
||||||
if (phone == null || phone.length() != 11) {
|
|
||||||
return phone;
|
|
||||||
}
|
|
||||||
return phone.substring(0, 3) + "****" + phone.substring(7);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,90 +0,0 @@
|
||||||
package com.xjhs.findmemerchant.entity;
|
|
||||||
|
|
||||||
import com.xjhs.findmemerchant.common.jpa.json.HashMapJsonConverter;
|
|
||||||
import com.xjhs.findmemerchant.common.jpa.AbstractBaseEntity;
|
|
||||||
import com.xjhs.findmemerchant.types.HealthCertificateStatus;
|
|
||||||
import jakarta.persistence.*;
|
|
||||||
import lombok.Getter;
|
|
||||||
import lombok.Setter;
|
|
||||||
import org.hibernate.annotations.Comment;
|
|
||||||
|
|
||||||
import java.time.LocalDateTime;
|
|
||||||
import java.util.HashMap;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 健康证资质
|
|
||||||
* 对应表:health_certificates
|
|
||||||
*/
|
|
||||||
@Getter
|
|
||||||
@Setter
|
|
||||||
@Entity
|
|
||||||
@Table(
|
|
||||||
name = "health_certificates",
|
|
||||||
indexes = {
|
|
||||||
@Index(name = "idx_health_certificates_store_id", columnList = "store_id"),
|
|
||||||
@Index(name = "idx_health_certificates_employee_id", columnList = "employee_id")
|
|
||||||
}
|
|
||||||
)
|
|
||||||
public class HealthCertificate extends AbstractBaseEntity {
|
|
||||||
|
|
||||||
@Column(name = "image_url", length = 500)
|
|
||||||
@Comment("健康证图片URL")
|
|
||||||
private String imageUrl;
|
|
||||||
|
|
||||||
@Column(name = "holder_name", length = 50)
|
|
||||||
@Comment("持证人姓名(OCR识别)")
|
|
||||||
private String holderName;
|
|
||||||
|
|
||||||
@Column(name = "valid_until")
|
|
||||||
@Comment("证件有效期至(OCR识别)")
|
|
||||||
private LocalDateTime validUntil;
|
|
||||||
|
|
||||||
@Column(name = "issuer", length = 100)
|
|
||||||
@Comment("签发机构(OCR识别)")
|
|
||||||
private String issuer;
|
|
||||||
|
|
||||||
@Convert(converter = HashMapJsonConverter.class)
|
|
||||||
@Column(name = "ocr_raw", columnDefinition = "json")
|
|
||||||
@Comment("OCR原始结果")
|
|
||||||
private HashMap<String, Object> ocrRaw;
|
|
||||||
|
|
||||||
@Column(name = "status",columnDefinition = "VARCHAR(20)",length = 20)
|
|
||||||
@Comment("状态:0待审核 1有效 2过期")
|
|
||||||
private HealthCertificateStatus status = HealthCertificateStatus.PENDING;
|
|
||||||
|
|
||||||
|
|
||||||
@ManyToOne(fetch = FetchType.LAZY)
|
|
||||||
@JoinColumn(name = "store_id", insertable = false, updatable = false)
|
|
||||||
private Store store;
|
|
||||||
|
|
||||||
@ManyToOne(fetch = FetchType.LAZY)
|
|
||||||
@JoinColumn(name = "employee_id", insertable = false, updatable = false)
|
|
||||||
private Employee employee;
|
|
||||||
|
|
||||||
// ===== 业务方法 =====
|
|
||||||
|
|
||||||
public boolean isValid() {
|
|
||||||
if (getStatusEnum() != HealthCertificateStatus.VALID) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (validUntil != null && LocalDateTime.now().isAfter(validUntil)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isExpired() {
|
|
||||||
if (validUntil == null) return false;
|
|
||||||
return LocalDateTime.now().isAfter(validUntil);
|
|
||||||
}
|
|
||||||
|
|
||||||
public HealthCertificateStatus getStatusEnum() {
|
|
||||||
return this.status;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public String getStatusText() {
|
|
||||||
var e = getStatusEnum();
|
|
||||||
return e != null ? e.getDesc() : "未知";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,127 +0,0 @@
|
||||||
package com.xjhs.findmemerchant.entity;
|
|
||||||
|
|
||||||
import com.xjhs.findmemerchant.common.jpa.AbstractBaseEntity;
|
|
||||||
import jakarta.persistence.*;
|
|
||||||
import lombok.Getter;
|
|
||||||
import lombok.Setter;
|
|
||||||
import org.hibernate.annotations.Comment;
|
|
||||||
|
|
||||||
import java.math.BigDecimal;
|
|
||||||
import java.time.LocalDateTime;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 会员实体(C 端用户)
|
|
||||||
* 对应表:members
|
|
||||||
*/
|
|
||||||
@Getter
|
|
||||||
@Setter
|
|
||||||
@Entity
|
|
||||||
@Table(
|
|
||||||
name = "members",
|
|
||||||
indexes = {
|
|
||||||
@Index(name = "idx_members_phone", columnList = "phone")
|
|
||||||
},
|
|
||||||
uniqueConstraints = {
|
|
||||||
@UniqueConstraint(
|
|
||||||
name = "idx_merchant_phone",
|
|
||||||
columnNames = {"merchant_id", "phone"}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
)
|
|
||||||
public class Member extends AbstractBaseEntity {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 手机号
|
|
||||||
*/
|
|
||||||
@Column(name = "phone", length = 11)
|
|
||||||
@Comment("手机号")
|
|
||||||
private String phone;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 昵称
|
|
||||||
*/
|
|
||||||
@Column(name = "nickname", length = 50)
|
|
||||||
@Comment("昵称")
|
|
||||||
private String nickname;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 头像地址
|
|
||||||
*/
|
|
||||||
@Column(name = "avatar", length = 500)
|
|
||||||
@Comment("头像URL")
|
|
||||||
private String avatar;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 累计订单数
|
|
||||||
*/
|
|
||||||
@Column(name = "total_orders")
|
|
||||||
@Comment("累计订单数")
|
|
||||||
private Integer totalOrders = 0;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 累计消费金额
|
|
||||||
*/
|
|
||||||
@Column(name = "total_amount", precision = 12, scale = 2)
|
|
||||||
@Comment("累计消费金额")
|
|
||||||
private BigDecimal totalAmount = BigDecimal.ZERO;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 最后一次下单时间
|
|
||||||
*/
|
|
||||||
@Column(name = "last_order_at")
|
|
||||||
@Comment("最后下单时间")
|
|
||||||
private LocalDateTime lastOrderAt;
|
|
||||||
|
|
||||||
// ============ 关联关系 ============
|
|
||||||
/**
|
|
||||||
* 商家
|
|
||||||
*/
|
|
||||||
@ManyToOne(fetch = FetchType.LAZY)
|
|
||||||
@JoinColumn(name = "merchant_id", insertable = false, updatable = false)
|
|
||||||
private Merchant merchant;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 拥有的券码
|
|
||||||
*/
|
|
||||||
@OneToMany(mappedBy = "member", fetch = FetchType.LAZY)
|
|
||||||
private List<CouponCode> couponCodes;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 订单列表
|
|
||||||
*/
|
|
||||||
@OneToMany(mappedBy = "member", fetch = FetchType.LAZY)
|
|
||||||
private List<Order> orders;
|
|
||||||
|
|
||||||
// ============ 业务方法 ============
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 返回脱敏手机号,例如:138****1234
|
|
||||||
*/
|
|
||||||
public String maskPhone() {
|
|
||||||
if (phone == null || phone.length() != 11) {
|
|
||||||
return phone;
|
|
||||||
}
|
|
||||||
return phone.substring(0, 3) + "****" + phone.substring(7);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 展示用名称:优先昵称,否则使用脱敏手机号
|
|
||||||
*/
|
|
||||||
public String getDisplayName() {
|
|
||||||
if (nickname != null && !nickname.isBlank()) {
|
|
||||||
return nickname;
|
|
||||||
}
|
|
||||||
return maskPhone();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 返回头像URL,若为空则返回默认头像
|
|
||||||
*/
|
|
||||||
public String getAvatarOrDefault() {
|
|
||||||
if (avatar != null && !avatar.isBlank()) {
|
|
||||||
return avatar;
|
|
||||||
}
|
|
||||||
return "/static/default-avatar.png";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,147 +1,27 @@
|
||||||
package com.xjhs.findmemerchant.entity;
|
package com.xjhs.findmemerchant.entity;
|
||||||
|
|
||||||
|
|
||||||
import com.xjhs.findmemerchant.common.jpa.AbstractBaseEntity;
|
import com.xjhs.findmemerchant.common.jpa.AbstractBaseEntity;
|
||||||
import com.xjhs.findmemerchant.types.AuthStatus;
|
import com.xjhs.findmemerchant.system.entity.SystemUser;
|
||||||
import com.xjhs.findmemerchant.types.CommonStatus;
|
import jakarta.persistence.Entity;
|
||||||
import jakarta.persistence.*;
|
import jakarta.persistence.JoinColumn;
|
||||||
import lombok.Getter;
|
import jakarta.persistence.OneToOne;
|
||||||
import lombok.Setter;
|
import jakarta.persistence.Table;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
import org.hibernate.annotations.Comment;
|
import org.hibernate.annotations.Comment;
|
||||||
|
|
||||||
import java.util.List;
|
@EqualsAndHashCode(callSuper = true)
|
||||||
|
@Data
|
||||||
/**
|
|
||||||
* 商家实体
|
|
||||||
* 对应表:merchants
|
|
||||||
*/
|
|
||||||
@Getter
|
|
||||||
@Setter
|
|
||||||
@Entity
|
@Entity
|
||||||
@Table(
|
@Table
|
||||||
name = "merchants",
|
@Comment("商户信息表")
|
||||||
indexes = {
|
|
||||||
@Index(name = "idx_merchants_auth_status", columnList = "auth_status"),
|
|
||||||
@Index(name = "idx_merchants_status", columnList = "status")
|
|
||||||
},
|
|
||||||
uniqueConstraints = {
|
|
||||||
@UniqueConstraint(name = "uk_merchant_phone", columnNames = "phone")
|
|
||||||
}
|
|
||||||
)
|
|
||||||
public class Merchant extends AbstractBaseEntity {
|
public class Merchant extends AbstractBaseEntity {
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 登录手机号
|
* 用户信息
|
||||||
*/
|
*/
|
||||||
@Column(name = "phone", length = 11)
|
@OneToOne
|
||||||
@Comment("手机号")
|
@JoinColumn(name = "user_id")
|
||||||
private String phone;
|
@Comment("关联的用户信息")
|
||||||
|
private SystemUser systemUser;
|
||||||
|
|
||||||
/**
|
|
||||||
* 登录密码Hash
|
|
||||||
*/
|
|
||||||
@Column(name = "password_hash", length = 255)
|
|
||||||
@Comment("密码Hash")
|
|
||||||
private String passwordHash;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 真实姓名
|
|
||||||
*/
|
|
||||||
@Column(name = "real_name", length = 50)
|
|
||||||
@Comment("真实姓名")
|
|
||||||
private String realName;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 身份证号(明文)——不入库
|
|
||||||
*/
|
|
||||||
@Transient
|
|
||||||
private String idCardNo;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 身份证加密存储
|
|
||||||
*/
|
|
||||||
@Column(name = "id_card_encrypted", length = 255)
|
|
||||||
@Comment("身份证加密存储")
|
|
||||||
private String idCardEncrypted;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 认证状态
|
|
||||||
*/
|
|
||||||
@Column(name = "auth_status",length = 20,columnDefinition = "VARCHAR(20)")
|
|
||||||
@Comment("认证状态")
|
|
||||||
@Enumerated(EnumType.STRING)
|
|
||||||
private AuthStatus authStatus = AuthStatus.NOT_VERIFIED;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 账户状态
|
|
||||||
*/
|
|
||||||
@Column(name = "status",length = 20,columnDefinition = "VARCHAR(20)")
|
|
||||||
@Comment("账户状态")
|
|
||||||
@Enumerated(EnumType.STRING)
|
|
||||||
private CommonStatus status = CommonStatus.ENABLED;
|
|
||||||
|
|
||||||
// ========== 关联关系 ==========
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 门店列表
|
|
||||||
*/
|
|
||||||
@OneToMany(mappedBy = "merchant", fetch = FetchType.LAZY, cascade = CascadeType.ALL, orphanRemoval = true)
|
|
||||||
private List<Store> stores;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 添加一个门店
|
|
||||||
* @param store 门店信息
|
|
||||||
*/
|
|
||||||
public void addStore(Store store) {
|
|
||||||
store.setMerchant(this);
|
|
||||||
this.stores.add(store);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 营业执照
|
|
||||||
*/
|
|
||||||
@OneToOne(fetch = FetchType.LAZY)
|
|
||||||
@JoinColumn(name = "id", referencedColumnName = "merchant_id", insertable = false, updatable = false)
|
|
||||||
private BusinessLicense businessLicense;
|
|
||||||
|
|
||||||
// ========== 业务方法 ==========
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 是否已完成实名认证
|
|
||||||
*/
|
|
||||||
public boolean isAuthenticated() {
|
|
||||||
return getAuthStatusEnum() == AuthStatus.VERIFIED;
|
|
||||||
}
|
|
||||||
|
|
||||||
public AuthStatus getAuthStatusEnum() {
|
|
||||||
return this.authStatus;
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* 是否启用
|
|
||||||
*/
|
|
||||||
public boolean isActive() {
|
|
||||||
return getStatusEnum() == CommonStatus.ENABLED;
|
|
||||||
}
|
|
||||||
|
|
||||||
public CommonStatus getStatusEnum() {
|
|
||||||
return this.status;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 手机脱敏
|
|
||||||
*/
|
|
||||||
public String maskPhone() {
|
|
||||||
if (phone == null || phone.length() != 11) return phone;
|
|
||||||
return phone.substring(0, 3) + "****" + phone.substring(7);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 身份证脱敏
|
|
||||||
*/
|
|
||||||
public String maskIdCard() {
|
|
||||||
if (idCardNo == null || idCardNo.length() != 18) return idCardNo;
|
|
||||||
return idCardNo.substring(0, 3) + "***********" + idCardNo.substring(14);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,122 +0,0 @@
|
||||||
package com.xjhs.findmemerchant.entity;
|
|
||||||
|
|
||||||
import com.xjhs.findmemerchant.common.jpa.AbstractBaseEntity;
|
|
||||||
import com.xjhs.findmemerchant.types.MessageType;
|
|
||||||
import jakarta.persistence.*;
|
|
||||||
import lombok.Getter;
|
|
||||||
import lombok.Setter;
|
|
||||||
import org.hibernate.annotations.Comment;
|
|
||||||
|
|
||||||
import java.time.LocalDateTime;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 消息实体
|
|
||||||
* 对应表:messages
|
|
||||||
*/
|
|
||||||
@Getter
|
|
||||||
@Setter
|
|
||||||
@Entity
|
|
||||||
@Table(
|
|
||||||
name = "messages",
|
|
||||||
indexes = {
|
|
||||||
@Index(name = "idx_messages_merchant", columnList = "merchant_id"),
|
|
||||||
@Index(name = "idx_messages_type_read", columnList = "merchant_id,type,is_read")
|
|
||||||
}
|
|
||||||
)
|
|
||||||
public class Message extends AbstractBaseEntity {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 消息类型:1-系统通知 2-活动提醒 3-私信
|
|
||||||
*/
|
|
||||||
@Column(name = "type",columnDefinition = "VARCHAR(20)",length = 20)
|
|
||||||
@Enumerated(EnumType.STRING)
|
|
||||||
@Comment("消息类型:1系统通知 2活动提醒 3私信")
|
|
||||||
private MessageType type;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 标题
|
|
||||||
*/
|
|
||||||
@Column(name = "title", length = 200)
|
|
||||||
@Comment("消息标题")
|
|
||||||
private String title;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 内容
|
|
||||||
*/
|
|
||||||
@Column(name = "content", columnDefinition = "text")
|
|
||||||
@Comment("消息内容")
|
|
||||||
private String content;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 是否已读:0-未读 1-已读
|
|
||||||
*/
|
|
||||||
@Column(name = "is_read")
|
|
||||||
@Comment("是否已读:0未读 1已读")
|
|
||||||
private Boolean isRead = false;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 创建时间
|
|
||||||
*/
|
|
||||||
@Column(name = "created_at")
|
|
||||||
@Comment("创建时间")
|
|
||||||
private LocalDateTime createdAt;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 阅读时间
|
|
||||||
*/
|
|
||||||
@Column(name = "read_at")
|
|
||||||
@Comment("阅读时间")
|
|
||||||
private LocalDateTime readAt;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 商家
|
|
||||||
*/
|
|
||||||
@ManyToOne(fetch = FetchType.LAZY)
|
|
||||||
@JoinColumn(name = "merchant_id", insertable = false, updatable = false)
|
|
||||||
private Merchant merchant;
|
|
||||||
|
|
||||||
// ========== 业务方法 ==========
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 标记为已读
|
|
||||||
*/
|
|
||||||
public void markAsRead() {
|
|
||||||
this.isRead = true;
|
|
||||||
this.readAt = LocalDateTime.now();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 是否未读
|
|
||||||
*/
|
|
||||||
public boolean isUnread() {
|
|
||||||
return this.isRead != null && !this.isRead;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 消息类型文案
|
|
||||||
*/
|
|
||||||
public String getTypeText() {
|
|
||||||
MessageType t = getTypeEnum();
|
|
||||||
return t != null ? t.getDesc() : "未知";
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 内容摘要,最多100字符
|
|
||||||
*/
|
|
||||||
public String getSummary() {
|
|
||||||
if (content == null) {
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
if (content.length() <= 100) {
|
|
||||||
return content;
|
|
||||||
}
|
|
||||||
return content.substring(0, 100) + "...";
|
|
||||||
}
|
|
||||||
|
|
||||||
// ========== 枚举转换辅助 ==========
|
|
||||||
|
|
||||||
public MessageType getTypeEnum() {
|
|
||||||
return this.type;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -1,168 +0,0 @@
|
||||||
package com.xjhs.findmemerchant.entity;
|
|
||||||
|
|
||||||
import com.xjhs.findmemerchant.common.jpa.AbstractBaseEntity;
|
|
||||||
import com.xjhs.findmemerchant.types.OrderStatus;
|
|
||||||
import jakarta.persistence.*;
|
|
||||||
import lombok.Getter;
|
|
||||||
import lombok.Setter;
|
|
||||||
import org.hibernate.annotations.Comment;
|
|
||||||
|
|
||||||
import java.math.BigDecimal;
|
|
||||||
import java.time.LocalDateTime;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 订单实体
|
|
||||||
* 对应表:orders
|
|
||||||
*/
|
|
||||||
@Getter
|
|
||||||
@Setter
|
|
||||||
@Entity
|
|
||||||
@Table(
|
|
||||||
name = "orders",
|
|
||||||
indexes = {
|
|
||||||
@Index(name = "idx_orders_store_id", columnList = "store_id"),
|
|
||||||
@Index(name = "idx_orders_member_id", columnList = "member_id"),
|
|
||||||
@Index(name = "idx_orders_status", columnList = "status")
|
|
||||||
},
|
|
||||||
uniqueConstraints = {
|
|
||||||
@UniqueConstraint(name = "uk_orders_order_no", columnNames = "order_no")
|
|
||||||
}
|
|
||||||
)
|
|
||||||
public class Order extends AbstractBaseEntity {
|
|
||||||
/**
|
|
||||||
* 订单号
|
|
||||||
*/
|
|
||||||
@Column(name = "order_no", length = 32)
|
|
||||||
@Comment("订单号")
|
|
||||||
private String orderNo;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 订单总金额
|
|
||||||
*/
|
|
||||||
@Column(name = "total_amount", precision = 10, scale = 2)
|
|
||||||
@Comment("订单总金额")
|
|
||||||
private BigDecimal totalAmount;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 优惠金额
|
|
||||||
*/
|
|
||||||
@Column(name = "discount_amount", precision = 10, scale = 2)
|
|
||||||
@Comment("优惠金额")
|
|
||||||
private BigDecimal discountAmount = BigDecimal.ZERO;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 实付金额
|
|
||||||
*/
|
|
||||||
@Column(name = "pay_amount", precision = 10, scale = 2)
|
|
||||||
@Comment("实付金额")
|
|
||||||
private BigDecimal payAmount;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 使用的券码ID(可为空)
|
|
||||||
*/
|
|
||||||
@Column(name = "coupon_code_id")
|
|
||||||
@Comment("优惠券码ID")
|
|
||||||
private Long couponCodeId;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 订单状态:1-待支付 2-已支付 3-已完成 4-已退款 5-已取消
|
|
||||||
*/
|
|
||||||
@Column(name = "status")
|
|
||||||
@Comment("订单状态:1待支付 2已支付 3已完成 4已退款 5已取消")
|
|
||||||
private OrderStatus status;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 支付时间
|
|
||||||
*/
|
|
||||||
@Column(name = "paid_at")
|
|
||||||
@Comment("支付时间")
|
|
||||||
private LocalDateTime paidAt;
|
|
||||||
|
|
||||||
|
|
||||||
// ========== 关联关系 ==========
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 门店
|
|
||||||
*/
|
|
||||||
@ManyToOne(fetch = FetchType.LAZY)
|
|
||||||
@JoinColumn(name = "store_id", insertable = false, updatable = false)
|
|
||||||
private Store store;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 会员
|
|
||||||
*/
|
|
||||||
@ManyToOne(fetch = FetchType.LAZY)
|
|
||||||
@JoinColumn(name = "member_id", insertable = false, updatable = false)
|
|
||||||
private Member member;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 优惠券码
|
|
||||||
*/
|
|
||||||
@ManyToOne(fetch = FetchType.LAZY)
|
|
||||||
@JoinColumn(name = "coupon_code_id", insertable = false, updatable = false)
|
|
||||||
private CouponCode couponCode;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 订单明细
|
|
||||||
*/
|
|
||||||
@OneToMany(mappedBy = "order", fetch = FetchType.LAZY)
|
|
||||||
private List<OrderItem> items;
|
|
||||||
|
|
||||||
// ========== 业务方法 ==========
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 是否已支付(状态>=已支付且非已取消)
|
|
||||||
*/
|
|
||||||
public boolean isPaid() {
|
|
||||||
OrderStatus s = getStatusEnum();
|
|
||||||
if (s == null) return false;
|
|
||||||
return s.getCodeValue() >= OrderStatus.PAID.getCodeValue()
|
|
||||||
&& s != OrderStatus.CANCELLED;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 是否已完成
|
|
||||||
*/
|
|
||||||
public boolean isCompleted() {
|
|
||||||
return getStatusEnum() == OrderStatus.COMPLETED;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 是否可退款(已支付或已完成)
|
|
||||||
*/
|
|
||||||
public boolean canRefund() {
|
|
||||||
OrderStatus s = getStatusEnum();
|
|
||||||
return s == OrderStatus.PAID || s == OrderStatus.COMPLETED;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 是否可取消(待支付)
|
|
||||||
*/
|
|
||||||
public boolean canCancel() {
|
|
||||||
return getStatusEnum() == OrderStatus.PENDING;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 状态文案
|
|
||||||
*/
|
|
||||||
public String getStatusText() {
|
|
||||||
OrderStatus s = getStatusEnum();
|
|
||||||
return s != null ? s.getDesc() : "未知";
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 是否有优惠
|
|
||||||
*/
|
|
||||||
public boolean hasDiscount() {
|
|
||||||
return discountAmount != null && discountAmount.compareTo(BigDecimal.ZERO) > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ========== 枚举转换辅助 ==========
|
|
||||||
|
|
||||||
public OrderStatus getStatusEnum() {
|
|
||||||
return this.status;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -1,123 +0,0 @@
|
||||||
package com.xjhs.findmemerchant.entity;
|
|
||||||
|
|
||||||
import com.xjhs.findmemerchant.common.jpa.id.SnowflakeGenerated;
|
|
||||||
import jakarta.persistence.*;
|
|
||||||
import lombok.Getter;
|
|
||||||
import lombok.Setter;
|
|
||||||
import org.hibernate.annotations.Comment;
|
|
||||||
|
|
||||||
import java.math.BigDecimal;
|
|
||||||
import java.time.LocalDateTime;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 订单明细
|
|
||||||
* 对应表:order_items
|
|
||||||
*/
|
|
||||||
@Getter
|
|
||||||
@Setter
|
|
||||||
@Entity
|
|
||||||
@Table(
|
|
||||||
name = "order_items",
|
|
||||||
indexes = {
|
|
||||||
@Index(name = "idx_order_items_order_id", columnList = "order_id"),
|
|
||||||
@Index(name = "idx_order_items_product_id", columnList = "product_id"),
|
|
||||||
@Index(name = "idx_order_items_sku_id", columnList = "sku_id")
|
|
||||||
}
|
|
||||||
)
|
|
||||||
public class OrderItem {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 主键(雪花ID)
|
|
||||||
*/
|
|
||||||
@Id
|
|
||||||
@GeneratedValue
|
|
||||||
@SnowflakeGenerated
|
|
||||||
@Comment("主键ID")
|
|
||||||
private Long id;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 商品ID(可能被删除所以可空)
|
|
||||||
*/
|
|
||||||
@Column(name = "product_id")
|
|
||||||
@Comment("商品ID(可空)")
|
|
||||||
private Long productId;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 商品名称(快照)
|
|
||||||
*/
|
|
||||||
@Column(name = "product_name", length = 100)
|
|
||||||
@Comment("商品名称(快照)")
|
|
||||||
private String productName;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* SKU ID(可能被删除所以可空)
|
|
||||||
*/
|
|
||||||
@Column(name = "sku_id")
|
|
||||||
@Comment("SKU ID(可空)")
|
|
||||||
private Long skuId;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* SKU 名称(快照)
|
|
||||||
*/
|
|
||||||
@Column(name = "sku_name", length = 100)
|
|
||||||
@Comment("SKU名称(快照)")
|
|
||||||
private String skuName;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 商品图片(快照)
|
|
||||||
*/
|
|
||||||
@Column(name = "image", length = 255)
|
|
||||||
@Comment("商品图片(快照)")
|
|
||||||
private String image;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 商品单价
|
|
||||||
*/
|
|
||||||
@Column(name = "unit_price", precision = 10, scale = 2)
|
|
||||||
@Comment("商品单价")
|
|
||||||
private BigDecimal unitPrice;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 购买数量
|
|
||||||
*/
|
|
||||||
@Column(name = "quantity")
|
|
||||||
@Comment("购买数量")
|
|
||||||
private Integer quantity = 1;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 小计金额
|
|
||||||
*/
|
|
||||||
@Column(name = "total_price", precision = 10, scale = 2)
|
|
||||||
@Comment("小计金额")
|
|
||||||
private BigDecimal totalPrice;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 创建时间
|
|
||||||
*/
|
|
||||||
@Column(name = "created_at")
|
|
||||||
@Comment("创建时间")
|
|
||||||
private LocalDateTime createdAt;
|
|
||||||
|
|
||||||
// ========== 关联关系 ==========
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 所属订单
|
|
||||||
*/
|
|
||||||
@ManyToOne(fetch = FetchType.LAZY)
|
|
||||||
@JoinColumn(name = "order_id")
|
|
||||||
private Order order;
|
|
||||||
|
|
||||||
// ========== 业务方法 ==========
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 根据单价 * 数量计算小计
|
|
||||||
*/
|
|
||||||
public BigDecimal getSubtotal() {
|
|
||||||
if (unitPrice == null || quantity == null) {
|
|
||||||
return BigDecimal.ZERO;
|
|
||||||
}
|
|
||||||
return unitPrice.multiply(BigDecimal.valueOf(quantity));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,190 +0,0 @@
|
||||||
package com.xjhs.findmemerchant.entity;
|
|
||||||
|
|
||||||
import com.xjhs.findmemerchant.common.jpa.AbstractBaseEntity;
|
|
||||||
import com.xjhs.findmemerchant.types.ProductStatus;
|
|
||||||
import jakarta.persistence.*;
|
|
||||||
import lombok.Getter;
|
|
||||||
import lombok.Setter;
|
|
||||||
import org.hibernate.annotations.Comment;
|
|
||||||
|
|
||||||
import java.math.BigDecimal;
|
|
||||||
import java.math.RoundingMode;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 商品实体
|
|
||||||
* 对应表:products
|
|
||||||
*/
|
|
||||||
@Getter
|
|
||||||
@Setter
|
|
||||||
@Entity
|
|
||||||
@Table(
|
|
||||||
name = "products",
|
|
||||||
indexes = {
|
|
||||||
@Index(name = "idx_products_merchant_id", columnList = "merchant_id"),
|
|
||||||
@Index(name = "idx_products_store_id", columnList = "store_id"),
|
|
||||||
@Index(name = "idx_products_category_id", columnList = "category_id"),
|
|
||||||
@Index(name = "idx_products_status", columnList = "status")
|
|
||||||
}
|
|
||||||
)
|
|
||||||
public class Product extends AbstractBaseEntity {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 商品名称
|
|
||||||
*/
|
|
||||||
@Column(name = "name", length = 100)
|
|
||||||
@Comment("商品名称")
|
|
||||||
private String name;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 商品描述
|
|
||||||
*/
|
|
||||||
@Column(name = "description", columnDefinition = "text")
|
|
||||||
@Comment("商品描述")
|
|
||||||
private String description;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 商品图片列表(JSON数组字符串)
|
|
||||||
*/
|
|
||||||
@Column(name = "images", columnDefinition = "text")
|
|
||||||
@Comment("商品图片(JSON数组)")
|
|
||||||
private String images;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 原价
|
|
||||||
*/
|
|
||||||
@Column(name = "original_price", precision = 10, scale = 2)
|
|
||||||
@Comment("原价")
|
|
||||||
private BigDecimal originalPrice;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 售价
|
|
||||||
*/
|
|
||||||
@Column(name = "sale_price", precision = 10, scale = 2)
|
|
||||||
@Comment("售价")
|
|
||||||
private BigDecimal salePrice;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 库存,-1 表示无限库存
|
|
||||||
*/
|
|
||||||
@Column(name = "stock")
|
|
||||||
@Comment("库存,-1表示无限库存")
|
|
||||||
private Integer stock = -1;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 已售数量
|
|
||||||
*/
|
|
||||||
@Column(name = "sold_count")
|
|
||||||
@Comment("已售数量")
|
|
||||||
private Integer soldCount = 0;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 排序值
|
|
||||||
*/
|
|
||||||
@Column(name = "sort_order")
|
|
||||||
@Comment("排序值")
|
|
||||||
private Integer sortOrder = 0;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 商品状态:0-下架 1-上架
|
|
||||||
*/
|
|
||||||
@Column(name = "status",columnDefinition = "VARCHAR(20)",length = 20)
|
|
||||||
@Enumerated(EnumType.STRING)
|
|
||||||
@Comment("商品状态:0下架 1上架")
|
|
||||||
private ProductStatus status = ProductStatus.OFF_SALE;
|
|
||||||
|
|
||||||
// ========== 关联关系 ==========
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 商家
|
|
||||||
*/
|
|
||||||
@ManyToOne(fetch = FetchType.LAZY)
|
|
||||||
@JoinColumn(name = "merchant_id", insertable = false, updatable = false)
|
|
||||||
private Merchant merchant;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 门店
|
|
||||||
*/
|
|
||||||
@ManyToOne(fetch = FetchType.LAZY)
|
|
||||||
@JoinColumn(name = "store_id", insertable = false, updatable = false)
|
|
||||||
private Store store;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 商品分类
|
|
||||||
*/
|
|
||||||
@ManyToOne(fetch = FetchType.LAZY)
|
|
||||||
@JoinColumn(name = "category_id", insertable = false, updatable = false)
|
|
||||||
private ProductCategory category;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* SKU 列表
|
|
||||||
*/
|
|
||||||
@OneToMany(mappedBy = "product", fetch = FetchType.LAZY)
|
|
||||||
private List<ProductSKU> skus;
|
|
||||||
|
|
||||||
// ========== 业务方法 ==========
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 是否上架中
|
|
||||||
*/
|
|
||||||
public boolean isOnSale() {
|
|
||||||
return getStatusEnum() == ProductStatus.ON_SALE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 是否有库存
|
|
||||||
*/
|
|
||||||
public boolean hasStock() {
|
|
||||||
if (stock == null) return false;
|
|
||||||
return stock == -1 || stock > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 是否有折扣(售价 < 原价)
|
|
||||||
*/
|
|
||||||
public boolean hasDiscount() {
|
|
||||||
if (salePrice == null || originalPrice == null) return false;
|
|
||||||
return salePrice.compareTo(originalPrice) < 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 折扣率 (0-100),整数部分
|
|
||||||
*/
|
|
||||||
public int getDiscountRate() {
|
|
||||||
if (originalPrice == null || originalPrice.compareTo(BigDecimal.ZERO) == 0
|
|
||||||
|| salePrice == null) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
BigDecimal rate = salePrice
|
|
||||||
.divide(originalPrice, 2, RoundingMode.HALF_UP)
|
|
||||||
.multiply(BigDecimal.valueOf(100));
|
|
||||||
return rate.intValue();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 状态文案
|
|
||||||
*/
|
|
||||||
public String getStatusText() {
|
|
||||||
ProductStatus s = getStatusEnum();
|
|
||||||
return s != null ? s.getDesc() : "未知";
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 是否可扣减库存
|
|
||||||
*/
|
|
||||||
public boolean canDeductStock(int quantity) {
|
|
||||||
if (stock == null || quantity <= 0) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (stock == -1) {
|
|
||||||
return true; // 无限库存
|
|
||||||
}
|
|
||||||
return stock >= quantity;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ========== 枚举转换辅助 ==========
|
|
||||||
|
|
||||||
public ProductStatus getStatusEnum() {
|
|
||||||
return this.status;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,109 +0,0 @@
|
||||||
package com.xjhs.findmemerchant.entity;
|
|
||||||
|
|
||||||
import com.xjhs.findmemerchant.common.jpa.AbstractBaseEntity;
|
|
||||||
import com.xjhs.findmemerchant.types.CommonStatus;
|
|
||||||
import jakarta.persistence.*;
|
|
||||||
import lombok.Getter;
|
|
||||||
import lombok.Setter;
|
|
||||||
import org.hibernate.annotations.Comment;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 商品分类实体
|
|
||||||
* 对应表:product_categories
|
|
||||||
*/
|
|
||||||
@Getter
|
|
||||||
@Setter
|
|
||||||
@Entity
|
|
||||||
@Table(
|
|
||||||
name = "product_categories",
|
|
||||||
indexes = {
|
|
||||||
@Index(name = "idx_product_categories_merchant_id", columnList = "merchant_id"),
|
|
||||||
@Index(name = "idx_product_categories_parent_id", columnList = "parent_id"),
|
|
||||||
@Index(name = "idx_product_categories_status", columnList = "status")
|
|
||||||
}
|
|
||||||
)
|
|
||||||
public class ProductCategory extends AbstractBaseEntity {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 分类名称
|
|
||||||
*/
|
|
||||||
@Column(name = "name", length = 50)
|
|
||||||
@Comment("分类名称")
|
|
||||||
private String name;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 父分类ID,支持二级分类
|
|
||||||
*/
|
|
||||||
@Column(name = "parent_id")
|
|
||||||
@Comment("父分类ID,支持二级分类")
|
|
||||||
private Long parentId;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 排序值
|
|
||||||
*/
|
|
||||||
@Column(name = "sort_order")
|
|
||||||
@Comment("排序值")
|
|
||||||
private Integer sortOrder = 0;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 状态:0-禁用 1-启用
|
|
||||||
*/
|
|
||||||
@Column(name = "status")
|
|
||||||
@Comment("状态:0禁用 1启用")
|
|
||||||
private CommonStatus status = CommonStatus.ENABLED;
|
|
||||||
|
|
||||||
// ========== 关联关系 ==========
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 商家
|
|
||||||
*/
|
|
||||||
@ManyToOne(fetch = FetchType.LAZY)
|
|
||||||
@JoinColumn(name = "merchant_id", insertable = false, updatable = false)
|
|
||||||
private Merchant merchant;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 父分类
|
|
||||||
*/
|
|
||||||
@ManyToOne(fetch = FetchType.LAZY)
|
|
||||||
@JoinColumn(name = "parent_id", insertable = false, updatable = false)
|
|
||||||
private ProductCategory parent;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 子分类列表
|
|
||||||
*/
|
|
||||||
@OneToMany(mappedBy = "parent", fetch = FetchType.LAZY)
|
|
||||||
private List<ProductCategory> children;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 分类下商品
|
|
||||||
*/
|
|
||||||
@OneToMany(mappedBy = "category", fetch = FetchType.LAZY)
|
|
||||||
private List<Product> products;
|
|
||||||
|
|
||||||
// ========== 业务方法 ==========
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 是否启用
|
|
||||||
*/
|
|
||||||
public boolean isEnabled() {
|
|
||||||
return getStatusEnum() == CommonStatus.ENABLED;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 是否为一级分类(无父分类)
|
|
||||||
*/
|
|
||||||
public boolean isTopLevel() {
|
|
||||||
return parentId == null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public CommonStatus getStatusEnum() {
|
|
||||||
return this.status;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getStatusText() {
|
|
||||||
CommonStatus e = getStatusEnum();
|
|
||||||
return e != null ? e.getDesc() : "未知";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,126 +0,0 @@
|
||||||
package com.xjhs.findmemerchant.entity;
|
|
||||||
|
|
||||||
import com.xjhs.findmemerchant.common.jpa.id.SnowflakeGenerated;
|
|
||||||
import com.xjhs.findmemerchant.common.jpa.AbstractBaseEntity;
|
|
||||||
import com.xjhs.findmemerchant.types.CommonStatus;
|
|
||||||
import jakarta.persistence.*;
|
|
||||||
import lombok.Getter;
|
|
||||||
import lombok.Setter;
|
|
||||||
import org.hibernate.annotations.Comment;
|
|
||||||
|
|
||||||
import java.math.BigDecimal;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 商品SKU(规格)实体
|
|
||||||
* 对应表:product_skus
|
|
||||||
*/
|
|
||||||
@Getter
|
|
||||||
@Setter
|
|
||||||
@Entity
|
|
||||||
@Table(
|
|
||||||
name = "product_skus",
|
|
||||||
indexes = {
|
|
||||||
@Index(name = "idx_product_skus_product_id", columnList = "product_id"),
|
|
||||||
@Index(name = "idx_product_skus_sku_code", columnList = "sku_code")
|
|
||||||
}
|
|
||||||
)
|
|
||||||
public class ProductSKU extends AbstractBaseEntity {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 主键(雪花ID)
|
|
||||||
*/
|
|
||||||
@Id
|
|
||||||
@GeneratedValue
|
|
||||||
@SnowflakeGenerated
|
|
||||||
@Comment("主键ID")
|
|
||||||
private Long id;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 规格名称(如:大杯/加冰)
|
|
||||||
*/
|
|
||||||
@Column(name = "sku_name", length = 100)
|
|
||||||
@Comment("规格名称")
|
|
||||||
private String skuName;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* SKU 编码
|
|
||||||
*/
|
|
||||||
@Column(name = "sku_code", length = 50)
|
|
||||||
@Comment("SKU编码")
|
|
||||||
private String skuCode;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 售价
|
|
||||||
*/
|
|
||||||
@Column(name = "price", precision = 10, scale = 2)
|
|
||||||
@Comment("规格价格")
|
|
||||||
private BigDecimal price;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 库存,-1 表示无限库存
|
|
||||||
*/
|
|
||||||
@Column(name = "stock")
|
|
||||||
@Comment("库存,-1表示无限库存")
|
|
||||||
private Integer stock = -1;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 已售数量
|
|
||||||
*/
|
|
||||||
@Column(name = "sold_count")
|
|
||||||
@Comment("已售数量")
|
|
||||||
private Integer soldCount = 0;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 状态:0-禁用 1-启用
|
|
||||||
*/
|
|
||||||
@Column(name = "status",columnDefinition = "VARCHAR(20)",length = 20)
|
|
||||||
@Comment("状态:0禁用 1启用")
|
|
||||||
private CommonStatus status = CommonStatus.ENABLED;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 所属商品
|
|
||||||
*/
|
|
||||||
@ManyToOne(fetch = FetchType.LAZY)
|
|
||||||
@JoinColumn(name = "product_id", insertable = false, updatable = false)
|
|
||||||
private Product product;
|
|
||||||
|
|
||||||
// ===== 业务方法 =====
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 是否启用
|
|
||||||
*/
|
|
||||||
public boolean isEnabled() {
|
|
||||||
return getStatusEnum() == CommonStatus.ENABLED;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 是否有库存
|
|
||||||
*/
|
|
||||||
public boolean hasStock() {
|
|
||||||
if (stock == null) return false;
|
|
||||||
return stock == -1 || stock > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 是否可扣减库存
|
|
||||||
*/
|
|
||||||
public boolean canDeductStock(int quantity) {
|
|
||||||
if (stock == null || quantity <= 0) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (stock == -1) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return stock >= quantity;
|
|
||||||
}
|
|
||||||
|
|
||||||
public CommonStatus getStatusEnum() {
|
|
||||||
return this.status;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getStatusText() {
|
|
||||||
CommonStatus e = getStatusEnum();
|
|
||||||
return e != null ? e.getDesc() : "未知";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,170 +0,0 @@
|
||||||
package com.xjhs.findmemerchant.entity;
|
|
||||||
|
|
||||||
import com.xjhs.findmemerchant.common.jpa.AbstractBaseEntity;
|
|
||||||
import com.xjhs.findmemerchant.types.ReviewStatus;
|
|
||||||
import jakarta.persistence.*;
|
|
||||||
import lombok.Getter;
|
|
||||||
import lombok.Setter;
|
|
||||||
import org.hibernate.annotations.Comment;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 用户评价(C端共享)
|
|
||||||
* 对应表:reviews
|
|
||||||
*/
|
|
||||||
@Getter
|
|
||||||
@Setter
|
|
||||||
@Entity
|
|
||||||
@Table(
|
|
||||||
name = "reviews",
|
|
||||||
indexes = {
|
|
||||||
@Index(name = "idx_reviews_order_id", columnList = "order_id"),
|
|
||||||
@Index(name = "idx_reviews_merchant_id", columnList = "merchant_id"),
|
|
||||||
@Index(name = "idx_reviews_store_id", columnList = "store_id"),
|
|
||||||
@Index(name = "idx_reviews_user_id", columnList = "user_id"),
|
|
||||||
@Index(name = "idx_reviews_created_at", columnList = "created_at")
|
|
||||||
}
|
|
||||||
)
|
|
||||||
public class Review extends AbstractBaseEntity {
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* C端用户ID
|
|
||||||
*/
|
|
||||||
@Column(name = "user_id")
|
|
||||||
@Comment("C端用户ID")
|
|
||||||
private Long userId;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 用户昵称
|
|
||||||
*/
|
|
||||||
@Column(name = "user_name", length = 50)
|
|
||||||
@Comment("用户昵称")
|
|
||||||
private String userName;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 用户头像
|
|
||||||
*/
|
|
||||||
@Column(name = "user_avatar", length = 255)
|
|
||||||
@Comment("用户头像URL")
|
|
||||||
private String userAvatar;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 评分 1-5
|
|
||||||
*/
|
|
||||||
@Column(name = "rating")
|
|
||||||
@Comment("评分 1-5")
|
|
||||||
private Integer rating;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 评价内容
|
|
||||||
*/
|
|
||||||
@Column(name = "content", columnDefinition = "text")
|
|
||||||
@Comment("评价内容")
|
|
||||||
private String content;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 图片URL,逗号分隔
|
|
||||||
*/
|
|
||||||
@Column(name = "images", length = 1000)
|
|
||||||
@Comment("评价图片URL,逗号分隔")
|
|
||||||
private String images;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 是否匿名
|
|
||||||
*/
|
|
||||||
@Column(name = "is_anonymous")
|
|
||||||
@Comment("是否匿名")
|
|
||||||
private Boolean isAnonymous = Boolean.FALSE;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 状态:1-正常 0-隐藏
|
|
||||||
*/
|
|
||||||
@Column(name = "status",columnDefinition = "VARCHAR(20)",length = 20)
|
|
||||||
@Comment("状态:1正常 0隐藏")
|
|
||||||
private ReviewStatus status = ReviewStatus.NORMAL;
|
|
||||||
|
|
||||||
// ========== 关联关系 ==========
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 回复
|
|
||||||
*/
|
|
||||||
@OneToOne(mappedBy = "review", fetch = FetchType.LAZY)
|
|
||||||
private ReviewReply reply;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 门店
|
|
||||||
*/
|
|
||||||
@ManyToOne(fetch = FetchType.LAZY)
|
|
||||||
@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")
|
|
||||||
private Order order;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// ========== 业务方法 ==========
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 评分文案
|
|
||||||
*/
|
|
||||||
public String getRatingText() {
|
|
||||||
if (rating == null) {
|
|
||||||
return "未知";
|
|
||||||
}
|
|
||||||
return switch (rating) {
|
|
||||||
case 5 -> "非常满意";
|
|
||||||
case 4 -> "满意";
|
|
||||||
case 3 -> "一般";
|
|
||||||
case 2 -> "不满意";
|
|
||||||
case 1 -> "非常不满意";
|
|
||||||
default -> "未知";
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 是否好评(4-5星)
|
|
||||||
*/
|
|
||||||
public boolean isPositive() {
|
|
||||||
return rating != null && rating >= 4;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 是否差评(1-2星)
|
|
||||||
*/
|
|
||||||
public boolean isNegative() {
|
|
||||||
return rating != null && rating <= 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 展示用昵称(匿名/真实)
|
|
||||||
*/
|
|
||||||
public String getDisplayName() {
|
|
||||||
if (Boolean.TRUE.equals(isAnonymous)) {
|
|
||||||
return "匿名用户";
|
|
||||||
}
|
|
||||||
return userName;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ReviewStatus getStatusEnum() {
|
|
||||||
return this.status;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getStatusText() {
|
|
||||||
ReviewStatus e = getStatusEnum();
|
|
||||||
return e != null ? e.getDesc() : "未知";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,77 +0,0 @@
|
||||||
package com.xjhs.findmemerchant.entity;
|
|
||||||
|
|
||||||
import com.xjhs.findmemerchant.common.jpa.id.SnowflakeGenerated;
|
|
||||||
import jakarta.persistence.*;
|
|
||||||
import lombok.Getter;
|
|
||||||
import lombok.Setter;
|
|
||||||
import org.hibernate.annotations.Comment;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 商家对评价的回复
|
|
||||||
* 对应表:review_replies
|
|
||||||
*/
|
|
||||||
@Getter
|
|
||||||
@Setter
|
|
||||||
@Entity
|
|
||||||
@Table(
|
|
||||||
name = "review_replies",
|
|
||||||
uniqueConstraints = {
|
|
||||||
@UniqueConstraint(name = "uk_review_replies_review_id", columnNames = "review_id")
|
|
||||||
},
|
|
||||||
indexes = {
|
|
||||||
@Index(name = "idx_review_replies_merchant_id", columnList = "merchant_id")
|
|
||||||
}
|
|
||||||
)
|
|
||||||
public class ReviewReply{
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 主键(雪花ID)
|
|
||||||
*/
|
|
||||||
@Id
|
|
||||||
@GeneratedValue
|
|
||||||
@SnowflakeGenerated
|
|
||||||
@Comment("主键ID")
|
|
||||||
private Long id;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 评价ID(唯一,一个评价一条回复)
|
|
||||||
*/
|
|
||||||
@Column(name = "review_id")
|
|
||||||
@Comment("评价ID")
|
|
||||||
private Long reviewId;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 商家ID
|
|
||||||
*/
|
|
||||||
@Column(name = "merchant_id")
|
|
||||||
@Comment("商家ID")
|
|
||||||
private Long merchantId;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 回复内容
|
|
||||||
*/
|
|
||||||
@Column(name = "content", columnDefinition = "text")
|
|
||||||
@Comment("回复内容")
|
|
||||||
private String content;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 回复人ID(商家或员工)
|
|
||||||
*/
|
|
||||||
@Column(name = "replier_id")
|
|
||||||
@Comment("回复人ID(商家或员工)")
|
|
||||||
private Long replierId;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 回复人名称
|
|
||||||
*/
|
|
||||||
@Column(name = "replier_name", length = 50)
|
|
||||||
@Comment("回复人名称")
|
|
||||||
private String replierName;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 所属评价
|
|
||||||
*/
|
|
||||||
@OneToOne(fetch = FetchType.LAZY)
|
|
||||||
@JoinColumn(name = "review_id", insertable = false, updatable = false)
|
|
||||||
private Review review;
|
|
||||||
}
|
|
||||||
|
|
@ -1,162 +0,0 @@
|
||||||
package com.xjhs.findmemerchant.entity;
|
|
||||||
|
|
||||||
import com.xjhs.findmemerchant.common.jpa.json.StringListJsonConverter;
|
|
||||||
import com.xjhs.findmemerchant.common.jpa.AbstractBaseEntity;
|
|
||||||
import jakarta.persistence.*;
|
|
||||||
import lombok.Getter;
|
|
||||||
import lombok.Setter;
|
|
||||||
import org.hibernate.annotations.Comment;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import static com.xjhs.findmemerchant.constants.RoleConstants.*;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 角色实体
|
|
||||||
* 对应表:roles
|
|
||||||
*/
|
|
||||||
@Getter
|
|
||||||
@Setter
|
|
||||||
@Entity
|
|
||||||
@Table(
|
|
||||||
name = "roles",
|
|
||||||
uniqueConstraints = {
|
|
||||||
@UniqueConstraint(name = "uk_roles_code", columnNames = "code")
|
|
||||||
}
|
|
||||||
)
|
|
||||||
public class Role extends AbstractBaseEntity {
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 角色名称
|
|
||||||
*/
|
|
||||||
@Column(name = "name", length = 50)
|
|
||||||
@Comment("角色名称")
|
|
||||||
private String name;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 角色编码(唯一)
|
|
||||||
*/
|
|
||||||
@Column(name = "code", length = 50)
|
|
||||||
@Comment("角色编码")
|
|
||||||
private String code;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 描述
|
|
||||||
*/
|
|
||||||
@Column(name = "description", length = 200)
|
|
||||||
@Comment("角色描述")
|
|
||||||
private String description;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 权限列表(JSON数组)
|
|
||||||
*/
|
|
||||||
@Convert(converter = StringListJsonConverter.class)
|
|
||||||
@Column(name = "permissions", columnDefinition = "json")
|
|
||||||
@Comment("权限列表(JSON数组)")
|
|
||||||
private List<String> permissions = new ArrayList<>();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 是否系统内置角色:1-是 0-否
|
|
||||||
*/
|
|
||||||
@Column(name = "is_system")
|
|
||||||
@Comment("是否系统内置角色:1是 0否")
|
|
||||||
private Byte isSystem = 0;
|
|
||||||
|
|
||||||
// ========== 业务方法 ==========
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 是否系统预置角色
|
|
||||||
*/
|
|
||||||
public boolean isSystemRole() {
|
|
||||||
return Byte.valueOf((byte) 1).equals(isSystem);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 是否拥有指定权限(支持 *)
|
|
||||||
*/
|
|
||||||
public boolean hasPermission(String permission) {
|
|
||||||
if (permission == null || permissions == null || permissions.isEmpty()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
for (String p : permissions) {
|
|
||||||
if (PERMISSION_ALL.equals(p) || permission.equals(p)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 返回权限列表,避免 null
|
|
||||||
*/
|
|
||||||
public List<String> getPermissionsSafe() {
|
|
||||||
return permissions != null ? permissions : new ArrayList<>();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 系统内置默认角色(不带ID、时间,用于初始化)
|
|
||||||
*/
|
|
||||||
public static List<Role> getDefaultRoles() {
|
|
||||||
List<Role> roles = new ArrayList<>();
|
|
||||||
|
|
||||||
// 店长:全部权限
|
|
||||||
Role owner = new Role();
|
|
||||||
owner.setCode(ROLE_CODE_OWNER);
|
|
||||||
owner.setName("店长");
|
|
||||||
owner.setPermissions(List.of(PERMISSION_ALL));
|
|
||||||
owner.setIsSystem((byte) 1);
|
|
||||||
roles.add(owner);
|
|
||||||
|
|
||||||
// 运营
|
|
||||||
Role operator = new Role();
|
|
||||||
operator.setCode(ROLE_CODE_OPERATOR);
|
|
||||||
operator.setName("运营");
|
|
||||||
operator.setPermissions(List.of(
|
|
||||||
PERMISSION_STORE_VIEW,
|
|
||||||
PERMISSION_COUPON_MANAGE,
|
|
||||||
PERMISSION_COUPON_VIEW,
|
|
||||||
PERMISSION_COUPON_VERIFY,
|
|
||||||
PERMISSION_ORDER_VIEW,
|
|
||||||
PERMISSION_ACTIVITY_MANAGE,
|
|
||||||
PERMISSION_ACTIVITY_VIEW,
|
|
||||||
PERMISSION_ANALYTICS_VIEW,
|
|
||||||
PERMISSION_MEMBER_VIEW
|
|
||||||
));
|
|
||||||
operator.setIsSystem((byte) 1);
|
|
||||||
roles.add(operator);
|
|
||||||
|
|
||||||
// 客服
|
|
||||||
Role service = new Role();
|
|
||||||
service.setCode(ROLE_CODE_SERVICE);
|
|
||||||
service.setName("客服");
|
|
||||||
service.setPermissions(List.of(
|
|
||||||
PERMISSION_STORE_VIEW,
|
|
||||||
PERMISSION_COUPON_VIEW,
|
|
||||||
PERMISSION_COUPON_VERIFY,
|
|
||||||
PERMISSION_ORDER_VIEW,
|
|
||||||
PERMISSION_MEMBER_VIEW,
|
|
||||||
PERMISSION_MESSAGE_VIEW
|
|
||||||
));
|
|
||||||
service.setIsSystem((byte) 1);
|
|
||||||
roles.add(service);
|
|
||||||
|
|
||||||
// 营销管理员
|
|
||||||
Role marketing = new Role();
|
|
||||||
marketing.setCode(ROLE_CODE_MARKETING);
|
|
||||||
marketing.setName("营销管理员");
|
|
||||||
marketing.setPermissions(List.of(
|
|
||||||
PERMISSION_COUPON_MANAGE,
|
|
||||||
PERMISSION_COUPON_VIEW,
|
|
||||||
PERMISSION_ACTIVITY_MANAGE,
|
|
||||||
PERMISSION_ACTIVITY_VIEW,
|
|
||||||
PERMISSION_ANALYTICS_VIEW
|
|
||||||
));
|
|
||||||
marketing.setIsSystem((byte) 1);
|
|
||||||
roles.add(marketing);
|
|
||||||
|
|
||||||
return roles;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,167 +0,0 @@
|
||||||
package com.xjhs.findmemerchant.entity;
|
|
||||||
|
|
||||||
import com.xjhs.findmemerchant.common.jpa.AbstractBaseEntity;
|
|
||||||
import com.xjhs.findmemerchant.types.SettlementStatus;
|
|
||||||
import com.xjhs.findmemerchant.types.SettlementType;
|
|
||||||
import jakarta.persistence.*;
|
|
||||||
import lombok.Getter;
|
|
||||||
import lombok.Setter;
|
|
||||||
import org.hibernate.annotations.Comment;
|
|
||||||
|
|
||||||
import java.math.BigDecimal;
|
|
||||||
import java.time.LocalDateTime;
|
|
||||||
import java.time.format.DateTimeFormatter;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 结算记录(按日/按周)
|
|
||||||
* 对应表:settlements
|
|
||||||
*/
|
|
||||||
@Getter
|
|
||||||
@Setter
|
|
||||||
@Entity
|
|
||||||
@Table(
|
|
||||||
name = "settlements",
|
|
||||||
indexes = {
|
|
||||||
@Index(name = "idx_settlements_merchant_id", columnList = "merchant_id"),
|
|
||||||
@Index(name = "idx_settlements_status", columnList = "status")
|
|
||||||
},
|
|
||||||
uniqueConstraints = {
|
|
||||||
@UniqueConstraint(name = "uk_settlements_no", columnNames = "settlement_no")
|
|
||||||
}
|
|
||||||
)
|
|
||||||
public class Settlement extends AbstractBaseEntity {
|
|
||||||
|
|
||||||
private static final DateTimeFormatter PERIOD_DATE_FORMATTER =
|
|
||||||
DateTimeFormatter.ofPattern("yyyy-MM-dd");
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 商家
|
|
||||||
*/
|
|
||||||
@ManyToOne(fetch = FetchType.LAZY)
|
|
||||||
@JoinColumn(name = "merchant_id", insertable = false, updatable = false)
|
|
||||||
private Merchant merchant;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 结算单号
|
|
||||||
*/
|
|
||||||
@Column(name = "settlement_no", length = 32)
|
|
||||||
@Comment("结算单号")
|
|
||||||
private String settlementNo;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 结算类型:1-日结 2-周结
|
|
||||||
*/
|
|
||||||
@Column(name = "type")
|
|
||||||
@Comment("结算类型:1日结 2周结")
|
|
||||||
private SettlementType type;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 结算周期开始时间
|
|
||||||
*/
|
|
||||||
@Column(name = "period_start")
|
|
||||||
@Comment("结算周期开始时间")
|
|
||||||
private LocalDateTime periodStart;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 结算周期结束时间
|
|
||||||
*/
|
|
||||||
@Column(name = "period_end")
|
|
||||||
@Comment("结算周期结束时间")
|
|
||||||
private LocalDateTime periodEnd;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 订单数量
|
|
||||||
*/
|
|
||||||
@Column(name = "order_count")
|
|
||||||
@Comment("订单数量")
|
|
||||||
private Integer orderCount = 0;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 订单总额
|
|
||||||
*/
|
|
||||||
@Column(name = "total_amount", precision = 12, scale = 2)
|
|
||||||
@Comment("订单总额")
|
|
||||||
private BigDecimal totalAmount;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 退款金额
|
|
||||||
*/
|
|
||||||
@Column(name = "refund_amount", precision = 12, scale = 2)
|
|
||||||
@Comment("退款金额")
|
|
||||||
private BigDecimal refundAmount = BigDecimal.ZERO;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 平台服务费
|
|
||||||
*/
|
|
||||||
@Column(name = "platform_fee", precision = 10, scale = 2)
|
|
||||||
@Comment("平台服务费")
|
|
||||||
private BigDecimal platformFee = BigDecimal.ZERO;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 结算金额
|
|
||||||
*/
|
|
||||||
@Column(name = "settlement_amount", precision = 12, scale = 2)
|
|
||||||
@Comment("结算金额")
|
|
||||||
private BigDecimal settlementAmount;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 结算状态:0-待结算 1-已结算
|
|
||||||
*/
|
|
||||||
@Column(name = "status")
|
|
||||||
@Comment("结算状态:0待结算 1已结算")
|
|
||||||
private SettlementStatus status = SettlementStatus.PENDING;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 实际结算时间
|
|
||||||
*/
|
|
||||||
@Column(name = "settled_at")
|
|
||||||
@Comment("实际结算时间")
|
|
||||||
private LocalDateTime settledAt;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// ========== 业务方法 ==========
|
|
||||||
|
|
||||||
public SettlementType getTypeEnum() {
|
|
||||||
return this.type;
|
|
||||||
}
|
|
||||||
|
|
||||||
public SettlementStatus getStatusEnum() {
|
|
||||||
return this.status;
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* 结算类型文案
|
|
||||||
*/
|
|
||||||
public String getTypeText() {
|
|
||||||
SettlementType e = getTypeEnum();
|
|
||||||
return e != null ? e.getDesc() : "未知";
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 状态文案
|
|
||||||
*/
|
|
||||||
public String getStatusText() {
|
|
||||||
SettlementStatus e = getStatusEnum();
|
|
||||||
return e != null ? e.getDesc() : "未知";
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 是否已结算
|
|
||||||
*/
|
|
||||||
public boolean isSettled() {
|
|
||||||
return getStatusEnum() == SettlementStatus.SETTLED;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 周期文案,例如:2024-01-01 ~ 2024-01-07
|
|
||||||
*/
|
|
||||||
public String getPeriodText() {
|
|
||||||
if (periodStart == null || periodEnd == null) {
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
return periodStart.format(PERIOD_DATE_FORMATTER)
|
|
||||||
+ " ~ "
|
|
||||||
+ periodEnd.format(PERIOD_DATE_FORMATTER);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,258 +0,0 @@
|
||||||
package com.xjhs.findmemerchant.entity;
|
|
||||||
|
|
||||||
import com.xjhs.findmemerchant.common.jpa.AbstractBaseEntity;
|
|
||||||
import com.xjhs.findmemerchant.types.BusinessStatus;
|
|
||||||
import com.xjhs.findmemerchant.types.CommonStatus;
|
|
||||||
import com.xjhs.findmemerchant.types.StoreAuditStatus;
|
|
||||||
import jakarta.persistence.*;
|
|
||||||
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;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 门店实体
|
|
||||||
* 对应表:stores
|
|
||||||
*/
|
|
||||||
@Getter
|
|
||||||
@Setter
|
|
||||||
@Entity
|
|
||||||
@Table(
|
|
||||||
name = "stores",
|
|
||||||
indexes = {
|
|
||||||
@Index(name = "idx_stores_merchant_id", columnList = "merchant_id"),
|
|
||||||
@Index(name = "idx_stores_audit_status", columnList = "audit_status")
|
|
||||||
}
|
|
||||||
)
|
|
||||||
public class Store extends AbstractBaseEntity {
|
|
||||||
/**
|
|
||||||
* 门店名称
|
|
||||||
*/
|
|
||||||
@Column(name = "name", length = 100)
|
|
||||||
@Comment("门店名称")
|
|
||||||
private String name;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 门店Logo
|
|
||||||
*/
|
|
||||||
@Column(name = "logo", length = 500)
|
|
||||||
@Comment("门店Logo")
|
|
||||||
private String logo;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 联系电话
|
|
||||||
*/
|
|
||||||
@Column(name = "phone", length = 11)
|
|
||||||
@Comment("联系电话")
|
|
||||||
private String phone;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 省
|
|
||||||
*/
|
|
||||||
@Column(name = "province", length = 50)
|
|
||||||
@Comment("省")
|
|
||||||
private String province;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 市
|
|
||||||
*/
|
|
||||||
@Column(name = "city", length = 50)
|
|
||||||
@Comment("市")
|
|
||||||
private String city;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 区/县
|
|
||||||
*/
|
|
||||||
@Column(name = "district", length = 50)
|
|
||||||
@Comment("区/县")
|
|
||||||
private String district;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 详细地址
|
|
||||||
*/
|
|
||||||
@Column(name = "address", length = 200)
|
|
||||||
@Comment("详细地址")
|
|
||||||
private String address;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 经度
|
|
||||||
*/
|
|
||||||
@Column(name = "longitude", precision = 10, scale = 7)
|
|
||||||
@Comment("经度")
|
|
||||||
private BigDecimal longitude;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 纬度
|
|
||||||
*/
|
|
||||||
@Column(name = "latitude", precision = 10, scale = 7)
|
|
||||||
@Comment("纬度")
|
|
||||||
private BigDecimal latitude;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 营业时间描述
|
|
||||||
*/
|
|
||||||
@Column(name = "business_hours", length = 100)
|
|
||||||
@Comment("营业时间描述")
|
|
||||||
private String businessHours;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 营业状态:0-已打烊 1-营业中 2-临时打烊
|
|
||||||
*/
|
|
||||||
@Column(name = "business_status",columnDefinition = "VARCHAR(20)", length = 20)
|
|
||||||
@Enumerated(EnumType.STRING)
|
|
||||||
@Comment("营业状态:0已打烊 1营业中 2临时打烊")
|
|
||||||
private BusinessStatus businessStatus = BusinessStatus.OPEN;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 临时打烊原因
|
|
||||||
*/
|
|
||||||
@Column(name = "temp_close_reason", length = 200)
|
|
||||||
@Comment("临时打烊原因")
|
|
||||||
private String tempCloseReason;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 临时打烊结束时间
|
|
||||||
*/
|
|
||||||
@Column(name = "temp_close_until")
|
|
||||||
@Comment("临时打烊结束时间")
|
|
||||||
private LocalDateTime tempCloseUntil;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 审核状态
|
|
||||||
*/
|
|
||||||
@Column(name = "audit_status",columnDefinition = "VARCHAR(20)", length = 20)
|
|
||||||
@Comment("审核状态:0待审核 1已通过 2已拒绝")
|
|
||||||
private StoreAuditStatus auditStatus = StoreAuditStatus.PENDING;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 审核备注
|
|
||||||
*/
|
|
||||||
@Column(name = "audit_remark", length = 500)
|
|
||||||
@Comment("审核备注")
|
|
||||||
private String auditRemark;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 启用状态:0-禁用 1-启用
|
|
||||||
*/
|
|
||||||
@Column(name = "status",columnDefinition = "VARCHAR(20)", length = 20)
|
|
||||||
@Comment("启用状态:0禁用 1启用")
|
|
||||||
private CommonStatus status = CommonStatus.ENABLED;
|
|
||||||
|
|
||||||
// ========== 关联关系 ==========
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 商家
|
|
||||||
*/
|
|
||||||
@ManyToOne(fetch = FetchType.LAZY)
|
|
||||||
@JoinColumn(name = "merchant_id")
|
|
||||||
private Merchant merchant;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 员工列表
|
|
||||||
*/
|
|
||||||
@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,cascade = CascadeType.ALL,orphanRemoval = true)
|
|
||||||
private List<BusinessPeriod> businessPeriods = new ArrayList<>();
|
|
||||||
|
|
||||||
public void addBusinessPeriods(BusinessPeriod businessPeriod){
|
|
||||||
businessPeriod.setStore(this);
|
|
||||||
this.businessPeriods.add(businessPeriod);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// ========== 业务方法 ==========
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 完整地址
|
|
||||||
*/
|
|
||||||
public String getFullAddress() {
|
|
||||||
return (province == null ? "" : province)
|
|
||||||
+ (city == null ? "" : city)
|
|
||||||
+ (district == null ? "" : district)
|
|
||||||
+ (address == null ? "" : address);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 是否审核通过
|
|
||||||
*/
|
|
||||||
public boolean isApproved() {
|
|
||||||
return getAuditStatusEnum() == StoreAuditStatus.APPROVED;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 是否启用
|
|
||||||
*/
|
|
||||||
public boolean isActive() {
|
|
||||||
return getStatusEnum() == CommonStatus.ENABLED;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 是否有地理位置
|
|
||||||
*/
|
|
||||||
public boolean hasLocation() {
|
|
||||||
return longitude != null && latitude != null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 当前是否营业
|
|
||||||
*/
|
|
||||||
public boolean isBusinessOpen() {
|
|
||||||
BusinessStatus bs = getBusinessStatusEnum();
|
|
||||||
if (bs == null) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (bs == BusinessStatus.TEMP_CLOSED) {
|
|
||||||
// 如果设置了临时打烊结束时间且已过期,则视作应恢复营业
|
|
||||||
if (tempCloseUntil != null && LocalDateTime.now().isAfter(tempCloseUntil)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return bs == BusinessStatus.OPEN;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 营业状态文案
|
|
||||||
*/
|
|
||||||
public String getBusinessStatusText() {
|
|
||||||
BusinessStatus bs = getBusinessStatusEnum();
|
|
||||||
return bs != null ? bs.getDesc() : "未知";
|
|
||||||
}
|
|
||||||
|
|
||||||
public BusinessStatus getBusinessStatusEnum() {
|
|
||||||
return this.businessStatus;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public StoreAuditStatus getAuditStatusEnum() {
|
|
||||||
return this.auditStatus;
|
|
||||||
}
|
|
||||||
|
|
||||||
public CommonStatus getStatusEnum() {
|
|
||||||
return this.status;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getAuditStatusText() {
|
|
||||||
StoreAuditStatus e = getAuditStatusEnum();
|
|
||||||
return e != null ? e.getDesc() : "未知";
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getStatusText() {
|
|
||||||
CommonStatus e = getStatusEnum();
|
|
||||||
return e != null ? e.getDesc() : "未知";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,133 +0,0 @@
|
||||||
package com.xjhs.findmemerchant.entity;
|
|
||||||
|
|
||||||
import com.xjhs.findmemerchant.common.jpa.id.SnowflakeGenerated;
|
|
||||||
import com.xjhs.findmemerchant.types.TransactionType;
|
|
||||||
import jakarta.persistence.*;
|
|
||||||
import lombok.Getter;
|
|
||||||
import lombok.Setter;
|
|
||||||
import org.hibernate.annotations.Comment;
|
|
||||||
|
|
||||||
import java.math.BigDecimal;
|
|
||||||
import java.time.LocalDateTime;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 钱包交易流水
|
|
||||||
* 对应表:wallet_transactions
|
|
||||||
*/
|
|
||||||
@Getter
|
|
||||||
@Setter
|
|
||||||
@Entity
|
|
||||||
@Table(
|
|
||||||
name = "wallet_transactions",
|
|
||||||
indexes = {
|
|
||||||
@Index(name = "idx_wallet_transactions_wallet_id", columnList = "wallet_id"),
|
|
||||||
@Index(name = "idx_wallet_transactions_merchant_id", columnList = "merchant_id"),
|
|
||||||
@Index(name = "idx_wallet_transactions_type", columnList = "type"),
|
|
||||||
@Index(name = "idx_wallet_transactions_created_at", columnList = "created_at")
|
|
||||||
}
|
|
||||||
)
|
|
||||||
public class Transaction {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 主键(雪花ID)
|
|
||||||
*/
|
|
||||||
@Id
|
|
||||||
@GeneratedValue
|
|
||||||
@SnowflakeGenerated
|
|
||||||
@Comment("主键ID")
|
|
||||||
private Long id;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 交易类型:1-收入 2-支出 3-冻结 4-解冻 5-提现
|
|
||||||
*/
|
|
||||||
@Column(name = "type",columnDefinition = "VARCHAR(20)",length = 20)
|
|
||||||
@Comment("交易类型:1收入 2支出 3冻结 4解冻 5提现")
|
|
||||||
private TransactionType type;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 交易金额
|
|
||||||
*/
|
|
||||||
@Column(name = "amount", precision = 12, scale = 2)
|
|
||||||
@Comment("交易金额")
|
|
||||||
private BigDecimal amount;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 交易前余额
|
|
||||||
*/
|
|
||||||
@Column(name = "balance_before", precision = 12, scale = 2)
|
|
||||||
@Comment("交易前余额")
|
|
||||||
private BigDecimal balanceBefore;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 交易后余额
|
|
||||||
*/
|
|
||||||
@Column(name = "balance_after", precision = 12, scale = 2)
|
|
||||||
@Comment("交易后余额")
|
|
||||||
private BigDecimal balanceAfter;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 关联类型: order, withdrawal, settlement
|
|
||||||
*/
|
|
||||||
@Column(name = "ref_type", length = 32)
|
|
||||||
@Comment("关联类型:order/withdrawal/settlement等")
|
|
||||||
private String refType;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 关联ID
|
|
||||||
*/
|
|
||||||
@Column(name = "ref_id")
|
|
||||||
@Comment("关联业务ID")
|
|
||||||
private Long refId;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 描述
|
|
||||||
*/
|
|
||||||
@Column(name = "description", length = 200)
|
|
||||||
@Comment("交易描述")
|
|
||||||
private String description;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 创建时间
|
|
||||||
*/
|
|
||||||
@Column(name = "created_at")
|
|
||||||
@Comment("创建时间")
|
|
||||||
private LocalDateTime createdAt;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 所属钱包
|
|
||||||
*/
|
|
||||||
@ManyToOne(fetch = FetchType.LAZY)
|
|
||||||
@JoinColumn(name = "wallet_id", insertable = false, updatable = false)
|
|
||||||
private Wallet wallet;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 商家
|
|
||||||
*/
|
|
||||||
@ManyToOne(fetch = FetchType.LAZY)
|
|
||||||
@JoinColumn(name = "merchant_id", insertable = false, updatable = false)
|
|
||||||
private Merchant merchant;
|
|
||||||
|
|
||||||
|
|
||||||
// ========== 业务方法 ==========
|
|
||||||
|
|
||||||
public TransactionType getTypeEnum() {
|
|
||||||
return this.type;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 交易类型文案
|
|
||||||
*/
|
|
||||||
public String getTypeText() {
|
|
||||||
TransactionType t = getTypeEnum();
|
|
||||||
return t != null ? t.getDesc() : "未知";
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 是否收入流水
|
|
||||||
*/
|
|
||||||
public boolean isIncome() {
|
|
||||||
return getTypeEnum() == TransactionType.INCOME;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,100 +0,0 @@
|
||||||
package com.xjhs.findmemerchant.entity;
|
|
||||||
|
|
||||||
import com.xjhs.findmemerchant.common.jpa.AbstractBaseEntity;
|
|
||||||
import jakarta.persistence.*;
|
|
||||||
import lombok.Getter;
|
|
||||||
import lombok.Setter;
|
|
||||||
import org.hibernate.annotations.Comment;
|
|
||||||
|
|
||||||
import java.math.BigDecimal;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 商家钱包
|
|
||||||
* 对应表:wallets
|
|
||||||
*/
|
|
||||||
@Getter
|
|
||||||
@Setter
|
|
||||||
@Entity
|
|
||||||
@Table(
|
|
||||||
name = "wallets",
|
|
||||||
uniqueConstraints = {
|
|
||||||
@UniqueConstraint(name = "uk_wallets_merchant_id", columnNames = "merchant_id")
|
|
||||||
}
|
|
||||||
)
|
|
||||||
public class Wallet extends AbstractBaseEntity {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 可用余额
|
|
||||||
*/
|
|
||||||
@Column(name = "balance", precision = 12, scale = 2)
|
|
||||||
@Comment("可用余额")
|
|
||||||
private BigDecimal balance = BigDecimal.ZERO;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 冻结余额(提现中)
|
|
||||||
*/
|
|
||||||
@Column(name = "frozen_balance", precision = 12, scale = 2)
|
|
||||||
@Comment("冻结余额(提现中)")
|
|
||||||
private BigDecimal frozenBalance = BigDecimal.ZERO;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 累计收入
|
|
||||||
*/
|
|
||||||
@Column(name = "total_income", precision = 12, scale = 2)
|
|
||||||
@Comment("累计收入")
|
|
||||||
private BigDecimal totalIncome = BigDecimal.ZERO;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 累计提现
|
|
||||||
*/
|
|
||||||
@Column(name = "total_withdrawn", precision = 12, scale = 2)
|
|
||||||
@Comment("累计提现")
|
|
||||||
private BigDecimal totalWithdrawn = BigDecimal.ZERO;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 待结算金额
|
|
||||||
*/
|
|
||||||
@Column(name = "pending_settlement", precision = 12, scale = 2)
|
|
||||||
@Comment("待结算金额")
|
|
||||||
private BigDecimal pendingSettlement = BigDecimal.ZERO;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 商家
|
|
||||||
*/
|
|
||||||
@ManyToOne(fetch = FetchType.LAZY)
|
|
||||||
@JoinColumn(name = "merchant_id")
|
|
||||||
private Merchant merchant;
|
|
||||||
|
|
||||||
// ========== 业务方法 ==========
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 可提现余额
|
|
||||||
*/
|
|
||||||
public BigDecimal getAvailableBalance() {
|
|
||||||
return balance != null ? balance : BigDecimal.ZERO;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 总余额(含冻结)
|
|
||||||
*/
|
|
||||||
public BigDecimal getTotalBalance() {
|
|
||||||
BigDecimal b = balance != null ? balance : BigDecimal.ZERO;
|
|
||||||
BigDecimal f = frozenBalance != null ? frozenBalance : BigDecimal.ZERO;
|
|
||||||
return b.add(f);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 是否可提现指定金额
|
|
||||||
*/
|
|
||||||
public boolean canWithdraw(BigDecimal amount) {
|
|
||||||
if (amount == null) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (amount.compareTo(BigDecimal.ZERO) <= 0) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
BigDecimal b = balance != null ? balance : BigDecimal.ZERO;
|
|
||||||
return b.compareTo(amount) >= 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,175 +0,0 @@
|
||||||
package com.xjhs.findmemerchant.entity;
|
|
||||||
|
|
||||||
import com.xjhs.findmemerchant.common.jpa.AbstractBaseEntity;
|
|
||||||
import com.xjhs.findmemerchant.types.WithdrawalStatus;
|
|
||||||
import jakarta.persistence.*;
|
|
||||||
import lombok.Getter;
|
|
||||||
import lombok.Setter;
|
|
||||||
import org.hibernate.annotations.Comment;
|
|
||||||
|
|
||||||
import java.math.BigDecimal;
|
|
||||||
import java.time.LocalDateTime;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 提现申请
|
|
||||||
* 对应表:withdrawals
|
|
||||||
*/
|
|
||||||
@Getter
|
|
||||||
@Setter
|
|
||||||
@Entity
|
|
||||||
@Table(
|
|
||||||
name = "withdrawals",
|
|
||||||
indexes = {
|
|
||||||
@Index(name = "idx_withdrawals_merchant_id", columnList = "merchant_id"),
|
|
||||||
@Index(name = "idx_withdrawals_wallet_id", columnList = "wallet_id"),
|
|
||||||
@Index(name = "idx_withdrawals_status", columnList = "status"),
|
|
||||||
@Index(name = "idx_withdrawals_created_at", columnList = "created_at")
|
|
||||||
}
|
|
||||||
)
|
|
||||||
public class Withdrawal extends AbstractBaseEntity {
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 提现金额
|
|
||||||
*/
|
|
||||||
@Column(name = "amount", precision = 12, scale = 2)
|
|
||||||
@Comment("提现金额")
|
|
||||||
private BigDecimal amount;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 手续费
|
|
||||||
*/
|
|
||||||
@Column(name = "fee", precision = 10, scale = 2)
|
|
||||||
@Comment("提现手续费")
|
|
||||||
private BigDecimal fee = BigDecimal.ZERO;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 实际到账金额
|
|
||||||
*/
|
|
||||||
@Column(name = "actual_amount", precision = 12, scale = 2)
|
|
||||||
@Comment("实际到账金额")
|
|
||||||
private BigDecimal actualAmount;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 银行名称
|
|
||||||
*/
|
|
||||||
@Column(name = "bank_name", length = 50)
|
|
||||||
@Comment("银行名称")
|
|
||||||
private String bankName;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 银行账号(加密存储)
|
|
||||||
*/
|
|
||||||
@Column(name = "bank_account", length = 30)
|
|
||||||
@Comment("银行账号(加密)")
|
|
||||||
private String bankAccount;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 户名
|
|
||||||
*/
|
|
||||||
@Column(name = "account_name", length = 50)
|
|
||||||
@Comment("开户人姓名")
|
|
||||||
private String accountName;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 状态:0-待审核 1-处理中 2-已完成 3-已拒绝 4-已取消
|
|
||||||
*/
|
|
||||||
@Column(name = "status")
|
|
||||||
@Comment("提现状态")
|
|
||||||
private Byte status = 0;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 拒绝原因
|
|
||||||
*/
|
|
||||||
@Column(name = "reject_reason", length = 200)
|
|
||||||
@Comment("拒绝原因")
|
|
||||||
private String rejectReason;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 审核/处理时间
|
|
||||||
*/
|
|
||||||
@Column(name = "processed_at")
|
|
||||||
@Comment("审核/处理时间")
|
|
||||||
private LocalDateTime processedAt;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 完成时间
|
|
||||||
*/
|
|
||||||
@Column(name = "completed_at")
|
|
||||||
@Comment("完成时间")
|
|
||||||
private LocalDateTime completedAt;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 银行流水号
|
|
||||||
*/
|
|
||||||
@Column(name = "transaction_no", length = 64)
|
|
||||||
@Comment("银行流水号")
|
|
||||||
private String transactionNo;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 备注
|
|
||||||
*/
|
|
||||||
@Column(name = "remark", length = 200)
|
|
||||||
@Comment("备注")
|
|
||||||
private String remark;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 商家
|
|
||||||
*/
|
|
||||||
@ManyToOne(fetch = FetchType.LAZY)
|
|
||||||
@JoinColumn(name = "merchant_id", insertable = false, updatable = false)
|
|
||||||
private Merchant merchant;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 钱包
|
|
||||||
*/
|
|
||||||
@ManyToOne(fetch = FetchType.LAZY)
|
|
||||||
@JoinColumn(name = "wallet_id", insertable = false, updatable = false)
|
|
||||||
private Wallet wallet;
|
|
||||||
|
|
||||||
// ========= 业务方法 =========
|
|
||||||
|
|
||||||
public WithdrawalStatus getStatusEnum() {
|
|
||||||
return WithdrawalStatus.fromCode(this.status);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setStatusEnum(WithdrawalStatus statusEnum) {
|
|
||||||
this.status = statusEnum == null ? null : statusEnum.code();
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getStatusText() {
|
|
||||||
WithdrawalStatus e = getStatusEnum();
|
|
||||||
return e != null ? e.getDesc() : "未知";
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 是否待审核
|
|
||||||
*/
|
|
||||||
public boolean isPending() {
|
|
||||||
return getStatusEnum() == WithdrawalStatus.PENDING;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 是否已完成
|
|
||||||
*/
|
|
||||||
public boolean isCompleted() {
|
|
||||||
return getStatusEnum() == WithdrawalStatus.COMPLETED;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 是否可以取消
|
|
||||||
*/
|
|
||||||
public boolean canCancel() {
|
|
||||||
return getStatusEnum() == WithdrawalStatus.PENDING;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 脱敏银行卡号
|
|
||||||
*/
|
|
||||||
public String getMaskedBankAccount() {
|
|
||||||
if (bankAccount == null || bankAccount.length() <= 8) {
|
|
||||||
return bankAccount;
|
|
||||||
}
|
|
||||||
return bankAccount.substring(0, 4) + "****" + bankAccount.substring(bankAccount.length() - 4);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
108
src/main/java/com/xjhs/findmemerchant/file/FileController.java
Normal file
108
src/main/java/com/xjhs/findmemerchant/file/FileController.java
Normal file
|
|
@ -0,0 +1,108 @@
|
||||||
|
package com.xjhs.findmemerchant.file;
|
||||||
|
|
||||||
|
import com.xjhs.findmemerchant.common.ApiResult;
|
||||||
|
import com.xjhs.findmemerchant.file.dao.FileMetaInfo;
|
||||||
|
import com.xjhs.findmemerchant.file.dao.FileMetaInfoRepository;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.apache.tika.mime.MimeTypes;
|
||||||
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
|
import org.springframework.http.MediaType;
|
||||||
|
import org.springframework.http.ResponseEntity;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.nio.file.Paths;
|
||||||
|
import java.time.LocalDate;
|
||||||
|
import java.time.format.DateTimeFormatter;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 统一文件管理控制器
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
@RestController
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class FileController {
|
||||||
|
|
||||||
|
|
||||||
|
@Value("${appconfig.saveFileRoot}")
|
||||||
|
private String fileSaveRoot="./file-data";
|
||||||
|
|
||||||
|
private final FileMetaInfoRepository fileMetaInfoRepository;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取并检查创建文件存储目录
|
||||||
|
* @return 文件存储目录带日期
|
||||||
|
*/
|
||||||
|
public Path getFileSavePath() throws IOException {
|
||||||
|
var datePath = DateTimeFormatter.ofPattern("yyyy/MM-dd").format(LocalDate.now());
|
||||||
|
var path = Path.of(this.fileSaveRoot, datePath);
|
||||||
|
if (!Files.exists(path)){
|
||||||
|
Files.createDirectories(path);
|
||||||
|
}
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 上传文件
|
||||||
|
*
|
||||||
|
* @param file 文件数据内容
|
||||||
|
* @return 文件描信息
|
||||||
|
*/
|
||||||
|
|
||||||
|
@PostMapping("/platform/file/upload")
|
||||||
|
public ApiResult<FileMetaInfo> uploadFile(@RequestPart(name = "file") MultipartFile file) {
|
||||||
|
try {
|
||||||
|
var ext = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf("."));
|
||||||
|
if (StringUtils.isEmpty(ext)) {
|
||||||
|
try {
|
||||||
|
ext = MimeTypes.getDefaultMimeTypes().forName(file.getContentType()).getExtension();
|
||||||
|
} catch (Exception e) {
|
||||||
|
ext = "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var filePath = Path.of(this.fileSaveRoot, UUID.randomUUID() + ext);
|
||||||
|
file.transferTo(filePath);
|
||||||
|
var fileMetaInfo = new FileMetaInfo();
|
||||||
|
fileMetaInfo.setName(file.getOriginalFilename());
|
||||||
|
fileMetaInfo.setContentType(file.getContentType());
|
||||||
|
fileMetaInfo.setExtension(ext);
|
||||||
|
fileMetaInfo.setSavePath(filePath.toFile().getAbsolutePath());
|
||||||
|
fileMetaInfoRepository.save(fileMetaInfo);
|
||||||
|
return ApiResult.data(fileMetaInfo);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error(e.getMessage(),e);
|
||||||
|
return ApiResult.fail(e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 预览文件
|
||||||
|
* @param fileId 文件id
|
||||||
|
* @return 文件内容
|
||||||
|
*/
|
||||||
|
@GetMapping("/platform/file/view/{fileId}")
|
||||||
|
public ResponseEntity<?> uploadFile(@PathVariable("fileId") String fileId) {
|
||||||
|
return this.fileMetaInfoRepository.findById(fileId).map(item->{
|
||||||
|
try {
|
||||||
|
var bytes = Files.readAllBytes(Paths.get(item.getSavePath()));
|
||||||
|
return ResponseEntity.ok()
|
||||||
|
.contentType(MediaType.parseMediaType(item.getContentType()))
|
||||||
|
.body(bytes);
|
||||||
|
} catch (IOException e) {
|
||||||
|
return ResponseEntity.<byte[]>internalServerError().build();
|
||||||
|
}
|
||||||
|
|
||||||
|
}).orElse(ResponseEntity.<byte[]>internalServerError().build());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,41 @@
|
||||||
|
package com.xjhs.findmemerchant.file.dao;
|
||||||
|
|
||||||
|
import com.xjhs.findmemerchant.common.jpa.id.SnowflakeGenerated;
|
||||||
|
import jakarta.persistence.Column;
|
||||||
|
import jakarta.persistence.Entity;
|
||||||
|
import jakarta.persistence.Id;
|
||||||
|
import lombok.Data;
|
||||||
|
import org.hibernate.annotations.Comment;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 文件信息表
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@Entity
|
||||||
|
@Comment("文件信息表")
|
||||||
|
public class FileMetaInfo {
|
||||||
|
@Id
|
||||||
|
@SnowflakeGenerated
|
||||||
|
@Comment("主键")
|
||||||
|
private Long id;
|
||||||
|
@Comment("文件原始名称")
|
||||||
|
private String name;
|
||||||
|
@Comment("文件媒体类型")
|
||||||
|
private String contentType;
|
||||||
|
@Comment("文件扩展名称")
|
||||||
|
@Column(length = 10)
|
||||||
|
private String extension;
|
||||||
|
@Comment("本地存储路径")
|
||||||
|
private String savePath;
|
||||||
|
@Comment("是否已迁移到云服务")
|
||||||
|
private boolean moveToCloud = false;
|
||||||
|
@Comment("云对象id")
|
||||||
|
@Column(length = 50)
|
||||||
|
private String cloudObjectId;
|
||||||
|
@Comment("创建时间")
|
||||||
|
private LocalDateTime createTime = LocalDateTime.now();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,10 @@
|
||||||
|
package com.xjhs.findmemerchant.file.dao;
|
||||||
|
|
||||||
|
import org.springframework.data.jpa.repository.JpaRepository;
|
||||||
|
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
|
||||||
|
import org.springframework.stereotype.Repository;
|
||||||
|
|
||||||
|
@Repository
|
||||||
|
public interface FileMetaInfoRepository extends JpaRepository<FileMetaInfo,String>, JpaSpecificationExecutor<FileMetaInfo> {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -1,20 +0,0 @@
|
||||||
package com.xjhs.findmemerchant.mapper;
|
|
||||||
|
|
||||||
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);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -1,15 +1,12 @@
|
||||||
package com.xjhs.findmemerchant.mapper;
|
package com.xjhs.findmemerchant.mapper;
|
||||||
|
|
||||||
import com.xjhs.findmemerchant.dto.MerchantDto;
|
import com.xjhs.findmemerchant.dto.merchant.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);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,32 +0,0 @@
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
@ -0,0 +1,15 @@
|
||||||
|
package com.xjhs.findmemerchant.mapper;
|
||||||
|
|
||||||
|
import com.xjhs.findmemerchant.security.LoginUser;
|
||||||
|
import com.xjhs.findmemerchant.system.entity.SystemUser;
|
||||||
|
import org.mapstruct.Mapper;
|
||||||
|
import org.mapstruct.Mapping;
|
||||||
|
import org.mapstruct.ReportingPolicy;
|
||||||
|
|
||||||
|
|
||||||
|
@Mapper(componentModel = "spring",unmappedTargetPolicy = ReportingPolicy.IGNORE,unmappedSourcePolicy = ReportingPolicy.IGNORE)
|
||||||
|
public interface SystemUserMapper {
|
||||||
|
|
||||||
|
@Mapping(target = "merchantId",source = "systemUser.merchant.id")
|
||||||
|
LoginUser toLoginUserInfo(SystemUser systemUser);
|
||||||
|
}
|
||||||
|
|
@ -1,14 +0,0 @@
|
||||||
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> findByMerchant_Id(Long merchantId);
|
|
||||||
|
|
||||||
List<Activity> findByStatus(ActivityStatus status);
|
|
||||||
}
|
|
||||||
|
|
@ -1,25 +0,0 @@
|
||||||
package com.xjhs.findmemerchant.repository;
|
|
||||||
|
|
||||||
import com.xjhs.findmemerchant.entity.BankCard;
|
|
||||||
import org.springframework.data.jpa.repository.JpaRepository;
|
|
||||||
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Optional;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 商家银行卡仓储
|
|
||||||
*/
|
|
||||||
public interface BankCardRepository extends JpaRepository<BankCard, Long>,
|
|
||||||
JpaSpecificationExecutor<BankCard> {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 按商家查询所有银行卡
|
|
||||||
*/
|
|
||||||
List<BankCard> findByMerchant_Id(Long merchantId);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 查询商家的默认卡
|
|
||||||
*/
|
|
||||||
Optional<BankCard> findByMerchant_IdAndIsDefaultTrue(Long merchantId);
|
|
||||||
}
|
|
||||||
|
|
@ -1,16 +0,0 @@
|
||||||
package com.xjhs.findmemerchant.repository;
|
|
||||||
|
|
||||||
import com.xjhs.findmemerchant.entity.BusinessLicense;
|
|
||||||
import org.springframework.data.jpa.repository.JpaRepository;
|
|
||||||
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Optional;
|
|
||||||
|
|
||||||
public interface BusinessLicenseRepository extends JpaRepository<BusinessLicense, Long>,
|
|
||||||
JpaSpecificationExecutor<BusinessLicense> {
|
|
||||||
|
|
||||||
List<BusinessLicense> findByMerchant_Id(Long merchantId);
|
|
||||||
|
|
||||||
Optional<BusinessLicense> findTopByMerchant_IdOrderByCreatedAtDesc(Long merchantId);
|
|
||||||
}
|
|
||||||
|
|
@ -1,24 +0,0 @@
|
||||||
package com.xjhs.findmemerchant.repository;
|
|
||||||
|
|
||||||
import com.xjhs.findmemerchant.entity.BusinessPeriod;
|
|
||||||
import org.springframework.data.jpa.repository.JpaRepository;
|
|
||||||
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 门店营业时间段仓储
|
|
||||||
*/
|
|
||||||
public interface BusinessPeriodRepository extends JpaRepository<BusinessPeriod, Long>,
|
|
||||||
JpaSpecificationExecutor<BusinessPeriod> {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 按门店查询所有营业时间段
|
|
||||||
*/
|
|
||||||
List<BusinessPeriod> findByStore_Id(Long storeId);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 按门店 + 周几查询启用的时间段
|
|
||||||
*/
|
|
||||||
List<BusinessPeriod> findByStore_IdAndDayOfWeekAndIsEnabledTrue(Long storeId, Byte dayOfWeek);
|
|
||||||
}
|
|
||||||
|
|
@ -1,30 +0,0 @@
|
||||||
package com.xjhs.findmemerchant.repository;
|
|
||||||
|
|
||||||
import com.xjhs.findmemerchant.entity.CouponCode;
|
|
||||||
import org.springframework.data.jpa.repository.JpaRepository;
|
|
||||||
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Optional;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 优惠券码仓储
|
|
||||||
*/
|
|
||||||
public interface CouponCodeRepository extends JpaRepository<CouponCode, Long>,
|
|
||||||
JpaSpecificationExecutor<CouponCode> {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 按券模板查询券码
|
|
||||||
*/
|
|
||||||
List<CouponCode> findByCoupon_Id(Long couponId);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 按会员查询券码
|
|
||||||
*/
|
|
||||||
List<CouponCode> findByMember_Id(Long memberId);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 按券码查询
|
|
||||||
*/
|
|
||||||
Optional<CouponCode> findByCode(String code);
|
|
||||||
}
|
|
||||||
|
|
@ -1,29 +0,0 @@
|
||||||
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;
|
|
||||||
import java.util.Optional;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 优惠券模板仓储
|
|
||||||
*/
|
|
||||||
public interface CouponRepository extends JpaRepository<Coupon, Long> {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 按商家查询优惠券
|
|
||||||
*/
|
|
||||||
List<Coupon> findByMerchant_Id(Long merchantId);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 按状态查询优惠券
|
|
||||||
*/
|
|
||||||
List<Coupon> findByStatus(CouponStatus status);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 按ID + 商家ID 查询(防越权)
|
|
||||||
*/
|
|
||||||
Optional<Coupon> findByIdAndMerchant_Id(Long id, Long merchantId);
|
|
||||||
}
|
|
||||||
|
|
@ -1,20 +0,0 @@
|
||||||
package com.xjhs.findmemerchant.repository;
|
|
||||||
|
|
||||||
import com.xjhs.findmemerchant.entity.CouponStore;
|
|
||||||
import org.springframework.data.jpa.repository.JpaRepository;
|
|
||||||
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Optional;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 优惠券与门店关联仓储
|
|
||||||
*/
|
|
||||||
public interface CouponStoreRepository extends JpaSpecificationExecutor<CouponStore>,JpaRepository<CouponStore, Long> {
|
|
||||||
|
|
||||||
List<CouponStore> findByCoupon_Id(Long couponId);
|
|
||||||
|
|
||||||
List<CouponStore> findByStore_Id(Long storeId);
|
|
||||||
|
|
||||||
Optional<CouponStore> findByCoupon_IdAndStore_Id(Long couponId, Long storeId);
|
|
||||||
}
|
|
||||||
|
|
@ -1,17 +0,0 @@
|
||||||
package com.xjhs.findmemerchant.repository;
|
|
||||||
|
|
||||||
import com.xjhs.findmemerchant.entity.Employee;
|
|
||||||
import org.springframework.data.jpa.repository.JpaRepository;
|
|
||||||
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Optional;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 员工仓储
|
|
||||||
*/
|
|
||||||
public interface EmployeeRepository extends JpaRepository<Employee, Long>,
|
|
||||||
JpaSpecificationExecutor<Employee> {
|
|
||||||
|
|
||||||
List<Employee> findByStoreId(Long storeId);
|
|
||||||
}
|
|
||||||
|
|
@ -1,15 +0,0 @@
|
||||||
package com.xjhs.findmemerchant.repository;
|
|
||||||
|
|
||||||
import com.xjhs.findmemerchant.entity.HealthCertificate;
|
|
||||||
import org.springframework.data.jpa.repository.JpaRepository;
|
|
||||||
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public interface HealthCertificateRepository extends JpaRepository<HealthCertificate, Long>,
|
|
||||||
JpaSpecificationExecutor<HealthCertificate> {
|
|
||||||
|
|
||||||
List<HealthCertificate> findByStore_Id(Long storeId);
|
|
||||||
|
|
||||||
List<HealthCertificate> findByEmployee_Id(Long employeeId);
|
|
||||||
}
|
|
||||||
|
|
@ -1,27 +0,0 @@
|
||||||
package com.xjhs.findmemerchant.repository;
|
|
||||||
|
|
||||||
import com.xjhs.findmemerchant.entity.Member;
|
|
||||||
import org.springframework.data.jpa.repository.JpaRepository;
|
|
||||||
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Optional;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 会员仓储
|
|
||||||
*/
|
|
||||||
public interface MemberRepository extends JpaRepository<Member, Long>,
|
|
||||||
JpaSpecificationExecutor<Member> {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 按商家查询会员
|
|
||||||
*/
|
|
||||||
List<Member> findByMerchant_Id(Long merchantId);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 按商家 + 手机号查询(唯一)
|
|
||||||
*/
|
|
||||||
Optional<Member> findByPhone(String phone);
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -6,16 +6,6 @@ import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
|
||||||
|
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
/**
|
public interface MerchantRepository extends JpaSpecificationExecutor<Merchant>, JpaRepository<Merchant,Long> {
|
||||||
* 商家仓储
|
Optional<Merchant> findBySystemUserPhone(String phone);
|
||||||
*/
|
|
||||||
public interface MerchantRepository extends JpaRepository<Merchant, Long>,
|
|
||||||
JpaSpecificationExecutor<Merchant> {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 根据手机号查询
|
|
||||||
*/
|
|
||||||
Optional<Merchant> findByPhone(String phone);
|
|
||||||
|
|
||||||
Boolean existsByPhone(String phone);
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,26 +0,0 @@
|
||||||
package com.xjhs.findmemerchant.repository;
|
|
||||||
|
|
||||||
import com.xjhs.findmemerchant.entity.Message;
|
|
||||||
import org.springframework.data.jpa.repository.JpaRepository;
|
|
||||||
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 消息仓储
|
|
||||||
*/
|
|
||||||
public interface MessageRepository extends JpaRepository<Message, Long>,
|
|
||||||
JpaSpecificationExecutor<Message> {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 按商家查询消息
|
|
||||||
*/
|
|
||||||
List<Message> findByMerchant_Id(Long merchantId);
|
|
||||||
|
|
||||||
List<Message> findByMerchant_IdAndIsRead(Long merchantId, Boolean isRead);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 统计未读消息数量
|
|
||||||
*/
|
|
||||||
long countByMerchant_IdAndIsRead(Long merchantId, Boolean isRead);
|
|
||||||
}
|
|
||||||
|
|
@ -1,21 +0,0 @@
|
||||||
package com.xjhs.findmemerchant.repository;
|
|
||||||
|
|
||||||
import com.xjhs.findmemerchant.entity.OrderItem;
|
|
||||||
import org.springframework.data.jpa.repository.JpaRepository;
|
|
||||||
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 订单明细仓储
|
|
||||||
*/
|
|
||||||
public interface OrderItemRepository extends JpaRepository<OrderItem, Long>,
|
|
||||||
JpaSpecificationExecutor<OrderItem> {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 按订单查询订单明细
|
|
||||||
*/
|
|
||||||
List<OrderItem> findByOrder_Id(Long orderId);
|
|
||||||
|
|
||||||
List<OrderItem> findByProductId(Long productId);
|
|
||||||
}
|
|
||||||
|
|
@ -1,27 +0,0 @@
|
||||||
package com.xjhs.findmemerchant.repository;
|
|
||||||
|
|
||||||
import com.xjhs.findmemerchant.entity.Order;
|
|
||||||
import org.springframework.data.jpa.repository.JpaRepository;
|
|
||||||
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Optional;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 订单仓储
|
|
||||||
*/
|
|
||||||
public interface OrderRepository extends JpaRepository<Order, Long>,
|
|
||||||
JpaSpecificationExecutor<Order> {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 按订单号查询(唯一)
|
|
||||||
*/
|
|
||||||
Optional<Order> findByOrderNo(String orderNo);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 按门店查询订单
|
|
||||||
*/
|
|
||||||
List<Order> findByStore_Id(Long storeId);
|
|
||||||
|
|
||||||
List<Order> findByMember_Id(Long memberId);
|
|
||||||
}
|
|
||||||
|
|
@ -1,24 +0,0 @@
|
||||||
package com.xjhs.findmemerchant.repository;
|
|
||||||
|
|
||||||
import com.xjhs.findmemerchant.entity.ProductCategory;
|
|
||||||
import org.springframework.data.jpa.repository.JpaRepository;
|
|
||||||
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 商品分类仓储
|
|
||||||
*/
|
|
||||||
public interface ProductCategoryRepository extends JpaRepository<ProductCategory, Long>,
|
|
||||||
JpaSpecificationExecutor<ProductCategory> {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 按商家查询所有分类
|
|
||||||
*/
|
|
||||||
List<ProductCategory> findByMerchant_Id(Long merchantId);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 查询某商家下指定父分类的子分类
|
|
||||||
*/
|
|
||||||
List<ProductCategory> findByMerchantIdAndParentId(Long merchantId, Long parentId);
|
|
||||||
}
|
|
||||||
|
|
@ -1,32 +0,0 @@
|
||||||
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;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 商品仓储
|
|
||||||
*/
|
|
||||||
public interface ProductRepository extends JpaRepository<Product, Long>,
|
|
||||||
JpaSpecificationExecutor<Product> {
|
|
||||||
|
|
||||||
List<Product> findByMerchant_Id(Long merchantId);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 按门店查询商品
|
|
||||||
*/
|
|
||||||
List<Product> findByStoreId(Long storeId);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 按分类查询商品
|
|
||||||
*/
|
|
||||||
List<Product> findByCategoryId(Long categoryId);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 按状态查询商品
|
|
||||||
*/
|
|
||||||
List<Product> findByStatus(ProductStatus status);
|
|
||||||
}
|
|
||||||
|
|
@ -1,24 +0,0 @@
|
||||||
package com.xjhs.findmemerchant.repository;
|
|
||||||
|
|
||||||
import com.xjhs.findmemerchant.entity.ProductSKU;
|
|
||||||
import org.springframework.data.jpa.repository.JpaRepository;
|
|
||||||
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 商品SKU仓储
|
|
||||||
*/
|
|
||||||
public interface ProductSKURepository extends JpaRepository<ProductSKU, Long>,
|
|
||||||
JpaSpecificationExecutor<ProductSKU> {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 查询商品下的所有SKU
|
|
||||||
*/
|
|
||||||
List<ProductSKU> findByProductId(Long productId);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 按编码查询
|
|
||||||
*/
|
|
||||||
List<ProductSKU> findBySkuCode(String skuCode);
|
|
||||||
}
|
|
||||||
|
|
@ -1,16 +0,0 @@
|
||||||
package com.xjhs.findmemerchant.repository;
|
|
||||||
|
|
||||||
import com.xjhs.findmemerchant.entity.ReviewReply;
|
|
||||||
import org.springframework.data.jpa.repository.JpaRepository;
|
|
||||||
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
|
|
||||||
|
|
||||||
import java.util.Optional;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 评价回复仓储
|
|
||||||
*/
|
|
||||||
public interface ReviewReplyRepository extends JpaRepository<ReviewReply, Long>,
|
|
||||||
JpaSpecificationExecutor<ReviewReply> {
|
|
||||||
|
|
||||||
Optional<ReviewReply> findByReviewId(Long reviewId);
|
|
||||||
}
|
|
||||||
|
|
@ -1,22 +0,0 @@
|
||||||
package com.xjhs.findmemerchant.repository;
|
|
||||||
|
|
||||||
import com.xjhs.findmemerchant.entity.Review;
|
|
||||||
import org.springframework.data.jpa.repository.JpaRepository;
|
|
||||||
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 用户评价仓储
|
|
||||||
*/
|
|
||||||
public interface ReviewRepository extends JpaRepository<Review, Long>,
|
|
||||||
JpaSpecificationExecutor<Review> {
|
|
||||||
|
|
||||||
List<Review> findByMerchant_Id(Long merchantId);
|
|
||||||
|
|
||||||
List<Review> findByStoreId(Long storeId);
|
|
||||||
|
|
||||||
List<Review> findByOrderId(Long orderId);
|
|
||||||
|
|
||||||
List<Review> findByUserId(Long userId);
|
|
||||||
}
|
|
||||||
|
|
@ -1,19 +0,0 @@
|
||||||
package com.xjhs.findmemerchant.repository;
|
|
||||||
|
|
||||||
import com.xjhs.findmemerchant.entity.Role;
|
|
||||||
import org.springframework.data.jpa.repository.JpaRepository;
|
|
||||||
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
|
|
||||||
|
|
||||||
import java.util.Optional;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 角色仓储
|
|
||||||
*/
|
|
||||||
public interface RoleRepository extends JpaRepository<Role, Long>,
|
|
||||||
JpaSpecificationExecutor<Role> {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 按编码查询角色
|
|
||||||
*/
|
|
||||||
Optional<Role> findByCode(String code);
|
|
||||||
}
|
|
||||||
|
|
@ -1,25 +0,0 @@
|
||||||
package com.xjhs.findmemerchant.repository;
|
|
||||||
|
|
||||||
import com.xjhs.findmemerchant.entity.Settlement;
|
|
||||||
import org.springframework.data.jpa.repository.JpaRepository;
|
|
||||||
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Optional;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 结算记录仓储
|
|
||||||
*/
|
|
||||||
public interface SettlementRepository extends JpaRepository<Settlement, Long>,
|
|
||||||
JpaSpecificationExecutor<Settlement> {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 按结算单号查询
|
|
||||||
*/
|
|
||||||
Optional<Settlement> findBySettlementNo(String settlementNo);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 按商家查询结算记录
|
|
||||||
*/
|
|
||||||
List<Settlement> findByMerchantId(Long merchantId);
|
|
||||||
}
|
|
||||||
|
|
@ -1,22 +0,0 @@
|
||||||
package com.xjhs.findmemerchant.repository;
|
|
||||||
|
|
||||||
import com.xjhs.findmemerchant.entity.Store;
|
|
||||||
import org.springframework.data.jpa.repository.JpaRepository;
|
|
||||||
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Optional;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 门店仓储
|
|
||||||
*/
|
|
||||||
public interface StoreRepository extends JpaRepository<Store, Long>,
|
|
||||||
JpaSpecificationExecutor<Store> {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 按商家查询门店
|
|
||||||
*/
|
|
||||||
List<Store> findByMerchantId(Long merchantId);
|
|
||||||
|
|
||||||
Optional<Store> findByMerchant_IdAndId(Long merchantId, Long id);
|
|
||||||
}
|
|
||||||
|
|
@ -1,24 +0,0 @@
|
||||||
package com.xjhs.findmemerchant.repository;
|
|
||||||
|
|
||||||
import com.xjhs.findmemerchant.entity.Transaction;
|
|
||||||
import org.springframework.data.jpa.repository.JpaRepository;
|
|
||||||
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 钱包交易流水仓储
|
|
||||||
*/
|
|
||||||
public interface TransactionRepository extends JpaRepository<Transaction, Long>,
|
|
||||||
JpaSpecificationExecutor<Transaction> {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 按钱包查询流水
|
|
||||||
*/
|
|
||||||
List<Transaction> findByWalletId(Long walletId);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 按商家查询流水
|
|
||||||
*/
|
|
||||||
List<Transaction> findByMerchantId(Long merchantId);
|
|
||||||
}
|
|
||||||
|
|
@ -1,19 +0,0 @@
|
||||||
package com.xjhs.findmemerchant.repository;
|
|
||||||
|
|
||||||
import com.xjhs.findmemerchant.entity.Wallet;
|
|
||||||
import org.springframework.data.jpa.repository.JpaRepository;
|
|
||||||
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
|
|
||||||
|
|
||||||
import java.util.Optional;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 商家钱包仓储
|
|
||||||
*/
|
|
||||||
public interface WalletRepository extends JpaRepository<Wallet, Long>,
|
|
||||||
JpaSpecificationExecutor<Wallet> {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 根据商家ID查询钱包(唯一)
|
|
||||||
*/
|
|
||||||
Optional<Wallet> findByMerchantId(Long merchantId);
|
|
||||||
}
|
|
||||||
|
|
@ -1,24 +0,0 @@
|
||||||
package com.xjhs.findmemerchant.repository;
|
|
||||||
|
|
||||||
import com.xjhs.findmemerchant.entity.Withdrawal;
|
|
||||||
import org.springframework.data.jpa.repository.JpaRepository;
|
|
||||||
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 提现仓储
|
|
||||||
*/
|
|
||||||
public interface WithdrawalRepository extends JpaRepository<Withdrawal, Long>,
|
|
||||||
JpaSpecificationExecutor<Withdrawal> {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 按商家查提现记录
|
|
||||||
*/
|
|
||||||
List<Withdrawal> findByMerchantId(Long merchantId);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 按钱包查提现记录
|
|
||||||
*/
|
|
||||||
List<Withdrawal> findByWalletId(Long walletId);
|
|
||||||
}
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
package com.xjhs.findmemerchant.security;
|
package com.xjhs.findmemerchant.security;
|
||||||
|
|
||||||
|
|
||||||
import com.xjhs.findmemerchant.repository.MemberRepository;
|
import com.xjhs.findmemerchant.mapper.SystemUserMapper;
|
||||||
import com.xjhs.findmemerchant.repository.MerchantRepository;
|
import com.xjhs.findmemerchant.repository.MerchantRepository;
|
||||||
import com.xjhs.findmemerchant.security.sms.SmsAuthenticationToken;
|
import com.xjhs.findmemerchant.security.sms.SmsAuthenticationToken;
|
||||||
import jakarta.servlet.FilterChain;
|
import jakarta.servlet.FilterChain;
|
||||||
|
|
@ -24,24 +24,18 @@ public class JwtAuthenticationFilter extends OncePerRequestFilter {
|
||||||
|
|
||||||
private final JwtTokenService jwtTokenService;
|
private final JwtTokenService jwtTokenService;
|
||||||
private final MerchantRepository merchantRepository;
|
private final MerchantRepository merchantRepository;
|
||||||
private final MemberRepository memberRepository;
|
private final SystemUserMapper systemUserMapper;
|
||||||
|
|
||||||
|
|
||||||
|
private SmsAuthenticationToken getAuthenticationToken(String phone) throws Exception {
|
||||||
private SmsAuthenticationToken getAuthenticationToken(String phone) throws Exception {
|
|
||||||
// 手机号查商家
|
// 手机号查商家
|
||||||
var merchant = merchantRepository.findByPhone(phone).orElse(null);
|
var merchant = merchantRepository.findBySystemUserPhone(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"));
|
||||||
return new SmsAuthenticationToken(merchant, authorities);
|
var loginUser = systemUserMapper.toLoginUserInfo(merchant.getSystemUser());
|
||||||
|
return new SmsAuthenticationToken(loginUser, authorities);
|
||||||
}
|
}
|
||||||
// 手机号查员工
|
throw new Exception("用户信息不存在");
|
||||||
var member = memberRepository.findByPhone(phone).orElse(null);
|
|
||||||
if(member != null){
|
|
||||||
var authorities = List.of(new SimpleGrantedAuthority("ROLE_MEMBER"));
|
|
||||||
return new SmsAuthenticationToken(member, authorities);
|
|
||||||
}
|
|
||||||
throw new Exception("用户信息不存在");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,23 @@
|
||||||
|
package com.xjhs.findmemerchant.security;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 登录用户信息
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class LoginUser {
|
||||||
|
/**
|
||||||
|
* 用户id
|
||||||
|
*/
|
||||||
|
private Long userId;
|
||||||
|
/**
|
||||||
|
* 手机号
|
||||||
|
*/
|
||||||
|
private String phone;
|
||||||
|
/**
|
||||||
|
* 关联商户id,不存在则为null
|
||||||
|
*/
|
||||||
|
private Long merchantId;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -1,25 +1,31 @@
|
||||||
package com.xjhs.findmemerchant.security.sms;
|
package com.xjhs.findmemerchant.security.sms;
|
||||||
|
|
||||||
import com.xjhs.findmemerchant.repository.MemberRepository;
|
import com.xjhs.findmemerchant.mapper.SystemUserMapper;
|
||||||
import com.xjhs.findmemerchant.repository.MerchantRepository;
|
import com.xjhs.findmemerchant.system.SystemUserService;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.security.authentication.AuthenticationProvider;
|
import org.springframework.security.authentication.AuthenticationProvider;
|
||||||
|
import org.springframework.security.authentication.CredentialsExpiredException;
|
||||||
import org.springframework.security.core.Authentication;
|
import org.springframework.security.core.Authentication;
|
||||||
import org.springframework.security.core.AuthenticationException;
|
import org.springframework.security.core.AuthenticationException;
|
||||||
import org.springframework.security.core.authority.SimpleGrantedAuthority;
|
import org.springframework.security.core.authority.SimpleGrantedAuthority;
|
||||||
import org.springframework.security.core.userdetails.UsernameNotFoundException;
|
import org.springframework.security.core.userdetails.UsernameNotFoundException;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
@Component
|
@Component
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
public class SmsAuthenticationProvider implements AuthenticationProvider {
|
public class SmsAuthenticationProvider implements AuthenticationProvider {
|
||||||
private final SmsCodeService smsCodeService;
|
private final SmsCodeService smsCodeService;
|
||||||
private final MerchantRepository merchantRepository;
|
private final SystemUserService systemUserService;
|
||||||
private final MemberRepository memberRepository;
|
private final SystemUserMapper systemUserMapper;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@Transactional(readOnly = true)
|
||||||
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
|
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
|
||||||
SmsAuthenticationToken token = (SmsAuthenticationToken) authentication;
|
SmsAuthenticationToken token = (SmsAuthenticationToken) authentication;
|
||||||
String phone = (String) token.getPrincipal();
|
String phone = (String) token.getPrincipal();
|
||||||
|
|
@ -27,21 +33,17 @@ public class SmsAuthenticationProvider implements AuthenticationProvider {
|
||||||
try {
|
try {
|
||||||
this.smsCodeService.verifyCode(phone,"login" ,code);
|
this.smsCodeService.verifyCode(phone,"login" ,code);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw new UsernameNotFoundException(e.getMessage());
|
throw new CredentialsExpiredException(e.getMessage());
|
||||||
}
|
}
|
||||||
// 手机号查商家
|
// 取回商家身份
|
||||||
var merchant = merchantRepository.findByPhone(phone).orElse(null);
|
var systemUser = systemUserService.getAndRegisterByPhone(phone);
|
||||||
if(merchant != null){
|
if (Objects.isNull(systemUser.getMerchant())){
|
||||||
var authorities = List.of(new SimpleGrantedAuthority("ROLE_USER"));
|
throw new UsernameNotFoundException("手机号码未注册");
|
||||||
return new SmsAuthenticationToken(merchant, authorities);
|
|
||||||
}
|
}
|
||||||
// 手机号查员工
|
|
||||||
var member = memberRepository.findByPhone(phone).orElse(null);
|
var loginUser = this.systemUserMapper.toLoginUserInfo(systemUser);
|
||||||
if(member != null){
|
var authorities = List.of(new SimpleGrantedAuthority("ADMIN"));
|
||||||
var authorities = List.of(new SimpleGrantedAuthority("ROLE_MEMBER"));
|
return new SmsAuthenticationToken(loginUser, authorities);
|
||||||
return new SmsAuthenticationToken(member, authorities);
|
|
||||||
}
|
|
||||||
throw new UsernameNotFoundException("用户信息不存在");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@ public class SmsCodeService {
|
||||||
private static final String SMS_CODE_KEY_PREFIX = "sms:code:";
|
private static final String SMS_CODE_KEY_PREFIX = "sms:code:";
|
||||||
|
|
||||||
/** 验证码有效期:5 分钟 */
|
/** 验证码有效期:5 分钟 */
|
||||||
private static final Duration SMS_CODE_TTL = Duration.ofMinutes(5);
|
private static final Duration SMS_CODE_TTL = Duration.ofMinutes(1);
|
||||||
|
|
||||||
private final StringRedisTemplate redisTemplate;
|
private final StringRedisTemplate redisTemplate;
|
||||||
private final Random random = new Random();
|
private final Random random = new Random();
|
||||||
|
|
@ -29,10 +29,10 @@ public class SmsCodeService {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 生成 6 位数字验证码
|
* 生成 4 位数字验证码
|
||||||
*/
|
*/
|
||||||
private String generateCode() {
|
private String generateCode() {
|
||||||
return String.format("%06d", random.nextInt(1_000_000));
|
return String.format("%04d", random.nextInt(10000));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -64,7 +64,6 @@ public class SmsCodeService {
|
||||||
// 对齐 Go 里的 ErrSMSCodeExpired
|
// 对齐 Go 里的 ErrSMSCodeExpired
|
||||||
throw new Exception("验证码已过期或未发送");
|
throw new Exception("验证码已过期或未发送");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!realCode.equals(inputCode)) {
|
if (!realCode.equals(inputCode)) {
|
||||||
// 不正确,但不删除,让用户继续尝试(错误次数由 AuthService 控制)
|
// 不正确,但不删除,让用户继续尝试(错误次数由 AuthService 控制)
|
||||||
throw new Exception("验证码错误");
|
throw new Exception("验证码错误");
|
||||||
|
|
|
||||||
|
|
@ -1,85 +0,0 @@
|
||||||
package com.xjhs.findmemerchant.service;
|
|
||||||
|
|
||||||
import com.xjhs.findmemerchant.dto.MerchantDto;
|
|
||||||
import com.xjhs.findmemerchant.mapper.MerchantMapper;
|
|
||||||
import com.xjhs.findmemerchant.repository.MerchantRepository;
|
|
||||||
import com.xjhs.findmemerchant.types.AuthStatus;
|
|
||||||
import com.xjhs.findmemerchant.vo.merchant.MerchantUpdateVo;
|
|
||||||
import jakarta.transaction.Transactional;
|
|
||||||
import lombok.RequiredArgsConstructor;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
import org.springframework.stereotype.Service;
|
|
||||||
|
|
||||||
import java.util.Optional;
|
|
||||||
|
|
||||||
@Slf4j
|
|
||||||
@Service
|
|
||||||
@RequiredArgsConstructor
|
|
||||||
public class MerchantService {
|
|
||||||
public final MerchantRepository merchantRepository;
|
|
||||||
public final MerchantMapper merchantMapper;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 根据商家id获取商家信息
|
|
||||||
* @param id 商家id
|
|
||||||
* @return 商家信息
|
|
||||||
*/
|
|
||||||
public Optional<MerchantDto> getById(Long id) {
|
|
||||||
return this.merchantRepository.findById(id)
|
|
||||||
.map(this.merchantMapper::toDto);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 更新商家信息
|
|
||||||
* @param id 商家id
|
|
||||||
* @param merchantUpdateVo 更新信息
|
|
||||||
* @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("商家信息不存在"));
|
|
||||||
entity.setRealName(merchantUpdateVo.getRealName());
|
|
||||||
this.merchantRepository.save(entity);
|
|
||||||
return this.merchantMapper.toDto(entity);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 商家身份证信息验证
|
|
||||||
*
|
|
||||||
* @param id 商家id
|
|
||||||
* @param idCardNo 身份证号
|
|
||||||
* @param realName 真实姓名
|
|
||||||
* @throws Exception 验证异常信息
|
|
||||||
*/
|
|
||||||
@Transactional(rollbackOn = Exception.class)
|
|
||||||
public MerchantDto verifyMerchant(Long id, String idCardNo, String realName) throws Exception {
|
|
||||||
var entity = this.merchantRepository.findById(id)
|
|
||||||
.orElseThrow(() -> new Exception("商家信息不存在"));
|
|
||||||
if (entity.getAuthStatus() == AuthStatus.VERIFIED) {
|
|
||||||
throw new Exception("商家信息已认证");
|
|
||||||
}
|
|
||||||
this.idCardVerify(idCardNo, realName);
|
|
||||||
entity.setAuthStatus(AuthStatus.VERIFIED);
|
|
||||||
entity.setIdCardNo(idCardNo);
|
|
||||||
entity.setIdCardEncrypted(idCardNo);
|
|
||||||
entity.setRealName(realName);
|
|
||||||
this.merchantRepository.save(entity);
|
|
||||||
return this.merchantMapper.toDto(entity);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 第三方验证
|
|
||||||
* @param idCardNo 身份证号码
|
|
||||||
* @param realName 真实姓名
|
|
||||||
* @throws Exception 验证失败信息
|
|
||||||
*/
|
|
||||||
public void idCardVerify(String idCardNo, String realName) throws Exception {
|
|
||||||
// TODO: 调用腾讯云身份证二要素核验接口
|
|
||||||
throw new Exception("验证失败,正在开发中");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -1,34 +0,0 @@
|
||||||
package com.xjhs.findmemerchant.service;
|
|
||||||
|
|
||||||
import com.xjhs.findmemerchant.common.jpa.query.JpaSpecs;
|
|
||||||
import com.xjhs.findmemerchant.dto.store.StoreDto;
|
|
||||||
import com.xjhs.findmemerchant.mapper.StoreMapper;
|
|
||||||
import com.xjhs.findmemerchant.repository.StoreRepository;
|
|
||||||
import lombok.RequiredArgsConstructor;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
import org.springframework.data.domain.Page;
|
|
||||||
import org.springframework.data.domain.Pageable;
|
|
||||||
import org.springframework.data.jpa.domain.Specification;
|
|
||||||
import org.springframework.stereotype.Service;
|
|
||||||
|
|
||||||
@Slf4j
|
|
||||||
@Service
|
|
||||||
@RequiredArgsConstructor
|
|
||||||
public class StoreService {
|
|
||||||
|
|
||||||
private final StoreRepository storeRepository;
|
|
||||||
private final StoreMapper storeMapper;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 分页查询
|
|
||||||
*
|
|
||||||
* @param pageable 分页参数
|
|
||||||
* @param merchantId 商家id
|
|
||||||
* @return 分页数据
|
|
||||||
*/
|
|
||||||
public Page<StoreDto> findPage(Pageable pageable, Long merchantId) {
|
|
||||||
return this.storeRepository.findAll(Specification.allOf(
|
|
||||||
JpaSpecs.eq("merchant.id", merchantId)
|
|
||||||
), pageable).map(this.storeMapper::toDto);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -0,0 +1,36 @@
|
||||||
|
package com.xjhs.findmemerchant.system;
|
||||||
|
|
||||||
|
import com.xjhs.findmemerchant.system.entity.SystemUser;
|
||||||
|
import com.xjhs.findmemerchant.system.repository.SystemUserRepository;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
@Service
|
||||||
|
@AllArgsConstructor
|
||||||
|
public class SystemUserService {
|
||||||
|
|
||||||
|
private final SystemUserRepository systemUserRepository;
|
||||||
|
/**
|
||||||
|
* 通过手机号获取用户信息,不存在则进行注册
|
||||||
|
*
|
||||||
|
* @param phone 手机号码
|
||||||
|
* @return 用户信息
|
||||||
|
*/
|
||||||
|
public SystemUser getAndRegisterByPhone(String phone) {
|
||||||
|
return this.systemUserRepository.findByPhoneAndDeleteTimeIsNull(phone)
|
||||||
|
.orElseGet(() -> {
|
||||||
|
var systemUser = new SystemUser();
|
||||||
|
systemUser.setPhone(phone);
|
||||||
|
return this.systemUserRepository.save(systemUser);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public Optional<SystemUser> findByPhone(String phone){
|
||||||
|
return this.systemUserRepository.findByPhoneAndDeleteTimeIsNull(phone);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,31 @@
|
||||||
|
package com.xjhs.findmemerchant.system.entity;
|
||||||
|
|
||||||
|
import com.xjhs.findmemerchant.common.jpa.AbstractBaseEntity;
|
||||||
|
import com.xjhs.findmemerchant.entity.Merchant;
|
||||||
|
import jakarta.persistence.*;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
import org.hibernate.annotations.Comment;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用户信息表
|
||||||
|
*/
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
@Entity
|
||||||
|
@Table
|
||||||
|
public class SystemUser extends AbstractBaseEntity {
|
||||||
|
@Column(columnDefinition = "CHAR(11)",length = 11)
|
||||||
|
@Comment("用户手机号")
|
||||||
|
private String phone;
|
||||||
|
@Column(length = 20)
|
||||||
|
@Comment("用户真实姓名")
|
||||||
|
private String realName;
|
||||||
|
@Column(length = 18)
|
||||||
|
@Comment("身份证号")
|
||||||
|
private String idCardNo;
|
||||||
|
@OneToOne(mappedBy = "systemUser",cascade = CascadeType.ALL)
|
||||||
|
private Merchant merchant;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
package com.xjhs.findmemerchant.system.repository;
|
||||||
|
|
||||||
|
import com.xjhs.findmemerchant.system.entity.SystemUser;
|
||||||
|
import org.springframework.data.jpa.repository.JpaRepository;
|
||||||
|
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
|
||||||
|
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
public interface SystemUserRepository extends JpaRepository<SystemUser,Long> , JpaSpecificationExecutor<SystemUser> {
|
||||||
|
Optional<SystemUser> findByPhoneAndDeleteTimeIsNull(String phone);
|
||||||
|
}
|
||||||
|
|
@ -1,52 +0,0 @@
|
||||||
package com.xjhs.findmemerchant.types;
|
|
||||||
|
|
||||||
import lombok.AllArgsConstructor;
|
|
||||||
import lombok.Getter;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 活动状态
|
|
||||||
* 0-未开始 1-进行中 2-已结束 3-已下架
|
|
||||||
*/
|
|
||||||
@Getter
|
|
||||||
@AllArgsConstructor
|
|
||||||
public enum ActivityStatus {
|
|
||||||
/**
|
|
||||||
* 未开始
|
|
||||||
*/
|
|
||||||
NOT_STARTED("未开始"),
|
|
||||||
/**
|
|
||||||
* 进行中
|
|
||||||
*/
|
|
||||||
ONGOING("进行中"),
|
|
||||||
/**
|
|
||||||
* 已结束
|
|
||||||
*/
|
|
||||||
ENDED("已结束"),
|
|
||||||
/**
|
|
||||||
* 已下架
|
|
||||||
*/
|
|
||||||
OFFLINE("已下架");
|
|
||||||
|
|
||||||
private final String desc;
|
|
||||||
|
|
||||||
public static ActivityStatus fromCode(Byte code) {
|
|
||||||
if (code == null) return null;
|
|
||||||
|
|
||||||
return switch (code) {
|
|
||||||
case 0 -> NOT_STARTED;
|
|
||||||
case 1 -> ONGOING;
|
|
||||||
case 2 -> ENDED;
|
|
||||||
case 3 -> OFFLINE;
|
|
||||||
default -> null;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
public byte code() {
|
|
||||||
return switch (this) {
|
|
||||||
case NOT_STARTED -> 0;
|
|
||||||
case ONGOING -> 1;
|
|
||||||
case ENDED -> 2;
|
|
||||||
case OFFLINE -> 3;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,44 +0,0 @@
|
||||||
package com.xjhs.findmemerchant.types;
|
|
||||||
|
|
||||||
import lombok.AllArgsConstructor;
|
|
||||||
import lombok.Getter;
|
|
||||||
|
|
||||||
@Getter
|
|
||||||
@AllArgsConstructor
|
|
||||||
public enum ActivityType {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 团购
|
|
||||||
*/
|
|
||||||
GROUP_BUY("团购"),
|
|
||||||
/**
|
|
||||||
* 折扣
|
|
||||||
*/
|
|
||||||
DISCOUNT("折扣"),
|
|
||||||
/**
|
|
||||||
* 限时优惠
|
|
||||||
*/
|
|
||||||
FLASH_SALE("限时优惠");
|
|
||||||
|
|
||||||
private final String desc;
|
|
||||||
|
|
||||||
// 数据库存储 tinyint -> 转为枚举
|
|
||||||
public static ActivityType fromCode(Byte code) {
|
|
||||||
if (code == null) return null;
|
|
||||||
return switch (code) {
|
|
||||||
case 1 -> GROUP_BUY;
|
|
||||||
case 2 -> DISCOUNT;
|
|
||||||
case 3 -> FLASH_SALE;
|
|
||||||
default -> null;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
// 枚举 -> 数据库存储值
|
|
||||||
public byte code() {
|
|
||||||
return switch (this) {
|
|
||||||
case GROUP_BUY -> 1;
|
|
||||||
case DISCOUNT -> 2;
|
|
||||||
case FLASH_SALE -> 3;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,40 +0,0 @@
|
||||||
package com.xjhs.findmemerchant.types;
|
|
||||||
|
|
||||||
import lombok.AllArgsConstructor;
|
|
||||||
import lombok.Getter;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 商家实名认证状态
|
|
||||||
* 0-未认证 1-已认证
|
|
||||||
*/
|
|
||||||
@Getter
|
|
||||||
@AllArgsConstructor
|
|
||||||
public enum AuthStatus {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 未认证
|
|
||||||
*/
|
|
||||||
NOT_VERIFIED("未认证"),
|
|
||||||
/**
|
|
||||||
* 已认证
|
|
||||||
*/
|
|
||||||
VERIFIED("已认证");
|
|
||||||
|
|
||||||
private final String desc;
|
|
||||||
|
|
||||||
public static AuthStatus fromCode(Byte code) {
|
|
||||||
if (code == null) return null;
|
|
||||||
return switch (code) {
|
|
||||||
case 0 -> NOT_VERIFIED;
|
|
||||||
case 1 -> VERIFIED;
|
|
||||||
default -> null;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
public byte code() {
|
|
||||||
return switch (this) {
|
|
||||||
case NOT_VERIFIED -> 0;
|
|
||||||
case VERIFIED -> 1;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,47 +0,0 @@
|
||||||
package com.xjhs.findmemerchant.types;
|
|
||||||
|
|
||||||
import lombok.AllArgsConstructor;
|
|
||||||
import lombok.Getter;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 营业执照审核状态
|
|
||||||
* 0-待审核 1-已通过 2-已拒绝
|
|
||||||
*/
|
|
||||||
@Getter
|
|
||||||
@AllArgsConstructor
|
|
||||||
public enum BusinessLicenseStatus {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 待审核
|
|
||||||
*/
|
|
||||||
PENDING("待审核"),
|
|
||||||
/**
|
|
||||||
* 已通过
|
|
||||||
*/
|
|
||||||
APPROVED("已通过"),
|
|
||||||
/**
|
|
||||||
* 已拒绝
|
|
||||||
*/
|
|
||||||
REJECTED("已拒绝");
|
|
||||||
|
|
||||||
private final String desc;
|
|
||||||
|
|
||||||
public static BusinessLicenseStatus fromCode(Byte code) {
|
|
||||||
if (code == null) return null;
|
|
||||||
|
|
||||||
return switch (code) {
|
|
||||||
case 0 -> PENDING;
|
|
||||||
case 1 -> APPROVED;
|
|
||||||
case 2 -> REJECTED;
|
|
||||||
default -> null;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
public byte code() {
|
|
||||||
return switch (this) {
|
|
||||||
case PENDING -> 0;
|
|
||||||
case APPROVED -> 1;
|
|
||||||
case REJECTED -> 2;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,46 +0,0 @@
|
||||||
package com.xjhs.findmemerchant.types;
|
|
||||||
|
|
||||||
import lombok.AllArgsConstructor;
|
|
||||||
import lombok.Getter;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 门店营业状态
|
|
||||||
* 1-营业中 0-已打烊 2-临时打烊
|
|
||||||
*/
|
|
||||||
@Getter
|
|
||||||
@AllArgsConstructor
|
|
||||||
public enum BusinessStatus {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 已打烊
|
|
||||||
*/
|
|
||||||
CLOSED("已打烊"), // 0
|
|
||||||
/**
|
|
||||||
* 营业中
|
|
||||||
*/
|
|
||||||
OPEN("营业中"), // 1
|
|
||||||
/**
|
|
||||||
* 临时打烊
|
|
||||||
*/
|
|
||||||
TEMP_CLOSED("临时打烊"); // 2
|
|
||||||
|
|
||||||
private final String desc;
|
|
||||||
|
|
||||||
public static BusinessStatus fromCode(Byte code) {
|
|
||||||
if (code == null) return null;
|
|
||||||
return switch (code) {
|
|
||||||
case 0 -> CLOSED;
|
|
||||||
case 1 -> OPEN;
|
|
||||||
case 2 -> TEMP_CLOSED;
|
|
||||||
default -> null;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
public byte code() {
|
|
||||||
return switch (this) {
|
|
||||||
case CLOSED -> 0;
|
|
||||||
case OPEN -> 1;
|
|
||||||
case TEMP_CLOSED -> 2;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,40 +0,0 @@
|
||||||
package com.xjhs.findmemerchant.types;
|
|
||||||
|
|
||||||
import lombok.AllArgsConstructor;
|
|
||||||
import lombok.Getter;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 通用启用/禁用状态
|
|
||||||
* 0-禁用 1-启用
|
|
||||||
*/
|
|
||||||
@Getter
|
|
||||||
@AllArgsConstructor
|
|
||||||
public enum CommonStatus {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 禁用
|
|
||||||
*/
|
|
||||||
DISABLED("禁用"),
|
|
||||||
/**
|
|
||||||
* 启用
|
|
||||||
*/
|
|
||||||
ENABLED("启用");
|
|
||||||
|
|
||||||
private final String desc;
|
|
||||||
|
|
||||||
public static CommonStatus fromCode(Byte code) {
|
|
||||||
if (code == null) return null;
|
|
||||||
return switch (code) {
|
|
||||||
case 0 -> DISABLED;
|
|
||||||
case 1 -> ENABLED;
|
|
||||||
default -> null;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
public byte code() {
|
|
||||||
return switch (this) {
|
|
||||||
case DISABLED -> 0;
|
|
||||||
case ENABLED -> 1;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,46 +0,0 @@
|
||||||
package com.xjhs.findmemerchant.types;
|
|
||||||
|
|
||||||
import lombok.AllArgsConstructor;
|
|
||||||
import lombok.Getter;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 券码状态
|
|
||||||
* 0-未领取 1-已领取 2-已核销 3-已过期
|
|
||||||
*/
|
|
||||||
@Getter
|
|
||||||
@AllArgsConstructor
|
|
||||||
public enum CouponCodeStatus {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 未领取
|
|
||||||
*/
|
|
||||||
UNCLAIMED("未领取"),
|
|
||||||
/**
|
|
||||||
* 已领取
|
|
||||||
*/
|
|
||||||
CLAIMED("已领取"),
|
|
||||||
/**
|
|
||||||
* 已核销
|
|
||||||
*/
|
|
||||||
VERIFIED("已核销"),
|
|
||||||
/**
|
|
||||||
* 已过期
|
|
||||||
*/
|
|
||||||
EXPIRED("已过期");
|
|
||||||
|
|
||||||
private final String desc;
|
|
||||||
|
|
||||||
|
|
||||||
public static CouponCodeStatus fromCode(Byte code) {
|
|
||||||
if (code == null) return null;
|
|
||||||
return switch (code) {
|
|
||||||
case 0 -> UNCLAIMED;
|
|
||||||
case 1 -> CLAIMED;
|
|
||||||
case 2 -> VERIFIED;
|
|
||||||
case 3 -> EXPIRED;
|
|
||||||
default -> null;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -1,46 +0,0 @@
|
||||||
package com.xjhs.findmemerchant.types;
|
|
||||||
|
|
||||||
import lombok.AllArgsConstructor;
|
|
||||||
import lombok.Getter;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 优惠券状态
|
|
||||||
* 0-下架 1-进行中 2-已结束
|
|
||||||
*/
|
|
||||||
@Getter
|
|
||||||
@AllArgsConstructor
|
|
||||||
public enum CouponStatus {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 下架
|
|
||||||
*/
|
|
||||||
OFFLINE("下架"),
|
|
||||||
/**
|
|
||||||
* 进行中
|
|
||||||
*/
|
|
||||||
ONLINE("进行中"),
|
|
||||||
/**
|
|
||||||
* 已结束
|
|
||||||
*/
|
|
||||||
ENDED("已结束");
|
|
||||||
|
|
||||||
private final String desc;
|
|
||||||
|
|
||||||
public static CouponStatus fromCode(Byte code) {
|
|
||||||
if (code == null) return null;
|
|
||||||
return switch (code) {
|
|
||||||
case 0 -> OFFLINE;
|
|
||||||
case 1 -> ONLINE;
|
|
||||||
case 2 -> ENDED;
|
|
||||||
default -> null;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
public byte code() {
|
|
||||||
return switch (this) {
|
|
||||||
case OFFLINE -> 0;
|
|
||||||
case ONLINE -> 1;
|
|
||||||
case ENDED -> 2;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,58 +0,0 @@
|
||||||
package com.xjhs.findmemerchant.types;
|
|
||||||
|
|
||||||
import lombok.AllArgsConstructor;
|
|
||||||
import lombok.Getter;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 优惠券类型
|
|
||||||
* 1-折扣券 2-满减券 3-现金券 4-赠品券
|
|
||||||
*/
|
|
||||||
@Getter
|
|
||||||
@AllArgsConstructor
|
|
||||||
public enum CouponType {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 折扣券
|
|
||||||
*/
|
|
||||||
DISCOUNT("折扣券"),
|
|
||||||
/**
|
|
||||||
* 满减券
|
|
||||||
*/
|
|
||||||
REDUCE("满减券"),
|
|
||||||
/**
|
|
||||||
* 现金券
|
|
||||||
*/
|
|
||||||
CASH("现金券"),
|
|
||||||
/**
|
|
||||||
* 赠品券
|
|
||||||
*/
|
|
||||||
GIFT("赠品券");
|
|
||||||
|
|
||||||
private final String desc;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 数据库 tinyint -> 枚举
|
|
||||||
*/
|
|
||||||
public static CouponType fromCode(Byte code) {
|
|
||||||
if (code == null) return null;
|
|
||||||
return switch (code) {
|
|
||||||
case 1 -> DISCOUNT;
|
|
||||||
case 2 -> REDUCE;
|
|
||||||
case 3 -> CASH;
|
|
||||||
case 4 -> GIFT;
|
|
||||||
default -> null;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 枚举 -> 数据库 tinyint
|
|
||||||
*/
|
|
||||||
public byte code() {
|
|
||||||
return switch (this) {
|
|
||||||
case DISCOUNT -> 1;
|
|
||||||
case REDUCE -> 2;
|
|
||||||
case CASH -> 3;
|
|
||||||
case GIFT -> 4;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,47 +0,0 @@
|
||||||
package com.xjhs.findmemerchant.types;
|
|
||||||
|
|
||||||
import lombok.AllArgsConstructor;
|
|
||||||
import lombok.Getter;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 健康证状态
|
|
||||||
* 0-待审核 1-有效 2-过期
|
|
||||||
*/
|
|
||||||
@Getter
|
|
||||||
@AllArgsConstructor
|
|
||||||
public enum HealthCertificateStatus {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 待审核
|
|
||||||
*/
|
|
||||||
PENDING("待审核"),
|
|
||||||
/**
|
|
||||||
* 有效
|
|
||||||
*/
|
|
||||||
VALID("有效"),
|
|
||||||
/**
|
|
||||||
* 已过期
|
|
||||||
*/
|
|
||||||
EXPIRED("已过期");
|
|
||||||
|
|
||||||
private final String desc;
|
|
||||||
|
|
||||||
public static HealthCertificateStatus fromCode(Byte code) {
|
|
||||||
if (code == null) return null;
|
|
||||||
|
|
||||||
return switch (code) {
|
|
||||||
case 0 -> PENDING;
|
|
||||||
case 1 -> VALID;
|
|
||||||
case 2 -> EXPIRED;
|
|
||||||
default -> null;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
public byte code() {
|
|
||||||
return switch (this) {
|
|
||||||
case PENDING -> 0;
|
|
||||||
case VALID -> 1;
|
|
||||||
case EXPIRED -> 2;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,46 +0,0 @@
|
||||||
package com.xjhs.findmemerchant.types;
|
|
||||||
|
|
||||||
import lombok.AllArgsConstructor;
|
|
||||||
import lombok.Getter;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 消息类型
|
|
||||||
* 1-系统通知 2-活动提醒 3-私信
|
|
||||||
*/
|
|
||||||
@Getter
|
|
||||||
@AllArgsConstructor
|
|
||||||
public enum MessageType {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 系统通知
|
|
||||||
*/
|
|
||||||
SYSTEM("系统通知"),
|
|
||||||
/**
|
|
||||||
* 活动提醒
|
|
||||||
*/
|
|
||||||
ACTIVITY("活动提醒"),
|
|
||||||
/**
|
|
||||||
* 私信
|
|
||||||
*/
|
|
||||||
PRIVATE("私信");
|
|
||||||
|
|
||||||
private final String desc;
|
|
||||||
|
|
||||||
public static MessageType fromCode(Byte code) {
|
|
||||||
if (code == null) return null;
|
|
||||||
return switch (code) {
|
|
||||||
case 1 -> SYSTEM;
|
|
||||||
case 2 -> ACTIVITY;
|
|
||||||
case 3 -> PRIVATE;
|
|
||||||
default -> null;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
public byte code() {
|
|
||||||
return switch (this) {
|
|
||||||
case SYSTEM -> 1;
|
|
||||||
case ACTIVITY -> 2;
|
|
||||||
case PRIVATE -> 3;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue