refactor(user-center): 移除收货地址管理相关代码和配置
This commit is contained in:
@@ -1,100 +0,0 @@
|
||||
# xlxumu Java后端项目
|
||||
|
||||
## 项目结构
|
||||
|
||||
```
|
||||
backend-java/
|
||||
├── api/ # API定义
|
||||
├── common/ # 公共模块
|
||||
├── config-server/ # 配置服务器
|
||||
├── docs/ # 文档
|
||||
├── gateway/ # 网关服务
|
||||
├── registry/ # 服务注册中心
|
||||
├── scripts/ # 脚本
|
||||
└── services/ # 微服务
|
||||
├── ai-service/ # AI服务
|
||||
├── data-platform-service/ # 数据平台服务
|
||||
├── farming-service/ # 农业管理服务 (端口: 8081)
|
||||
├── finance-service/ # 金融服务
|
||||
├── government-service/ # 政府监管服务
|
||||
├── mall-service/ # 商城服务
|
||||
├── trade-service/ # 交易服务
|
||||
└── user-center-service/ # 用户中心服务 (端口: 8082)
|
||||
```
|
||||
|
||||
## 技术栈
|
||||
|
||||
- Java 8+
|
||||
- Spring Boot 2.7.x
|
||||
- Spring Cloud 2021.x
|
||||
- Maven 3.8.x
|
||||
- MySQL 8.0
|
||||
|
||||
## 环境要求
|
||||
|
||||
1. JDK 8或更高版本
|
||||
2. Maven 3.8或更高版本
|
||||
3. MySQL 8.0
|
||||
|
||||
## 快速开始
|
||||
|
||||
### 1. 安装依赖
|
||||
|
||||
```bash
|
||||
# 在backend-java根目录下执行
|
||||
mvn clean install
|
||||
```
|
||||
|
||||
### 2. 配置数据库
|
||||
|
||||
确保MySQL服务正在运行,并创建相应的数据库:
|
||||
|
||||
```sql
|
||||
CREATE DATABASE IF NOT EXISTS xlxumu_farming;
|
||||
CREATE DATABASE IF NOT EXISTS xlxumu_user;
|
||||
```
|
||||
|
||||
### 3. 运行服务
|
||||
|
||||
#### 运行farming-service
|
||||
|
||||
```bash
|
||||
cd services/farming-service
|
||||
mvn spring-boot:run
|
||||
```
|
||||
|
||||
服务将在 http://localhost:8081 启动
|
||||
|
||||
#### 运行user-center-service
|
||||
|
||||
```bash
|
||||
cd services/user-center-service
|
||||
mvn spring-boot:run
|
||||
```
|
||||
|
||||
服务将在 http://localhost:8082 启动
|
||||
|
||||
## 服务端口分配
|
||||
|
||||
| 服务名称 | 端口 |
|
||||
|---------|------|
|
||||
| farming-service | 8081 |
|
||||
| user-center-service | 8082 |
|
||||
|
||||
## 开发指南
|
||||
|
||||
1. 所有微服务都继承自根pom.xml
|
||||
2. 每个服务都有独立的数据库
|
||||
3. 使用Spring Boot Actuator进行健康检查
|
||||
4. 使用Spring Cloud Gateway作为API网关
|
||||
|
||||
## 构建和部署
|
||||
|
||||
```bash
|
||||
# 构建所有服务
|
||||
mvn clean package
|
||||
|
||||
# 构建单个服务
|
||||
cd services/farming-service
|
||||
mvn clean package
|
||||
```
|
||||
@@ -1,63 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
|
||||
http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<groupId>com.xlxumu</groupId>
|
||||
<artifactId>backend-java</artifactId>
|
||||
<version>1.0.0</version>
|
||||
<packaging>pom</packaging>
|
||||
|
||||
<name>XlMuMu Backend Java</name>
|
||||
<description>锡林郭勒盟地区智慧养殖产业平台后端Java服务</description>
|
||||
|
||||
<modules>
|
||||
<module>api</module>
|
||||
<module>gateway</module>
|
||||
<module>registry</module>
|
||||
<module>config-server</module>
|
||||
<module>services</module>
|
||||
<module>common</module>
|
||||
</modules>
|
||||
|
||||
<properties>
|
||||
<maven.compiler.source>1.8</maven.compiler.source>
|
||||
<maven.compiler.target>1.8</maven.compiler.target>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<spring.boot.version>2.7.5</spring.boot.version>
|
||||
<spring.cloud.version>2021.0.5</spring.cloud.version>
|
||||
</properties>
|
||||
|
||||
<dependencyManagement>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-dependencies</artifactId>
|
||||
<version>${spring.boot.version}</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-dependencies</artifactId>
|
||||
<version>${spring.cloud.version}</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</dependencyManagement>
|
||||
|
||||
<build>
|
||||
<pluginManagement>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
<version>${spring.boot.version}</version>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</pluginManagement>
|
||||
</build>
|
||||
</project>
|
||||
@@ -1,53 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
|
||||
http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<parent>
|
||||
<groupId>com.xlxumu</groupId>
|
||||
<artifactId>backend-java</artifactId>
|
||||
<version>1.0.0</version>
|
||||
</parent>
|
||||
|
||||
<artifactId=ai-service</artifactId>
|
||||
<version>1.0.0</version>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<name=ai-service</name>
|
||||
<description>AI能力服务</description>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-data-jpa</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>mysql</groupId>
|
||||
<artifactId>mysql-connector-java</artifactId>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
@@ -1,11 +0,0 @@
|
||||
package com.xlxumu.ai;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
|
||||
@SpringBootApplication
|
||||
public class AIServiceApplication {
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(AIServiceApplication.class, args);
|
||||
}
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
server.port=8089
|
||||
|
||||
spring.datasource.url=jdbc:mysql://localhost:3306/xlxumu_ai?useSSL=false&serverTimezone=UTC
|
||||
spring.datasource.username=root
|
||||
spring.datasource.password=
|
||||
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
|
||||
|
||||
spring.jpa.hibernate.ddl-auto=update
|
||||
spring.jpa.show-sql=true
|
||||
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL8Dialect
|
||||
@@ -1,53 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
|
||||
http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<parent>
|
||||
<groupId>com.xlxumu</groupId>
|
||||
<artifactId>backend-java</artifactId>
|
||||
<version>1.0.0</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>data-platform-service</artifactId>
|
||||
<version>1.0.0</version>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<name>data-platform-service</name>
|
||||
<description>数据平台服务</description>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-data-jpa</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>mysql</groupId>
|
||||
<artifactId>mysql-connector-java</artifactId>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
@@ -1,11 +0,0 @@
|
||||
package com.xlxumu.dataplatform;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
|
||||
@SpringBootApplication
|
||||
public class DataPlatformServiceApplication {
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(DataPlatformServiceApplication.class, args);
|
||||
}
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
server.port=8085
|
||||
|
||||
spring.datasource.url=jdbc:mysql://localhost:3306/xlxumu_data?useSSL=false&serverTimezone=UTC
|
||||
spring.datasource.username=root
|
||||
spring.datasource.password=
|
||||
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
|
||||
|
||||
spring.jpa.hibernate.ddl-auto=update
|
||||
spring.jpa.show-sql=true
|
||||
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL8Dialect
|
||||
@@ -1,43 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
|
||||
http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<parent>
|
||||
<groupId>com.xlxumu</groupId>
|
||||
<artifactId>backend-java</artifactId>
|
||||
<version>1.0.0</version>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
<artifactId>farming-service</artifactId>
|
||||
<name>Farming Service</name>
|
||||
<description>养殖管理服务</description>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-data-jpa</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>mysql</groupId>
|
||||
<artifactId>mysql-connector-java</artifactId>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
@@ -1,11 +0,0 @@
|
||||
package com.xlxumu.farm;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
|
||||
@SpringBootApplication
|
||||
public class FarmingServiceApplication {
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(FarmingServiceApplication.class, args);
|
||||
}
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
server.port=8081
|
||||
|
||||
spring.datasource.url=jdbc:mysql://localhost:3306/xlxumu_farming?useSSL=false&serverTimezone=UTC
|
||||
spring.datasource.username=root
|
||||
spring.datasource.password=
|
||||
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
|
||||
|
||||
spring.jpa.hibernate.ddl-auto=update
|
||||
spring.jpa.show-sql=true
|
||||
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL8Dialect
|
||||
@@ -1,10 +0,0 @@
|
||||
server.port=8081
|
||||
|
||||
spring.datasource.url=jdbc:mysql://localhost:3306/xlxumu_farming?useSSL=false&serverTimezone=UTC
|
||||
spring.datasource.username=root
|
||||
spring.datasource.password=
|
||||
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
|
||||
|
||||
spring.jpa.hibernate.ddl-auto=update
|
||||
spring.jpa.show-sql=true
|
||||
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL8Dialect
|
||||
Binary file not shown.
Binary file not shown.
@@ -1,3 +0,0 @@
|
||||
artifactId=farming-service
|
||||
groupId=com.xlxumu
|
||||
version=1.0.0
|
||||
@@ -1 +0,0 @@
|
||||
com/xlxumu/farm/FarmingServiceApplication.class
|
||||
@@ -1 +0,0 @@
|
||||
/Users/ainongkeji/code/vue/xlxumu/backend-java/services/farming-service/src/main/java/com/xlxumu/farm/FarmingServiceApplication.java
|
||||
@@ -1,53 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
|
||||
http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<parent>
|
||||
<groupId>com.xlxumu</groupId>
|
||||
<artifactId>backend-java</artifactId>
|
||||
<version>1.0.0</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>finance-service</artifactId>
|
||||
<version>1.0.0</version>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<name>finance-service</name>
|
||||
<description>金融服务</description>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-data-jpa</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>mysql</groupId>
|
||||
<artifactId>mysql-connector-java</artifactId>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
@@ -1,11 +0,0 @@
|
||||
package com.xlxumu.finance;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
|
||||
@SpringBootApplication
|
||||
public class FinanceServiceApplication {
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(FinanceServiceApplication.class, args);
|
||||
}
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
server.port=8084
|
||||
|
||||
spring.datasource.url=jdbc:mysql://localhost:3306/xlxumu_finance?useSSL=false&serverTimezone=UTC
|
||||
spring.datasource.username=root
|
||||
spring.datasource.password=
|
||||
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
|
||||
|
||||
spring.jpa.hibernate.ddl-auto=update
|
||||
spring.jpa.show-sql=true
|
||||
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL8Dialect
|
||||
@@ -1,53 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
|
||||
http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<parent>
|
||||
<groupId>com.xlxumu</groupId>
|
||||
<artifactId>backend-java</artifactId>
|
||||
<version>1.0.0</version>
|
||||
</parent>
|
||||
|
||||
<artifactId=government-service</artifactId>
|
||||
<version>1.0.0</version>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<name=government-service</name>
|
||||
<description>政务服务</description>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-data-jpa</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>mysql</groupId>
|
||||
<artifactId>mysql-connector-java</artifactId>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
@@ -1,11 +0,0 @@
|
||||
package com.xlxumu.government;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
|
||||
@SpringBootApplication
|
||||
public class GovernmentServiceApplication {
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(GovernmentServiceApplication.class, args);
|
||||
}
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
server.port=8086
|
||||
|
||||
spring.datasource.url=jdbc:mysql://localhost:3306/xlxumu_government?useSSL=false&serverTimezone=UTC
|
||||
spring.datasource.username=root
|
||||
spring.datasource.password=
|
||||
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
|
||||
|
||||
spring.jpa.hibernate.ddl-auto=update
|
||||
spring.jpa.show-sql=true
|
||||
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL8Dialect
|
||||
@@ -1,53 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
|
||||
http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<parent>
|
||||
<groupId>com.xlxumu</groupId>
|
||||
<artifactId>backend-java</artifactId>
|
||||
<version>1.0.0</version>
|
||||
</parent>
|
||||
|
||||
<artifactId=mall-service</artifactId>
|
||||
<version>1.0.0</version>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<name=mall-service</name>
|
||||
<description>商城服务</description>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-data-jpa</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>mysql</groupId>
|
||||
<artifactId>mysql-connector-java</artifactId>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
@@ -1,11 +0,0 @@
|
||||
package com.xlxumu.mall;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
|
||||
@SpringBootApplication
|
||||
public class MallServiceApplication {
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(MallServiceApplication.class, args);
|
||||
}
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
server.port=8088
|
||||
|
||||
spring.datasource.url=jdbc:mysql://localhost:3306/xlxumu_mall?useSSL=false&serverTimezone=UTC
|
||||
spring.datasource.username=root
|
||||
spring.datasource.password=
|
||||
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
|
||||
|
||||
spring.jpa.hibernate.ddl-auto=update
|
||||
spring.jpa.show-sql=true
|
||||
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL8Dialect
|
||||
@@ -1,53 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
|
||||
http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<parent>
|
||||
<groupId>com.xlxumu</groupId>
|
||||
<artifactId>backend-java</artifactId>
|
||||
<version>1.0.0</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>trade-service</artifactId>
|
||||
<version>1.0.0</version>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<name>trade-service</name>
|
||||
<description>交易服务</description>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-data-jpa</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>mysql</groupId>
|
||||
<artifactId>mysql-connector-java</artifactId>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
@@ -1,11 +0,0 @@
|
||||
package com.xlxumu.trade;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
|
||||
@SpringBootApplication
|
||||
public class TradeServiceApplication {
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(TradeServiceApplication.class, args);
|
||||
}
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
server.port=8083
|
||||
|
||||
spring.datasource.url=jdbc:mysql://localhost:3306/xlxumu_trade?useSSL=false&serverTimezone=UTC
|
||||
spring.datasource.username=root
|
||||
spring.datasource.password=
|
||||
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
|
||||
|
||||
spring.jpa.hibernate.ddl-auto=update
|
||||
spring.jpa.show-sql=true
|
||||
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL8Dialect
|
||||
@@ -1,44 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<parent>
|
||||
<groupId>com.xlxumu</groupId>
|
||||
<artifactId>backend-java</artifactId>
|
||||
<version>1.0.0</version>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
<artifactId>user-center-service</artifactId>
|
||||
<version>1.0.0</version>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-data-jpa</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>mysql</groupId>
|
||||
<artifactId>mysql-connector-java</artifactId>
|
||||
<version>8.0.33</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
@@ -1,11 +0,0 @@
|
||||
package com.xlxumu.user;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
|
||||
@SpringBootApplication
|
||||
public class UserCenterApplication {
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(UserCenterApplication.class, args);
|
||||
}
|
||||
}
|
||||
@@ -1,47 +0,0 @@
|
||||
package com.xlxumu.user.config;
|
||||
|
||||
import com.xlxumu.user.util.JwtUtil;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.servlet.HandlerInterceptor;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
|
||||
@Component
|
||||
public class JwtInterceptor implements HandlerInterceptor {
|
||||
|
||||
@Autowired
|
||||
private JwtUtil jwtUtil;
|
||||
|
||||
@Override
|
||||
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws IOException {
|
||||
// 获取请求头中的Authorization字段
|
||||
String authorizationHeader = request.getHeader("Authorization");
|
||||
|
||||
// 检查Authorization字段是否存在且以"Bearer "开头
|
||||
if (authorizationHeader != null && authorizationHeader.startsWith("Bearer ")) {
|
||||
// 提取JWT令牌
|
||||
String token = authorizationHeader.substring(7);
|
||||
|
||||
try {
|
||||
// 验证令牌
|
||||
Long userId = jwtUtil.getUserIdFromToken(token);
|
||||
// 将用户ID添加到请求属性中,以便在控制器中使用
|
||||
request.setAttribute("userId", userId);
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
// 令牌无效
|
||||
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
|
||||
response.getWriter().write("{\"code\": 401, \"message\": \"无效的访问令牌\"}");
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
// 缺少Authorization字段或格式不正确
|
||||
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
|
||||
response.getWriter().write("{\"code\": 401, \"message\": \"缺少访问令牌\"}");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,22 +0,0 @@
|
||||
package com.xlxumu.user.config;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
|
||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
||||
|
||||
@Configuration
|
||||
public class WebConfig implements WebMvcConfigurer {
|
||||
|
||||
@Autowired
|
||||
private JwtInterceptor jwtInterceptor;
|
||||
|
||||
@Override
|
||||
public void addInterceptors(InterceptorRegistry registry) {
|
||||
// 注册JWT拦截器,拦截除了注册和登录之外的所有API请求
|
||||
registry.addInterceptor(jwtInterceptor)
|
||||
.addPathPatterns("/api/**")
|
||||
.excludePathPatterns("/api/users/register")
|
||||
.excludePathPatterns("/api/users/login");
|
||||
}
|
||||
}
|
||||
@@ -1,175 +0,0 @@
|
||||
package com.xlxumu.user.controller;
|
||||
|
||||
import com.xlxumu.user.entity.Address;
|
||||
import com.xlxumu.user.service.AddressService;
|
||||
import com.xlxumu.user.util.JwtTokenUtil;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 收货地址控制器
|
||||
* 处理收货地址相关的HTTP请求
|
||||
*
|
||||
* @author xlxumu
|
||||
* @since 2024-01-15
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/api/addresses")
|
||||
public class AddressController {
|
||||
|
||||
@Autowired
|
||||
private AddressService addressService;
|
||||
|
||||
@Autowired
|
||||
private JwtTokenUtil jwtTokenUtil;
|
||||
|
||||
/**
|
||||
* 创建收货地址接口
|
||||
*/
|
||||
@PostMapping
|
||||
public ResponseEntity<Map<String, Object>> createAddress(
|
||||
HttpServletRequest request,
|
||||
@RequestBody Map<String, Object> requestData) {
|
||||
// 从JWT令牌中获取用户ID
|
||||
Long userId = jwtTokenUtil.getUserIdFromRequest(request);
|
||||
if (userId == null) {
|
||||
Map<String, Object> errorResponse = new HashMap<>();
|
||||
errorResponse.put("code", 401);
|
||||
errorResponse.put("message", "无效的访问令牌");
|
||||
return ResponseEntity.status(401).body(errorResponse);
|
||||
}
|
||||
|
||||
String name = (String) requestData.get("name");
|
||||
String phone = (String) requestData.get("phone");
|
||||
String province = (String) requestData.get("province");
|
||||
String city = (String) requestData.get("city");
|
||||
String district = (String) requestData.get("district");
|
||||
String detailAddress = (String) requestData.get("detailAddress");
|
||||
Boolean isDefault = (Boolean) requestData.get("isDefault");
|
||||
|
||||
Address address = addressService.createAddress(userId, name, phone, province, city, district, detailAddress, isDefault);
|
||||
|
||||
Map<String, Object> response = new HashMap<>();
|
||||
response.put("code", 200);
|
||||
response.put("message", "地址创建成功");
|
||||
response.put("data", address);
|
||||
|
||||
return ResponseEntity.ok(response);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取收货地址列表接口
|
||||
*/
|
||||
@GetMapping
|
||||
public ResponseEntity<Map<String, Object>> getAddressList(HttpServletRequest request) {
|
||||
// 从JWT令牌中获取用户ID
|
||||
Long userId = jwtTokenUtil.getUserIdFromRequest(request);
|
||||
if (userId == null) {
|
||||
Map<String, Object> errorResponse = new HashMap<>();
|
||||
errorResponse.put("code", 401);
|
||||
errorResponse.put("message", "无效的访问令牌");
|
||||
return ResponseEntity.status(401).body(errorResponse);
|
||||
}
|
||||
|
||||
List<Address> addresses = addressService.getAddressList(userId);
|
||||
|
||||
Map<String, Object> response = new HashMap<>();
|
||||
response.put("code", 200);
|
||||
response.put("message", "获取成功");
|
||||
response.put("data", addresses);
|
||||
|
||||
return ResponseEntity.ok(response);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取收货地址详情接口
|
||||
*/
|
||||
@GetMapping("/{addressId}")
|
||||
public ResponseEntity<Map<String, Object>> getAddressDetail(
|
||||
HttpServletRequest request,
|
||||
@PathVariable Long addressId) {
|
||||
// 从JWT令牌中获取用户ID
|
||||
Long userId = jwtTokenUtil.getUserIdFromRequest(request);
|
||||
if (userId == null) {
|
||||
Map<String, Object> errorResponse = new HashMap<>();
|
||||
errorResponse.put("code", 401);
|
||||
errorResponse.put("message", "无效的访问令牌");
|
||||
return ResponseEntity.status(401).body(errorResponse);
|
||||
}
|
||||
|
||||
Address address = addressService.getAddressDetail(userId, addressId);
|
||||
|
||||
Map<String, Object> response = new HashMap<>();
|
||||
response.put("code", 200);
|
||||
response.put("message", "获取成功");
|
||||
response.put("data", address);
|
||||
|
||||
return ResponseEntity.ok(response);
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新收货地址接口
|
||||
*/
|
||||
@PutMapping("/{addressId}")
|
||||
public ResponseEntity<Map<String, Object>> updateAddress(
|
||||
HttpServletRequest request,
|
||||
@PathVariable Long addressId,
|
||||
@RequestBody Map<String, Object> requestData) {
|
||||
// 从JWT令牌中获取用户ID
|
||||
Long userId = jwtTokenUtil.getUserIdFromRequest(request);
|
||||
if (userId == null) {
|
||||
Map<String, Object> errorResponse = new HashMap<>();
|
||||
errorResponse.put("code", 401);
|
||||
errorResponse.put("message", "无效的访问令牌");
|
||||
return ResponseEntity.status(401).body(errorResponse);
|
||||
}
|
||||
|
||||
String name = (String) requestData.get("name");
|
||||
String phone = (String) requestData.get("phone");
|
||||
String province = (String) requestData.get("province");
|
||||
String city = (String) requestData.get("city");
|
||||
String district = (String) requestData.get("district");
|
||||
String detailAddress = (String) requestData.get("detailAddress");
|
||||
Boolean isDefault = (Boolean) requestData.get("isDefault");
|
||||
|
||||
Address address = addressService.updateAddress(userId, addressId, name, phone, province, city, district, detailAddress, isDefault);
|
||||
|
||||
Map<String, Object> response = new HashMap<>();
|
||||
response.put("code", 200);
|
||||
response.put("message", "地址更新成功");
|
||||
response.put("data", address);
|
||||
|
||||
return ResponseEntity.ok(response);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除收货地址接口
|
||||
*/
|
||||
@DeleteMapping("/{addressId}")
|
||||
public ResponseEntity<Map<String, Object>> deleteAddress(
|
||||
HttpServletRequest request,
|
||||
@PathVariable Long addressId) {
|
||||
// 从JWT令牌中获取用户ID
|
||||
Long userId = jwtTokenUtil.getUserIdFromRequest(request);
|
||||
if (userId == null) {
|
||||
Map<String, Object> errorResponse = new HashMap<>();
|
||||
errorResponse.put("code", 401);
|
||||
errorResponse.put("message", "无效的访问令牌");
|
||||
return ResponseEntity.status(401).body(errorResponse);
|
||||
}
|
||||
|
||||
addressService.deleteAddress(userId, addressId);
|
||||
|
||||
Map<String, Object> response = new HashMap<>();
|
||||
response.put("code", 200);
|
||||
response.put("message", "地址删除成功");
|
||||
|
||||
return ResponseEntity.ok(response);
|
||||
}
|
||||
}
|
||||
@@ -1,90 +0,0 @@
|
||||
package com.xlxumu.user.controller;
|
||||
|
||||
import com.xlxumu.user.entity.Feedback;
|
||||
import com.xlxumu.user.service.FeedbackService;
|
||||
import com.xlxumu.user.service.PointsService;
|
||||
import com.xlxumu.user.util.JwtTokenUtil;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 用户反馈控制器
|
||||
* 处理用户反馈相关的HTTP请求
|
||||
*
|
||||
* @author xlxumu
|
||||
* @since 2024-01-15
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/api/feedback")
|
||||
public class FeedbackController {
|
||||
|
||||
@Autowired
|
||||
private FeedbackService feedbackService;
|
||||
|
||||
@Autowired
|
||||
private PointsService pointsService;
|
||||
|
||||
@Autowired
|
||||
private JwtTokenUtil jwtTokenUtil;
|
||||
|
||||
/**
|
||||
* 提交反馈接口
|
||||
*/
|
||||
@PostMapping
|
||||
public ResponseEntity<Map<String, Object>> submitFeedback(
|
||||
HttpServletRequest request,
|
||||
@RequestBody Map<String, String> requestData) {
|
||||
// 从JWT令牌中获取用户ID
|
||||
Long userId = jwtTokenUtil.getUserIdFromRequest(request);
|
||||
if (userId == null) {
|
||||
Map<String, Object> errorResponse = new HashMap<>();
|
||||
errorResponse.put("code", 401);
|
||||
errorResponse.put("message", "无效的访问令牌");
|
||||
return ResponseEntity.status(401).body(errorResponse);
|
||||
}
|
||||
|
||||
String title = requestData.get("title");
|
||||
String content = requestData.get("content");
|
||||
String type = requestData.get("type");
|
||||
String contactInfo = requestData.get("contactInfo");
|
||||
|
||||
Feedback feedback = feedbackService.submitFeedback(userId, title, content, type, contactInfo);
|
||||
|
||||
Map<String, Object> response = new HashMap<>();
|
||||
response.put("code", 200);
|
||||
response.put("message", "反馈提交成功");
|
||||
response.put("data", feedback);
|
||||
|
||||
return ResponseEntity.ok(response);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取反馈列表接口
|
||||
*/
|
||||
@GetMapping
|
||||
public ResponseEntity<Map<String, Object>> getFeedbackList(HttpServletRequest request) {
|
||||
// 从JWT令牌中获取用户ID
|
||||
Long userId = jwtTokenUtil.getUserIdFromRequest(request);
|
||||
if (userId == null) {
|
||||
Map<String, Object> errorResponse = new HashMap<>();
|
||||
errorResponse.put("code", 401);
|
||||
errorResponse.put("message", "无效的访问令牌");
|
||||
return ResponseEntity.status(401).body(errorResponse);
|
||||
}
|
||||
|
||||
List<Feedback> feedbacks = feedbackService.getFeedbackList(userId);
|
||||
|
||||
Map<String, Object> response = new HashMap<>();
|
||||
response.put("code", 200);
|
||||
response.put("message", "获取成功");
|
||||
response.put("data", feedbacks);
|
||||
|
||||
return ResponseEntity.ok(response);
|
||||
}
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
package com.xlxumu.user.controller;
|
||||
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
/**
|
||||
* 等级管理控制器
|
||||
* 提供用户等级查询、等级列表查询等API接口
|
||||
*
|
||||
* @author xlxumu
|
||||
* @since 2024-01-15
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/api/v1/users")
|
||||
public class LevelController {
|
||||
|
||||
// TODO: 实现获取用户当前等级接口
|
||||
// TODO: 实现获取等级列表接口
|
||||
}
|
||||
@@ -1,109 +0,0 @@
|
||||
package com.xlxumu.user.controller;
|
||||
|
||||
import com.xlxumu.user.entity.Message;
|
||||
import com.xlxumu.user.service.MessageService;
|
||||
import com.xlxumu.user.service.PointsService;
|
||||
import com.xlxumu.user.util.JwtTokenUtil;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 消息通知控制器
|
||||
* 处理用户消息相关的HTTP请求
|
||||
*
|
||||
* @author xlxumu
|
||||
* @since 2024-01-15
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/api/messages")
|
||||
public class MessageController {
|
||||
|
||||
@Autowired
|
||||
private MessageService messageService;
|
||||
|
||||
@Autowired
|
||||
private PointsService pointsService;
|
||||
|
||||
@Autowired
|
||||
private JwtTokenUtil jwtTokenUtil;
|
||||
|
||||
/**
|
||||
* 获取消息列表接口
|
||||
*/
|
||||
@GetMapping
|
||||
public ResponseEntity<Map<String, Object>> getMessageList(HttpServletRequest request) {
|
||||
// 从JWT令牌中获取用户ID
|
||||
Long userId = jwtTokenUtil.getUserIdFromRequest(request);
|
||||
if (userId == null) {
|
||||
Map<String, Object> errorResponse = new HashMap<>();
|
||||
errorResponse.put("code", 401);
|
||||
errorResponse.put("message", "无效的访问令牌");
|
||||
return ResponseEntity.status(401).body(errorResponse);
|
||||
}
|
||||
|
||||
List<Message> messages = messageService.getMessageList(userId);
|
||||
|
||||
Map<String, Object> response = new HashMap<>();
|
||||
response.put("code", 200);
|
||||
response.put("message", "获取成功");
|
||||
response.put("data", messages);
|
||||
|
||||
return ResponseEntity.ok(response);
|
||||
}
|
||||
|
||||
/**
|
||||
* 标记消息为已读接口
|
||||
*/
|
||||
@PutMapping("/{messageId}/read")
|
||||
public ResponseEntity<Map<String, Object>> markMessageAsRead(
|
||||
HttpServletRequest request,
|
||||
@PathVariable Long messageId) {
|
||||
// 从JWT令牌中获取用户ID
|
||||
Long userId = jwtTokenUtil.getUserIdFromRequest(request);
|
||||
if (userId == null) {
|
||||
Map<String, Object> errorResponse = new HashMap<>();
|
||||
errorResponse.put("code", 401);
|
||||
errorResponse.put("message", "无效的访问令牌");
|
||||
return ResponseEntity.status(401).body(errorResponse);
|
||||
}
|
||||
|
||||
messageService.markMessageAsRead(messageId);
|
||||
|
||||
Map<String, Object> response = new HashMap<>();
|
||||
response.put("code", 200);
|
||||
response.put("message", "标记成功");
|
||||
|
||||
return ResponseEntity.ok(response);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除消息接口
|
||||
*/
|
||||
@DeleteMapping("/{messageId}")
|
||||
public ResponseEntity<Map<String, Object>> deleteMessage(
|
||||
HttpServletRequest request,
|
||||
@PathVariable Long messageId) {
|
||||
// 从JWT令牌中获取用户ID
|
||||
Long userId = jwtTokenUtil.getUserIdFromRequest(request);
|
||||
if (userId == null) {
|
||||
Map<String, Object> errorResponse = new HashMap<>();
|
||||
errorResponse.put("code", 401);
|
||||
errorResponse.put("message", "无效的访问令牌");
|
||||
return ResponseEntity.status(401).body(errorResponse);
|
||||
}
|
||||
|
||||
messageService.deleteMessage(messageId);
|
||||
|
||||
Map<String, Object> response = new HashMap<>();
|
||||
response.put("code", 200);
|
||||
response.put("message", "删除成功");
|
||||
|
||||
return ResponseEntity.ok(response);
|
||||
}
|
||||
}
|
||||
@@ -1,123 +0,0 @@
|
||||
package com.xlxumu.user.controller;
|
||||
|
||||
import com.xlxumu.user.entity.Level;
|
||||
import com.xlxumu.user.entity.PointsRecord;
|
||||
import com.xlxumu.user.service.LevelService;
|
||||
import com.xlxumu.user.service.PointsService;
|
||||
import com.xlxumu.user.util.JwtTokenUtil;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 积分管理控制器
|
||||
* 处理用户积分相关的HTTP请求
|
||||
*
|
||||
* @author xlxumu
|
||||
* @since 2024-01-15
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/api/points")
|
||||
public class PointsController {
|
||||
|
||||
@Autowired
|
||||
private PointsService pointsService;
|
||||
|
||||
@Autowired
|
||||
private LevelService levelService;
|
||||
|
||||
@Autowired
|
||||
private JwtTokenUtil jwtTokenUtil;
|
||||
|
||||
/**
|
||||
* 获取用户积分余额接口
|
||||
*/
|
||||
@GetMapping("/balance")
|
||||
public ResponseEntity<Map<String, Object>> getUserPointsBalance(HttpServletRequest request) {
|
||||
// 从JWT令牌中获取用户ID
|
||||
Long userId = jwtTokenUtil.getUserIdFromRequest(request);
|
||||
if (userId == null) {
|
||||
Map<String, Object> errorResponse = new HashMap<>();
|
||||
errorResponse.put("code", 401);
|
||||
errorResponse.put("message", "无效的访问令牌");
|
||||
return ResponseEntity.status(401).body(errorResponse);
|
||||
}
|
||||
|
||||
Integer balance = pointsService.getUserPointsBalance(userId);
|
||||
|
||||
Map<String, Object> response = new HashMap<>();
|
||||
response.put("code", 200);
|
||||
response.put("message", "获取成功");
|
||||
response.put("data", Map.of("balance", balance));
|
||||
|
||||
return ResponseEntity.ok(response);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取积分记录列表接口
|
||||
*/
|
||||
@GetMapping("/records")
|
||||
public ResponseEntity<Map<String, Object>> getPointsRecordList(HttpServletRequest request) {
|
||||
// 从JWT令牌中获取用户ID
|
||||
Long userId = jwtTokenUtil.getUserIdFromRequest(request);
|
||||
if (userId == null) {
|
||||
Map<String, Object> errorResponse = new HashMap<>();
|
||||
errorResponse.put("code", 401);
|
||||
errorResponse.put("message", "无效的访问令牌");
|
||||
return ResponseEntity.status(401).body(errorResponse);
|
||||
}
|
||||
|
||||
List<PointsRecord> records = pointsService.getPointsRecordList(userId);
|
||||
|
||||
Map<String, Object> response = new HashMap<>();
|
||||
response.put("code", 200);
|
||||
response.put("message", "获取成功");
|
||||
response.put("data", records);
|
||||
|
||||
return ResponseEntity.ok(response);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取用户当前等级接口
|
||||
*/
|
||||
@GetMapping("/level")
|
||||
public ResponseEntity<Map<String, Object>> getUserCurrentLevel(HttpServletRequest request) {
|
||||
// 从JWT令牌中获取用户ID
|
||||
Long userId = jwtTokenUtil.getUserIdFromRequest(request);
|
||||
if (userId == null) {
|
||||
Map<String, Object> errorResponse = new HashMap<>();
|
||||
errorResponse.put("code", 401);
|
||||
errorResponse.put("message", "无效的访问令牌");
|
||||
return ResponseEntity.status(401).body(errorResponse);
|
||||
}
|
||||
|
||||
Level level = levelService.getUserCurrentLevel(userId);
|
||||
|
||||
Map<String, Object> response = new HashMap<>();
|
||||
response.put("code", 200);
|
||||
response.put("message", "获取成功");
|
||||
response.put("data", level);
|
||||
|
||||
return ResponseEntity.ok(response);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取等级列表接口
|
||||
*/
|
||||
@GetMapping("/levels")
|
||||
public ResponseEntity<Map<String, Object>> getLevelList() {
|
||||
List<Level> levels = levelService.getLevelList();
|
||||
|
||||
Map<String, Object> response = new HashMap<>();
|
||||
response.put("code", 200);
|
||||
response.put("message", "获取成功");
|
||||
response.put("data", levels);
|
||||
|
||||
return ResponseEntity.ok(response);
|
||||
}
|
||||
}
|
||||
@@ -1,165 +0,0 @@
|
||||
package com.xlxumu.user.controller;
|
||||
|
||||
import com.xlxumu.user.entity.User;
|
||||
import com.xlxumu.user.service.UserService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 用户管理控制器
|
||||
* 处理用户相关的HTTP请求
|
||||
*
|
||||
* @author xlxumu
|
||||
* @since 2024-01-15
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/api/users")
|
||||
public class UserController {
|
||||
|
||||
@Autowired
|
||||
private UserService userService;
|
||||
|
||||
/**
|
||||
* 用户注册接口
|
||||
*/
|
||||
@PostMapping("/register")
|
||||
public ResponseEntity<Map<String, Object>> register(@RequestBody Map<String, String> request) {
|
||||
String username = request.get("username");
|
||||
String password = request.get("password");
|
||||
String email = request.get("email");
|
||||
String phone = request.get("phone");
|
||||
|
||||
User user = userService.register(username, password, email, phone);
|
||||
|
||||
Map<String, Object> response = new HashMap<>();
|
||||
response.put("code", 200);
|
||||
response.put("message", "注册成功");
|
||||
response.put("data", user);
|
||||
|
||||
return ResponseEntity.ok(response);
|
||||
}
|
||||
|
||||
/**
|
||||
* 用户登录接口
|
||||
*/
|
||||
@PostMapping("/login")
|
||||
public ResponseEntity<Map<String, Object>> login(@RequestBody Map<String, String> request) {
|
||||
String username = request.get("username");
|
||||
String password = request.get("password");
|
||||
|
||||
String token = userService.login(username, password);
|
||||
|
||||
Map<String, Object> response = new HashMap<>();
|
||||
response.put("code", 200);
|
||||
response.put("message", "登录成功");
|
||||
response.put("data", Map.of("token", token));
|
||||
|
||||
return ResponseEntity.ok(response);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取用户信息
|
||||
* @param request HTTP请求
|
||||
* @return 用户信息
|
||||
*/
|
||||
@GetMapping("/info")
|
||||
public ResponseEntity<ApiResponse<User>> getUserInfo(HttpServletRequest request) {
|
||||
// 从JWT令牌中获取用户ID
|
||||
Long userId = jwtTokenUtil.getUserIdFromRequest(request);
|
||||
|
||||
if (userId == null) {
|
||||
return ResponseEntity.status(HttpStatus.UNAUTHORIZED)
|
||||
.body(new ApiResponse<>(401, "无效的访问令牌", null));
|
||||
}
|
||||
|
||||
try {
|
||||
User user = userService.getUserById(userId);
|
||||
return ResponseEntity.ok(new ApiResponse<>(200, "获取成功", user));
|
||||
} catch (UserException e) {
|
||||
return ResponseEntity.badRequest().body(new ApiResponse<>(e.getCode(), e.getMessage(), null));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新用户信息接口
|
||||
*/
|
||||
@PutMapping("/info")
|
||||
public ResponseEntity<Map<String, Object>> updateUserInfo(
|
||||
@RequestHeader("Authorization") String token,
|
||||
@RequestBody Map<String, String> request) {
|
||||
String nickname = request.get("nickname");
|
||||
String avatar = request.get("avatar");
|
||||
String gender = request.get("gender");
|
||||
String birthday = request.get("birthday");
|
||||
|
||||
User user = userService.updateUserInfo(token, nickname, avatar, gender, birthday);
|
||||
|
||||
Map<String, Object> response = new HashMap<>();
|
||||
response.put("code", 200);
|
||||
response.put("message", "更新成功");
|
||||
response.put("data", user);
|
||||
|
||||
return ResponseEntity.ok(response);
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改密码接口
|
||||
*/
|
||||
@PutMapping("/password")
|
||||
public ResponseEntity<Map<String, Object>> changePassword(
|
||||
@RequestHeader("Authorization") String token,
|
||||
@RequestBody Map<String, String> request) {
|
||||
String oldPassword = request.get("oldPassword");
|
||||
String newPassword = request.get("newPassword");
|
||||
|
||||
userService.changePassword(token, oldPassword, newPassword);
|
||||
|
||||
Map<String, Object> response = new HashMap<>();
|
||||
response.put("code", 200);
|
||||
response.put("message", "密码修改成功");
|
||||
|
||||
return ResponseEntity.ok(response);
|
||||
}
|
||||
|
||||
/**
|
||||
* 管理员获取用户列表接口
|
||||
*/
|
||||
@GetMapping("/list")
|
||||
public ResponseEntity<Map<String, Object>> getUserList(
|
||||
@RequestHeader("Authorization") String token,
|
||||
@RequestParam(defaultValue = "1") Integer page,
|
||||
@RequestParam(defaultValue = "10") Integer size) {
|
||||
List<User> users = userService.getUserList(token, page, size);
|
||||
|
||||
Map<String, Object> response = new HashMap<>();
|
||||
response.put("code", 200);
|
||||
response.put("message", "获取成功");
|
||||
response.put("data", users);
|
||||
|
||||
return ResponseEntity.ok(response);
|
||||
}
|
||||
|
||||
/**
|
||||
* 管理员更新用户状态接口
|
||||
*/
|
||||
@PutMapping("/{userId}/status")
|
||||
public ResponseEntity<Map<String, Object>> updateUserStatus(
|
||||
@RequestHeader("Authorization") String token,
|
||||
@PathVariable Long userId,
|
||||
@RequestBody Map<String, Integer> request) {
|
||||
Integer status = request.get("status");
|
||||
|
||||
userService.updateUserStatus(token, userId, status);
|
||||
|
||||
Map<String, Object> response = new HashMap<>();
|
||||
response.put("code", 200);
|
||||
response.put("message", "状态更新成功");
|
||||
|
||||
return ResponseEntity.ok(response);
|
||||
}
|
||||
}
|
||||
@@ -1,151 +0,0 @@
|
||||
package com.xlxumu.user.entity;
|
||||
|
||||
import javax.persistence.*;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* 收货地址实体类
|
||||
*
|
||||
* @author xlxumu
|
||||
* @since 2024-01-15
|
||||
*/
|
||||
@Entity
|
||||
@Table(name = "addresses")
|
||||
public class Address {
|
||||
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
private Long id;
|
||||
|
||||
@Column(name = "user_id", nullable = false)
|
||||
private Long userId;
|
||||
|
||||
@Column(name = "receiver_name", nullable = false)
|
||||
private String receiverName;
|
||||
|
||||
@Column(name = "receiver_phone", nullable = false)
|
||||
private String receiverPhone;
|
||||
|
||||
@Column(name = "province", nullable = false)
|
||||
private String province;
|
||||
|
||||
@Column(name = "city", nullable = false)
|
||||
private String city;
|
||||
|
||||
@Column(name = "district", nullable = false)
|
||||
private String district;
|
||||
|
||||
@Column(name = "detail_address", nullable = false)
|
||||
private String detailAddress;
|
||||
|
||||
@Column(name = "is_default")
|
||||
private Boolean isDefault = false;
|
||||
|
||||
private Integer status = 1;
|
||||
|
||||
@Column(name = "created_at", nullable = false)
|
||||
private LocalDateTime createdAt;
|
||||
|
||||
@Column(name = "updated_at", nullable = false)
|
||||
private LocalDateTime updatedAt;
|
||||
|
||||
// Constructors
|
||||
public Address() {}
|
||||
|
||||
// Getters and Setters
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public Long getUserId() {
|
||||
return userId;
|
||||
}
|
||||
|
||||
public void setUserId(Long userId) {
|
||||
this.userId = userId;
|
||||
}
|
||||
|
||||
public String getReceiverName() {
|
||||
return receiverName;
|
||||
}
|
||||
|
||||
public void setReceiverName(String receiverName) {
|
||||
this.receiverName = receiverName;
|
||||
}
|
||||
|
||||
public String getReceiverPhone() {
|
||||
return receiverPhone;
|
||||
}
|
||||
|
||||
public void setReceiverPhone(String receiverPhone) {
|
||||
this.receiverPhone = receiverPhone;
|
||||
}
|
||||
|
||||
public String getProvince() {
|
||||
return province;
|
||||
}
|
||||
|
||||
public void setProvince(String province) {
|
||||
this.province = province;
|
||||
}
|
||||
|
||||
public String getCity() {
|
||||
return city;
|
||||
}
|
||||
|
||||
public void setCity(String city) {
|
||||
this.city = city;
|
||||
}
|
||||
|
||||
public String getDistrict() {
|
||||
return district;
|
||||
}
|
||||
|
||||
public void setDistrict(String district) {
|
||||
this.district = district;
|
||||
}
|
||||
|
||||
public String getDetailAddress() {
|
||||
return detailAddress;
|
||||
}
|
||||
|
||||
public void setDetailAddress(String detailAddress) {
|
||||
this.detailAddress = detailAddress;
|
||||
}
|
||||
|
||||
public Boolean getIsDefault() {
|
||||
return isDefault;
|
||||
}
|
||||
|
||||
public void setIsDefault(Boolean isDefault) {
|
||||
this.isDefault = isDefault;
|
||||
}
|
||||
|
||||
public Integer getStatus() {
|
||||
return status;
|
||||
}
|
||||
|
||||
public void setStatus(Integer status) {
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
public LocalDateTime getCreatedAt() {
|
||||
return createdAt;
|
||||
}
|
||||
|
||||
public void setCreatedAt(LocalDateTime createdAt) {
|
||||
this.createdAt = createdAt;
|
||||
}
|
||||
|
||||
public LocalDateTime getUpdatedAt() {
|
||||
return updatedAt;
|
||||
}
|
||||
|
||||
public void setUpdatedAt(LocalDateTime updatedAt) {
|
||||
this.updatedAt = updatedAt;
|
||||
}
|
||||
}
|
||||
@@ -1,137 +0,0 @@
|
||||
package com.xlxumu.user.entity;
|
||||
|
||||
import javax.persistence.*;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* 用户反馈实体类
|
||||
*
|
||||
* @author xlxumu
|
||||
* @since 2024-01-15
|
||||
*/
|
||||
@Entity
|
||||
@Table(name = "feedbacks")
|
||||
public class Feedback {
|
||||
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
private Long id;
|
||||
|
||||
@Column(name = "user_id", nullable = false)
|
||||
private Long userId;
|
||||
|
||||
private String title;
|
||||
|
||||
private String content;
|
||||
|
||||
private Integer type;
|
||||
|
||||
@Column(name = "contact_info")
|
||||
private String contactInfo;
|
||||
|
||||
private Integer status = 1;
|
||||
|
||||
@Column(name = "reply_content")
|
||||
private String replyContent;
|
||||
|
||||
@Column(name = "replied_at")
|
||||
private LocalDateTime repliedAt;
|
||||
|
||||
@Column(name = "created_at", nullable = false)
|
||||
private LocalDateTime createdAt;
|
||||
|
||||
@Column(name = "updated_at", nullable = false)
|
||||
private LocalDateTime updatedAt;
|
||||
|
||||
// Constructors
|
||||
public Feedback() {}
|
||||
|
||||
// Getters and Setters
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public Long getUserId() {
|
||||
return userId;
|
||||
}
|
||||
|
||||
public void setUserId(Long userId) {
|
||||
this.userId = userId;
|
||||
}
|
||||
|
||||
public String getTitle() {
|
||||
return title;
|
||||
}
|
||||
|
||||
public void setTitle(String title) {
|
||||
this.title = title;
|
||||
}
|
||||
|
||||
public String getContent() {
|
||||
return content;
|
||||
}
|
||||
|
||||
public void setContent(String content) {
|
||||
this.content = content;
|
||||
}
|
||||
|
||||
public Integer getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public void setType(Integer type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public String getContactInfo() {
|
||||
return contactInfo;
|
||||
}
|
||||
|
||||
public void setContactInfo(String contactInfo) {
|
||||
this.contactInfo = contactInfo;
|
||||
}
|
||||
|
||||
public Integer getStatus() {
|
||||
return status;
|
||||
}
|
||||
|
||||
public void setStatus(Integer status) {
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
public String getReplyContent() {
|
||||
return replyContent;
|
||||
}
|
||||
|
||||
public void setReplyContent(String replyContent) {
|
||||
this.replyContent = replyContent;
|
||||
}
|
||||
|
||||
public LocalDateTime getRepliedAt() {
|
||||
return repliedAt;
|
||||
}
|
||||
|
||||
public void setRepliedAt(LocalDateTime repliedAt) {
|
||||
this.repliedAt = repliedAt;
|
||||
}
|
||||
|
||||
public LocalDateTime getCreatedAt() {
|
||||
return createdAt;
|
||||
}
|
||||
|
||||
public void setCreatedAt(LocalDateTime createdAt) {
|
||||
this.createdAt = createdAt;
|
||||
}
|
||||
|
||||
public LocalDateTime getUpdatedAt() {
|
||||
return updatedAt;
|
||||
}
|
||||
|
||||
public void setUpdatedAt(LocalDateTime updatedAt) {
|
||||
this.updatedAt = updatedAt;
|
||||
}
|
||||
}
|
||||
@@ -1,117 +0,0 @@
|
||||
package com.xlxumu.user.entity;
|
||||
|
||||
import javax.persistence.*;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* 等级定义实体类
|
||||
*
|
||||
* @author xlxumu
|
||||
* @since 2024-01-15
|
||||
*/
|
||||
@Entity
|
||||
@Table(name = "levels")
|
||||
public class Level {
|
||||
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
private Long id;
|
||||
|
||||
@Column(nullable = false, unique = true)
|
||||
private String name;
|
||||
|
||||
private String description;
|
||||
|
||||
@Column(name = "min_points", nullable = false)
|
||||
private Integer minPoints;
|
||||
|
||||
@Column(name = "max_points")
|
||||
private Integer maxPoints;
|
||||
|
||||
@Column(name = "benefits")
|
||||
private String benefits;
|
||||
|
||||
private Integer status = 1;
|
||||
|
||||
@Column(name = "created_at", nullable = false)
|
||||
private LocalDateTime createdAt;
|
||||
|
||||
@Column(name = "updated_at", nullable = false)
|
||||
private LocalDateTime updatedAt;
|
||||
|
||||
// Constructors
|
||||
public Level() {}
|
||||
|
||||
// Getters and Setters
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
public void setDescription(String description) {
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
public Integer getMinPoints() {
|
||||
return minPoints;
|
||||
}
|
||||
|
||||
public void setMinPoints(Integer minPoints) {
|
||||
this.minPoints = minPoints;
|
||||
}
|
||||
|
||||
public Integer getMaxPoints() {
|
||||
return maxPoints;
|
||||
}
|
||||
|
||||
public void setMaxPoints(Integer maxPoints) {
|
||||
this.maxPoints = maxPoints;
|
||||
}
|
||||
|
||||
public String getBenefits() {
|
||||
return benefits;
|
||||
}
|
||||
|
||||
public void setBenefits(String benefits) {
|
||||
this.benefits = benefits;
|
||||
}
|
||||
|
||||
public Integer getStatus() {
|
||||
return status;
|
||||
}
|
||||
|
||||
public void setStatus(Integer status) {
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
public LocalDateTime getCreatedAt() {
|
||||
return createdAt;
|
||||
}
|
||||
|
||||
public void setCreatedAt(LocalDateTime createdAt) {
|
||||
this.createdAt = createdAt;
|
||||
}
|
||||
|
||||
public LocalDateTime getUpdatedAt() {
|
||||
return updatedAt;
|
||||
}
|
||||
|
||||
public void setUpdatedAt(LocalDateTime updatedAt) {
|
||||
this.updatedAt = updatedAt;
|
||||
}
|
||||
}
|
||||
@@ -1,126 +0,0 @@
|
||||
package com.xlxumu.user.entity;
|
||||
|
||||
import javax.persistence.*;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* 用户消息实体类
|
||||
*
|
||||
* @author xlxumu
|
||||
* @since 2024-01-15
|
||||
*/
|
||||
@Entity
|
||||
@Table(name = "messages")
|
||||
public class Message {
|
||||
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
private Long id;
|
||||
|
||||
@Column(name = "user_id", nullable = false)
|
||||
private Long userId;
|
||||
|
||||
@Column(name = "sender_id")
|
||||
private Long senderId;
|
||||
|
||||
private String title;
|
||||
|
||||
private String content;
|
||||
|
||||
private Integer type;
|
||||
|
||||
@Column(name = "is_read")
|
||||
private Boolean isRead = false;
|
||||
|
||||
private Integer status = 1;
|
||||
|
||||
@Column(name = "created_at", nullable = false)
|
||||
private LocalDateTime createdAt;
|
||||
|
||||
@Column(name = "read_at")
|
||||
private LocalDateTime readAt;
|
||||
|
||||
// Constructors
|
||||
public Message() {}
|
||||
|
||||
// Getters and Setters
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public Long getUserId() {
|
||||
return userId;
|
||||
}
|
||||
|
||||
public void setUserId(Long userId) {
|
||||
this.userId = userId;
|
||||
}
|
||||
|
||||
public Long getSenderId() {
|
||||
return senderId;
|
||||
}
|
||||
|
||||
public void setSenderId(Long senderId) {
|
||||
this.senderId = senderId;
|
||||
}
|
||||
|
||||
public String getTitle() {
|
||||
return title;
|
||||
}
|
||||
|
||||
public void setTitle(String title) {
|
||||
this.title = title;
|
||||
}
|
||||
|
||||
public String getContent() {
|
||||
return content;
|
||||
}
|
||||
|
||||
public void setContent(String content) {
|
||||
this.content = content;
|
||||
}
|
||||
|
||||
public Integer getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public void setType(Integer type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public Boolean getIsRead() {
|
||||
return isRead;
|
||||
}
|
||||
|
||||
public void setIsRead(Boolean isRead) {
|
||||
this.isRead = isRead;
|
||||
}
|
||||
|
||||
public Integer getStatus() {
|
||||
return status;
|
||||
}
|
||||
|
||||
public void setStatus(Integer status) {
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
public LocalDateTime getCreatedAt() {
|
||||
return createdAt;
|
||||
}
|
||||
|
||||
public void setCreatedAt(LocalDateTime createdAt) {
|
||||
this.createdAt = createdAt;
|
||||
}
|
||||
|
||||
public LocalDateTime getReadAt() {
|
||||
return readAt;
|
||||
}
|
||||
|
||||
public void setReadAt(LocalDateTime readAt) {
|
||||
this.readAt = readAt;
|
||||
}
|
||||
}
|
||||
@@ -1,84 +0,0 @@
|
||||
package com.xlxumu.user.entity;
|
||||
|
||||
import javax.persistence.*;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* 积分记录实体类
|
||||
*
|
||||
* @author xlxumu
|
||||
* @since 2024-01-15
|
||||
*/
|
||||
@Entity
|
||||
@Table(name = "points_records")
|
||||
public class PointsRecord {
|
||||
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
private Long id;
|
||||
|
||||
@Column(name = "user_id", nullable = false)
|
||||
private Long userId;
|
||||
|
||||
private Integer points;
|
||||
|
||||
@Column(name = "change_type", nullable = false)
|
||||
private String changeType;
|
||||
|
||||
private String description;
|
||||
|
||||
@Column(name = "created_at", nullable = false)
|
||||
private LocalDateTime createdAt;
|
||||
|
||||
// Constructors
|
||||
public PointsRecord() {}
|
||||
|
||||
// Getters and Setters
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public Long getUserId() {
|
||||
return userId;
|
||||
}
|
||||
|
||||
public void setUserId(Long userId) {
|
||||
this.userId = userId;
|
||||
}
|
||||
|
||||
public Integer getPoints() {
|
||||
return points;
|
||||
}
|
||||
|
||||
public void setPoints(Integer points) {
|
||||
this.points = points;
|
||||
}
|
||||
|
||||
public String getChangeType() {
|
||||
return changeType;
|
||||
}
|
||||
|
||||
public void setChangeType(String changeType) {
|
||||
this.changeType = changeType;
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
public void setDescription(String description) {
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
public LocalDateTime getCreatedAt() {
|
||||
return createdAt;
|
||||
}
|
||||
|
||||
public void setCreatedAt(LocalDateTime createdAt) {
|
||||
this.createdAt = createdAt;
|
||||
}
|
||||
}
|
||||
@@ -1,180 +0,0 @@
|
||||
package com.xlxumu.user.entity;
|
||||
|
||||
import javax.persistence.*;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* 用户基本信息实体类
|
||||
*
|
||||
* @author xlxumu
|
||||
* @since 2024-01-15
|
||||
*/
|
||||
@Entity
|
||||
@Table(name = "users")
|
||||
public class User {
|
||||
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
private Long id;
|
||||
|
||||
@Column(nullable = false, unique = true)
|
||||
private String username;
|
||||
|
||||
@Column(nullable = false, unique = true)
|
||||
private String email;
|
||||
|
||||
private String phone;
|
||||
|
||||
@Column(name = "password_hash", nullable = false)
|
||||
private String passwordHash;
|
||||
|
||||
private String nickname;
|
||||
|
||||
@Column(name = "avatar_url")
|
||||
private String avatarUrl;
|
||||
|
||||
private Integer gender;
|
||||
|
||||
private LocalDateTime birthday;
|
||||
|
||||
@Column(name = "real_name")
|
||||
private String realName;
|
||||
|
||||
@Column(name = "id_card_number")
|
||||
private String idCardNumber;
|
||||
|
||||
private Integer status = 1;
|
||||
|
||||
@Column(name = "last_login_at")
|
||||
private LocalDateTime lastLoginAt;
|
||||
|
||||
@Column(name = "created_at", nullable = false)
|
||||
private LocalDateTime createdAt;
|
||||
|
||||
@Column(name = "updated_at", nullable = false)
|
||||
private LocalDateTime updatedAt;
|
||||
|
||||
// Constructors
|
||||
public User() {}
|
||||
|
||||
// Getters and Setters
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getUsername() {
|
||||
return username;
|
||||
}
|
||||
|
||||
public void setUsername(String username) {
|
||||
this.username = username;
|
||||
}
|
||||
|
||||
public String getEmail() {
|
||||
return email;
|
||||
}
|
||||
|
||||
public void setEmail(String email) {
|
||||
this.email = email;
|
||||
}
|
||||
|
||||
public String getPhone() {
|
||||
return phone;
|
||||
}
|
||||
|
||||
public void setPhone(String phone) {
|
||||
this.phone = phone;
|
||||
}
|
||||
|
||||
public String getPasswordHash() {
|
||||
return passwordHash;
|
||||
}
|
||||
|
||||
public void setPasswordHash(String passwordHash) {
|
||||
this.passwordHash = passwordHash;
|
||||
}
|
||||
|
||||
public String getNickname() {
|
||||
return nickname;
|
||||
}
|
||||
|
||||
public void setNickname(String nickname) {
|
||||
this.nickname = nickname;
|
||||
}
|
||||
|
||||
public String getAvatarUrl() {
|
||||
return avatarUrl;
|
||||
}
|
||||
|
||||
public void setAvatarUrl(String avatarUrl) {
|
||||
this.avatarUrl = avatarUrl;
|
||||
}
|
||||
|
||||
public Integer getGender() {
|
||||
return gender;
|
||||
}
|
||||
|
||||
public void setGender(Integer gender) {
|
||||
this.gender = gender;
|
||||
}
|
||||
|
||||
public LocalDateTime getBirthday() {
|
||||
return birthday;
|
||||
}
|
||||
|
||||
public void setBirthday(LocalDateTime birthday) {
|
||||
this.birthday = birthday;
|
||||
}
|
||||
|
||||
public String getRealName() {
|
||||
return realName;
|
||||
}
|
||||
|
||||
public void setRealName(String realName) {
|
||||
this.realName = realName;
|
||||
}
|
||||
|
||||
public String getIdCardNumber() {
|
||||
return idCardNumber;
|
||||
}
|
||||
|
||||
public void setIdCardNumber(String idCardNumber) {
|
||||
this.idCardNumber = idCardNumber;
|
||||
}
|
||||
|
||||
public Integer getStatus() {
|
||||
return status;
|
||||
}
|
||||
|
||||
public void setStatus(Integer status) {
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
public LocalDateTime getLastLoginAt() {
|
||||
return lastLoginAt;
|
||||
}
|
||||
|
||||
public void setLastLoginAt(LocalDateTime lastLoginAt) {
|
||||
this.lastLoginAt = lastLoginAt;
|
||||
}
|
||||
|
||||
public LocalDateTime getCreatedAt() {
|
||||
return createdAt;
|
||||
}
|
||||
|
||||
public void setCreatedAt(LocalDateTime createdAt) {
|
||||
this.createdAt = createdAt;
|
||||
}
|
||||
|
||||
public LocalDateTime getUpdatedAt() {
|
||||
return updatedAt;
|
||||
}
|
||||
|
||||
public void setUpdatedAt(LocalDateTime updatedAt) {
|
||||
this.updatedAt = updatedAt;
|
||||
}
|
||||
}
|
||||
@@ -1,86 +0,0 @@
|
||||
package com.xlxumu.user.entity;
|
||||
|
||||
import javax.persistence.*;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* 用户等级实体类
|
||||
*
|
||||
* @author xlxumu
|
||||
* @since 2024-01-15
|
||||
*/
|
||||
@Entity
|
||||
@Table(name = "user_levels")
|
||||
public class UserLevel {
|
||||
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
private Long id;
|
||||
|
||||
@Column(name = "user_id", nullable = false, unique = true)
|
||||
private Long userId;
|
||||
|
||||
@Column(name = "level_id", nullable = false)
|
||||
private Long levelId;
|
||||
|
||||
@Column(name = "current_points")
|
||||
private Integer currentPoints = 0;
|
||||
|
||||
@Column(name = "created_at", nullable = false)
|
||||
private LocalDateTime createdAt;
|
||||
|
||||
@Column(name = "updated_at", nullable = false)
|
||||
private LocalDateTime updatedAt;
|
||||
|
||||
// Constructors
|
||||
public UserLevel() {}
|
||||
|
||||
// Getters and Setters
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public Long getUserId() {
|
||||
return userId;
|
||||
}
|
||||
|
||||
public void setUserId(Long userId) {
|
||||
this.userId = userId;
|
||||
}
|
||||
|
||||
public Long getLevelId() {
|
||||
return levelId;
|
||||
}
|
||||
|
||||
public void setLevelId(Long levelId) {
|
||||
this.levelId = levelId;
|
||||
}
|
||||
|
||||
public Integer getCurrentPoints() {
|
||||
return currentPoints;
|
||||
}
|
||||
|
||||
public void setCurrentPoints(Integer currentPoints) {
|
||||
this.currentPoints = currentPoints;
|
||||
}
|
||||
|
||||
public LocalDateTime getCreatedAt() {
|
||||
return createdAt;
|
||||
}
|
||||
|
||||
public void setCreatedAt(LocalDateTime createdAt) {
|
||||
this.createdAt = createdAt;
|
||||
}
|
||||
|
||||
public LocalDateTime getUpdatedAt() {
|
||||
return updatedAt;
|
||||
}
|
||||
|
||||
public void setUpdatedAt(LocalDateTime updatedAt) {
|
||||
this.updatedAt = updatedAt;
|
||||
}
|
||||
}
|
||||
@@ -1,56 +0,0 @@
|
||||
package com.xlxumu.user.exception;
|
||||
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.ControllerAdvice;
|
||||
import org.springframework.web.bind.annotation.ExceptionHandler;
|
||||
import org.springframework.web.context.request.WebRequest;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 全局异常处理类
|
||||
*
|
||||
* @author xlxumu
|
||||
* @since 2024-01-15
|
||||
*/
|
||||
@ControllerAdvice
|
||||
public class GlobalExceptionHandler {
|
||||
|
||||
/**
|
||||
* 处理用户相关异常
|
||||
* @param ex 异常对象
|
||||
* @param request 请求对象
|
||||
* @return 错误响应
|
||||
*/
|
||||
@ExceptionHandler(UserException.class)
|
||||
public ResponseEntity<Object> handleUserException(UserException ex, WebRequest request) {
|
||||
Map<String, Object> body = new HashMap<>();
|
||||
body.put("timestamp", LocalDateTime.now());
|
||||
body.put("status", ex.getStatus());
|
||||
body.put("error", ex.getMessage());
|
||||
body.put("path", request.getDescription(false).replace("uri=", ""));
|
||||
|
||||
return new ResponseEntity<>(body, HttpStatus.valueOf(ex.getStatus()));
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理通用异常
|
||||
* @param ex 异常对象
|
||||
* @param request 请求对象
|
||||
* @return 错误响应
|
||||
*/
|
||||
@ExceptionHandler(Exception.class)
|
||||
public ResponseEntity<Object> handleGenericException(Exception ex, WebRequest request) {
|
||||
Map<String, Object> body = new HashMap<>();
|
||||
body.put("timestamp", LocalDateTime.now());
|
||||
body.put("status", HttpStatus.INTERNAL_SERVER_ERROR.value());
|
||||
body.put("error", "Internal Server Error");
|
||||
body.put("message", ex.getMessage());
|
||||
body.put("path", request.getDescription(false).replace("uri=", ""));
|
||||
|
||||
return new ResponseEntity<>(body, HttpStatus.INTERNAL_SERVER_ERROR);
|
||||
}
|
||||
}
|
||||
@@ -1,26 +0,0 @@
|
||||
package com.xlxumu.user.exception;
|
||||
|
||||
/**
|
||||
* 用户相关自定义异常类
|
||||
*
|
||||
* @author xlxumu
|
||||
* @since 2024-01-15
|
||||
*/
|
||||
public class UserException extends RuntimeException {
|
||||
|
||||
private int status;
|
||||
|
||||
public UserException(String message, int status) {
|
||||
super(message);
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
public UserException(String message, Throwable cause, int status) {
|
||||
super(message, cause);
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
public int getStatus() {
|
||||
return status;
|
||||
}
|
||||
}
|
||||
@@ -1,32 +0,0 @@
|
||||
package com.xlxumu.user.repository;
|
||||
|
||||
import com.xlxumu.user.entity.Address;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 收货地址数据访问接口
|
||||
*
|
||||
* @author xlxumu
|
||||
* @since 2024-01-15
|
||||
*/
|
||||
@Repository
|
||||
public interface AddressRepository extends JpaRepository<Address, Long> {
|
||||
|
||||
/**
|
||||
* 根据用户ID查找收货地址列表
|
||||
* @param userId 用户ID
|
||||
* @return 收货地址列表
|
||||
*/
|
||||
List<Address> findByUserId(Long userId);
|
||||
|
||||
/**
|
||||
* 根据用户ID和默认地址标识查找默认收货地址
|
||||
* @param userId 用户ID
|
||||
* @param isDefault 是否默认地址
|
||||
* @return 收货地址
|
||||
*/
|
||||
Address findByUserIdAndIsDefault(Long userId, Boolean isDefault);
|
||||
}
|
||||
@@ -1,24 +0,0 @@
|
||||
package com.xlxumu.user.repository;
|
||||
|
||||
import com.xlxumu.user.entity.Feedback;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 用户反馈数据访问接口
|
||||
*
|
||||
* @author xlxumu
|
||||
* @since 2024-01-15
|
||||
*/
|
||||
@Repository
|
||||
public interface FeedbackRepository extends JpaRepository<Feedback, Long> {
|
||||
|
||||
/**
|
||||
* 根据用户ID查找反馈列表
|
||||
* @param userId 用户ID
|
||||
* @return 反馈列表
|
||||
*/
|
||||
List<Feedback> findByUserIdOrderByCreatedAtDesc(Long userId);
|
||||
}
|
||||
@@ -1,24 +0,0 @@
|
||||
package com.xlxumu.user.repository;
|
||||
|
||||
import com.xlxumu.user.entity.Level;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 等级定义数据访问接口
|
||||
*
|
||||
* @author xlxumu
|
||||
* @since 2024-01-15
|
||||
*/
|
||||
@Repository
|
||||
public interface LevelRepository extends JpaRepository<Level, Long> {
|
||||
|
||||
/**
|
||||
* 根据状态查找等级列表
|
||||
* @param status 状态
|
||||
* @return 等级列表
|
||||
*/
|
||||
List<Level> findByStatusOrderByMinPointsAsc(Integer status);
|
||||
}
|
||||
@@ -1,32 +0,0 @@
|
||||
package com.xlxumu.user.repository;
|
||||
|
||||
import com.xlxumu.user.entity.Message;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 用户消息数据访问接口
|
||||
*
|
||||
* @author xlxumu
|
||||
* @since 2024-01-15
|
||||
*/
|
||||
@Repository
|
||||
public interface MessageRepository extends JpaRepository<Message, Long> {
|
||||
|
||||
/**
|
||||
* 根据用户ID查找消息列表
|
||||
* @param userId 用户ID
|
||||
* @return 消息列表
|
||||
*/
|
||||
List<Message> findByUserIdOrderByCreatedAtDesc(Long userId);
|
||||
|
||||
/**
|
||||
* 根据用户ID和已读状态查找消息列表
|
||||
* @param userId 用户ID
|
||||
* @param isRead 是否已读
|
||||
* @return 消息列表
|
||||
*/
|
||||
List<Message> findByUserIdAndIsReadOrderByCreatedAtDesc(Long userId, Boolean isRead);
|
||||
}
|
||||
@@ -1,24 +0,0 @@
|
||||
package com.xlxumu.user.repository;
|
||||
|
||||
import com.xlxumu.user.entity.PointsRecord;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 积分记录数据访问接口
|
||||
*
|
||||
* @author xlxumu
|
||||
* @since 2024-01-15
|
||||
*/
|
||||
@Repository
|
||||
public interface PointsRecordRepository extends JpaRepository<PointsRecord, Long> {
|
||||
|
||||
/**
|
||||
* 根据用户ID查找积分记录列表
|
||||
* @param userId 用户ID
|
||||
* @return 积分记录列表
|
||||
*/
|
||||
List<PointsRecord> findByUserIdOrderByCreatedAtDesc(Long userId);
|
||||
}
|
||||
@@ -1,24 +0,0 @@
|
||||
package com.xlxumu.user.repository;
|
||||
|
||||
import com.xlxumu.user.entity.UserLevel;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
* 用户等级数据访问接口
|
||||
*
|
||||
* @author xlxumu
|
||||
* @since 2024-01-15
|
||||
*/
|
||||
@Repository
|
||||
public interface UserLevelRepository extends JpaRepository<UserLevel, Long> {
|
||||
|
||||
/**
|
||||
* 根据用户ID查找用户等级信息
|
||||
* @param userId 用户ID
|
||||
* @return 用户等级信息
|
||||
*/
|
||||
Optional<UserLevel> findByUserId(Long userId);
|
||||
}
|
||||
@@ -1,46 +0,0 @@
|
||||
package com.xlxumu.user.repository;
|
||||
|
||||
import com.xlxumu.user.entity.User;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
* 用户信息数据访问接口
|
||||
*
|
||||
* @author xlxumu
|
||||
* @since 2024-01-15
|
||||
*/
|
||||
@Repository
|
||||
public interface UserRepository extends JpaRepository<User, Long> {
|
||||
|
||||
/**
|
||||
* 根据用户名查找用户
|
||||
* @param username 用户名
|
||||
* @return 用户信息
|
||||
*/
|
||||
Optional<User> findByUsername(String username);
|
||||
|
||||
/**
|
||||
* 根据邮箱查找用户
|
||||
* @param email 邮箱
|
||||
* @return 用户信息
|
||||
*/
|
||||
Optional<User> findByEmail(String email);
|
||||
|
||||
/**
|
||||
* 根据手机号查找用户
|
||||
* @param phone 手机号
|
||||
* @return 用户信息
|
||||
*/
|
||||
Optional<User> findByPhone(String phone);
|
||||
|
||||
/**
|
||||
* 根据用户名和密码查找用户
|
||||
* @param username 用户名
|
||||
* @param passwordHash 密码哈希值
|
||||
* @return 用户信息
|
||||
*/
|
||||
Optional<User> findByUsernameAndPasswordHash(String username, String passwordHash);
|
||||
}
|
||||
@@ -1,150 +0,0 @@
|
||||
package com.xlxumu.user.service;
|
||||
|
||||
import com.xlxumu.user.entity.Address;
|
||||
import com.xlxumu.user.exception.UserException;
|
||||
import com.xlxumu.user.repository.AddressRepository;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
* 收货地址服务类
|
||||
* 提供收货地址相关的业务逻辑处理
|
||||
*
|
||||
* @author xlxumu
|
||||
* @since 2024-01-15
|
||||
*/
|
||||
@Service
|
||||
public class AddressService {
|
||||
|
||||
@Autowired
|
||||
private AddressRepository addressRepository;
|
||||
|
||||
/**
|
||||
* 创建收货地址
|
||||
* @param userId 用户ID
|
||||
* @param receiverName 收货人姓名
|
||||
* @param receiverPhone 收货人电话
|
||||
* @param province 省
|
||||
* @param city 市
|
||||
* @param district 区
|
||||
* @param detailAddress 详细地址
|
||||
* @param isDefault 是否默认地址
|
||||
* @return 创建的地址信息
|
||||
*/
|
||||
public Address createAddress(Long userId, String receiverName, String receiverPhone,
|
||||
String province, String city, String district, String detailAddress,
|
||||
Boolean isDefault) {
|
||||
// 如果设置为默认地址,需要将其他地址设为非默认
|
||||
if (isDefault != null && isDefault) {
|
||||
Address defaultAddress = addressRepository.findByUserIdAndIsDefault(userId, true);
|
||||
if (defaultAddress != null) {
|
||||
defaultAddress.setIsDefault(false);
|
||||
addressRepository.save(defaultAddress);
|
||||
}
|
||||
}
|
||||
|
||||
Address address = new Address();
|
||||
address.setUserId(userId);
|
||||
address.setReceiverName(receiverName);
|
||||
address.setReceiverPhone(receiverPhone);
|
||||
address.setProvince(province);
|
||||
address.setCity(city);
|
||||
address.setDistrict(district);
|
||||
address.setDetailAddress(detailAddress);
|
||||
address.setIsDefault(isDefault != null ? isDefault : false);
|
||||
address.setStatus(1);
|
||||
address.setCreatedAt(LocalDateTime.now());
|
||||
address.setUpdatedAt(LocalDateTime.now());
|
||||
|
||||
return addressRepository.save(address);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取收货地址列表
|
||||
* @param userId 用户ID
|
||||
* @return 地址列表
|
||||
*/
|
||||
public List<Address> getAddressList(Long userId) {
|
||||
return addressRepository.findByUserId(userId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取收货地址详情
|
||||
* @param addressId 地址ID
|
||||
* @return 地址信息
|
||||
*/
|
||||
public Address getAddressDetail(Long addressId) {
|
||||
Optional<Address> addressOptional = addressRepository.findById(addressId);
|
||||
if (!addressOptional.isPresent()) {
|
||||
throw new UserException("地址不存在", 404);
|
||||
}
|
||||
|
||||
return addressOptional.get();
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新收货地址
|
||||
* @param addressId 地址ID
|
||||
* @param receiverName 收货人姓名
|
||||
* @param receiverPhone 收货人电话
|
||||
* @param province 省
|
||||
* @param city 市
|
||||
* @param district 区
|
||||
* @param detailAddress 详细地址
|
||||
* @param isDefault 是否默认地址
|
||||
* @return 更新后的地址信息
|
||||
*/
|
||||
public Address updateAddress(Long addressId, String receiverName, String receiverPhone,
|
||||
String province, String city, String district, String detailAddress,
|
||||
Boolean isDefault) {
|
||||
Optional<Address> addressOptional = addressRepository.findById(addressId);
|
||||
if (!addressOptional.isPresent()) {
|
||||
throw new UserException("地址不存在", 404);
|
||||
}
|
||||
|
||||
Address address = addressOptional.get();
|
||||
|
||||
// 如果设置为默认地址,需要将其他地址设为非默认
|
||||
if (isDefault != null && isDefault) {
|
||||
Address defaultAddress = addressRepository.findByUserIdAndIsDefault(address.getUserId(), true);
|
||||
if (defaultAddress != null && !defaultAddress.getId().equals(addressId)) {
|
||||
defaultAddress.setIsDefault(false);
|
||||
addressRepository.save(defaultAddress);
|
||||
}
|
||||
}
|
||||
|
||||
address.setReceiverName(receiverName);
|
||||
address.setReceiverPhone(receiverPhone);
|
||||
address.setProvince(province);
|
||||
address.setCity(city);
|
||||
address.setDistrict(district);
|
||||
address.setDetailAddress(detailAddress);
|
||||
if (isDefault != null) {
|
||||
address.setIsDefault(isDefault);
|
||||
}
|
||||
address.setUpdatedAt(LocalDateTime.now());
|
||||
|
||||
return addressRepository.save(address);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除收货地址
|
||||
* @param addressId 地址ID
|
||||
*/
|
||||
public void deleteAddress(Long addressId) {
|
||||
Optional<Address> addressOptional = addressRepository.findById(addressId);
|
||||
if (!addressOptional.isPresent()) {
|
||||
throw new UserException("地址不存在", 404);
|
||||
}
|
||||
|
||||
Address address = addressOptional.get();
|
||||
address.setStatus(0); // 软删除
|
||||
address.setUpdatedAt(LocalDateTime.now());
|
||||
|
||||
addressRepository.save(address);
|
||||
}
|
||||
}
|
||||
@@ -1,64 +0,0 @@
|
||||
package com.xlxumu.user.service;
|
||||
|
||||
import com.xlxumu.user.entity.Feedback;
|
||||
import com.xlxumu.user.exception.UserException;
|
||||
import com.xlxumu.user.repository.FeedbackRepository;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 用户反馈服务类
|
||||
* 提供用户反馈相关的业务逻辑处理
|
||||
*
|
||||
* @author xlxumu
|
||||
* @since 2024-01-15
|
||||
*/
|
||||
@Service
|
||||
public class FeedbackService {
|
||||
|
||||
@Autowired
|
||||
private FeedbackRepository feedbackRepository;
|
||||
|
||||
/**
|
||||
* 提交反馈
|
||||
* @param userId 用户ID
|
||||
* @param title 反馈标题
|
||||
* @param content 反馈内容
|
||||
* @param type 反馈类型
|
||||
* @param contactInfo 联系方式
|
||||
* @return 提交的反馈对象
|
||||
*/
|
||||
public Feedback submitFeedback(Long userId, String title, String content, String type, String contactInfo) {
|
||||
if (title == null || title.trim().isEmpty()) {
|
||||
throw new UserException("反馈标题不能为空", 400);
|
||||
}
|
||||
|
||||
if (content == null || content.trim().isEmpty()) {
|
||||
throw new UserException("反馈内容不能为空", 400);
|
||||
}
|
||||
|
||||
Feedback feedback = new Feedback();
|
||||
feedback.setUserId(userId);
|
||||
feedback.setTitle(title);
|
||||
feedback.setContent(content);
|
||||
feedback.setType(type);
|
||||
feedback.setContactInfo(contactInfo);
|
||||
feedback.setStatus(1); // 1-待处理
|
||||
feedback.setCreatedAt(LocalDateTime.now());
|
||||
feedback.setUpdatedAt(LocalDateTime.now());
|
||||
|
||||
return feedbackRepository.save(feedback);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取反馈列表
|
||||
* @param userId 用户ID
|
||||
* @return 反馈列表
|
||||
*/
|
||||
public List<Feedback> getFeedbackList(Long userId) {
|
||||
return feedbackRepository.findByUserIdOrderByCreatedAtDesc(userId);
|
||||
}
|
||||
}
|
||||
@@ -1,57 +0,0 @@
|
||||
package com.xlxumu.user.service;
|
||||
|
||||
import com.xlxumu.user.entity.Level;
|
||||
import com.xlxumu.user.entity.UserLevel;
|
||||
import com.xlxumu.user.exception.UserException;
|
||||
import com.xlxumu.user.repository.LevelRepository;
|
||||
import com.xlxumu.user.repository.UserLevelRepository;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
* 等级管理服务类
|
||||
* 提供用户等级相关的业务逻辑处理
|
||||
*
|
||||
* @author xlxumu
|
||||
* @since 2024-01-15
|
||||
*/
|
||||
@Service
|
||||
public class LevelService {
|
||||
|
||||
@Autowired
|
||||
private UserLevelRepository userLevelRepository;
|
||||
|
||||
@Autowired
|
||||
private LevelRepository levelRepository;
|
||||
|
||||
/**
|
||||
* 获取用户当前等级
|
||||
* @param userId 用户ID
|
||||
* @return 用户等级信息
|
||||
*/
|
||||
public Level getUserCurrentLevel(Long userId) {
|
||||
Optional<UserLevel> userLevelOptional = userLevelRepository.findByUserId(userId);
|
||||
if (!userLevelOptional.isPresent()) {
|
||||
throw new UserException("用户等级信息不存在", 404);
|
||||
}
|
||||
|
||||
Long levelId = userLevelOptional.get().getLevelId();
|
||||
Optional<Level> levelOptional = levelRepository.findById(levelId);
|
||||
if (!levelOptional.isPresent()) {
|
||||
throw new UserException("等级信息不存在", 404);
|
||||
}
|
||||
|
||||
return levelOptional.get();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取等级列表
|
||||
* @return 等级列表
|
||||
*/
|
||||
public List<Level> getLevelList() {
|
||||
return levelRepository.findByStatusOrderByMinPointsAsc(1);
|
||||
}
|
||||
}
|
||||
@@ -1,67 +0,0 @@
|
||||
package com.xlxumu.user.service;
|
||||
|
||||
import com.xlxumu.user.entity.Message;
|
||||
import com.xlxumu.user.exception.UserException;
|
||||
import com.xlxumu.user.repository.MessageRepository;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
* 消息通知服务类
|
||||
* 提供用户消息相关的业务逻辑处理
|
||||
*
|
||||
* @author xlxumu
|
||||
* @since 2024-01-15
|
||||
*/
|
||||
@Service
|
||||
public class MessageService {
|
||||
|
||||
@Autowired
|
||||
private MessageRepository messageRepository;
|
||||
|
||||
/**
|
||||
* 获取消息列表
|
||||
* @param userId 用户ID
|
||||
* @return 消息列表
|
||||
*/
|
||||
public List<Message> getMessageList(Long userId) {
|
||||
return messageRepository.findByUserIdOrderByCreatedAtDesc(userId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 标记消息为已读
|
||||
* @param messageId 消息ID
|
||||
*/
|
||||
public void markMessageAsRead(Long messageId) {
|
||||
Optional<Message> messageOptional = messageRepository.findById(messageId);
|
||||
if (!messageOptional.isPresent()) {
|
||||
throw new UserException("消息不存在", 404);
|
||||
}
|
||||
|
||||
Message message = messageOptional.get();
|
||||
if (!message.getIsRead()) {
|
||||
message.setIsRead(true);
|
||||
message.setReadAt(LocalDateTime.now());
|
||||
messageRepository.save(message);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除消息
|
||||
* @param messageId 消息ID
|
||||
*/
|
||||
public void deleteMessage(Long messageId) {
|
||||
Optional<Message> messageOptional = messageRepository.findById(messageId);
|
||||
if (!messageOptional.isPresent()) {
|
||||
throw new UserException("消息不存在", 404);
|
||||
}
|
||||
|
||||
Message message = messageOptional.get();
|
||||
message.setStatus(0); // 软删除
|
||||
messageRepository.save(message);
|
||||
}
|
||||
}
|
||||
@@ -1,96 +0,0 @@
|
||||
package com.xlxumu.user.service;
|
||||
|
||||
import com.xlxumu.user.entity.PointsRecord;
|
||||
import com.xlxumu.user.entity.UserLevel;
|
||||
import com.xlxumu.user.exception.UserException;
|
||||
import com.xlxumu.user.repository.PointsRecordRepository;
|
||||
import com.xlxumu.user.repository.UserLevelRepository;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
* 积分管理服务类
|
||||
* 提供用户积分相关的业务逻辑处理
|
||||
*
|
||||
* @author xlxumu
|
||||
* @since 2024-01-15
|
||||
*/
|
||||
@Service
|
||||
public class PointsService {
|
||||
|
||||
@Autowired
|
||||
private UserLevelRepository userLevelRepository;
|
||||
|
||||
@Autowired
|
||||
private PointsRecordRepository pointsRecordRepository;
|
||||
|
||||
/**
|
||||
* 获取用户积分余额
|
||||
* @param userId 用户ID
|
||||
* @return 积分余额
|
||||
*/
|
||||
public Integer getUserPointsBalance(Long userId) {
|
||||
Optional<UserLevel> userLevelOptional = userLevelRepository.findByUserId(userId);
|
||||
if (!userLevelOptional.isPresent()) {
|
||||
throw new UserException("用户等级信息不存在", 404);
|
||||
}
|
||||
|
||||
return userLevelOptional.get().getCurrentPoints();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取积分记录列表
|
||||
* @param userId 用户ID
|
||||
* @return 积分记录列表
|
||||
*/
|
||||
public List<PointsRecord> getPointsRecordList(Long userId) {
|
||||
return pointsRecordRepository.findByUserIdOrderByCreatedAtDesc(userId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加积分记录
|
||||
* @param userId 用户ID
|
||||
* @param points 积分数量(正数表示增加,负数表示减少)
|
||||
* @param changeType 变更类型
|
||||
* @param description 描述
|
||||
* @return 更新后的积分余额
|
||||
*/
|
||||
public Integer addPointsRecord(Long userId, Integer points, String changeType, String description) {
|
||||
// 更新用户积分余额
|
||||
Optional<UserLevel> userLevelOptional = userLevelRepository.findByUserId(userId);
|
||||
UserLevel userLevel;
|
||||
|
||||
if (!userLevelOptional.isPresent()) {
|
||||
// 创建新的用户等级记录
|
||||
userLevel = new UserLevel();
|
||||
userLevel.setUserId(userId);
|
||||
userLevel.setLevelId(1L); // 默认等级ID
|
||||
userLevel.setCurrentPoints(points > 0 ? points : 0);
|
||||
userLevel.setCreatedAt(LocalDateTime.now());
|
||||
userLevel.setUpdatedAt(LocalDateTime.now());
|
||||
} else {
|
||||
userLevel = userLevelOptional.get();
|
||||
int newPoints = userLevel.getCurrentPoints() + points;
|
||||
userLevel.setCurrentPoints(newPoints > 0 ? newPoints : 0);
|
||||
userLevel.setUpdatedAt(LocalDateTime.now());
|
||||
}
|
||||
|
||||
userLevelRepository.save(userLevel);
|
||||
|
||||
// 记录积分变更
|
||||
PointsRecord pointsRecord = new PointsRecord();
|
||||
pointsRecord.setUserId(userId);
|
||||
pointsRecord.setPoints(points);
|
||||
pointsRecord.setChangeType(changeType);
|
||||
pointsRecord.setDescription(description);
|
||||
pointsRecord.setCreatedAt(LocalDateTime.now());
|
||||
|
||||
pointsRecordRepository.save(pointsRecord);
|
||||
|
||||
return userLevel.getCurrentPoints();
|
||||
}
|
||||
}
|
||||
@@ -1,201 +0,0 @@
|
||||
package com.xlxumu.user.service;
|
||||
|
||||
import com.xlxumu.user.entity.User;
|
||||
import com.xlxumu.user.exception.UserException;
|
||||
import com.xlxumu.user.repository.UserRepository;
|
||||
import com.xlxumu.user.util.JwtUtil;
|
||||
import com.xlxumu.user.util.PasswordUtil;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
* 用户服务类
|
||||
* 提供用户相关的业务逻辑处理
|
||||
*
|
||||
* @author xlxumu
|
||||
* @since 2024-01-15
|
||||
*/
|
||||
@Service
|
||||
public class UserService {
|
||||
|
||||
@Autowired
|
||||
private UserRepository userRepository;
|
||||
|
||||
@Autowired
|
||||
private PasswordUtil passwordUtil;
|
||||
|
||||
@Autowired
|
||||
private JwtUtil jwtUtil;
|
||||
|
||||
/**
|
||||
* 用户注册
|
||||
* @param username 用户名
|
||||
* @param email 邮箱
|
||||
* @param phone 手机号
|
||||
* @param password 密码
|
||||
* @return JWT token
|
||||
*/
|
||||
public String register(String username, String email, String phone, String password) {
|
||||
// 检查用户名是否已存在
|
||||
if (userRepository.findByUsername(username).isPresent()) {
|
||||
throw new UserException("用户名已存在", 400);
|
||||
}
|
||||
|
||||
// 检查邮箱是否已存在
|
||||
if (userRepository.findByEmail(email).isPresent()) {
|
||||
throw new UserException("邮箱已被注册", 400);
|
||||
}
|
||||
|
||||
// 检查手机号是否已存在
|
||||
if (userRepository.findByPhone(phone).isPresent()) {
|
||||
throw new UserException("手机号已被注册", 400);
|
||||
}
|
||||
|
||||
// 创建新用户
|
||||
User user = new User();
|
||||
user.setUsername(username);
|
||||
user.setEmail(email);
|
||||
user.setPhone(phone);
|
||||
|
||||
// 密码加密
|
||||
String salt = passwordUtil.generateSalt();
|
||||
String hashedPassword = passwordUtil.hashPassword(password, salt);
|
||||
user.setPasswordHash(hashedPassword);
|
||||
|
||||
user.setCreatedAt(LocalDateTime.now());
|
||||
user.setUpdatedAt(LocalDateTime.now());
|
||||
|
||||
userRepository.save(user);
|
||||
|
||||
// 生成JWT token
|
||||
return jwtUtil.generateToken(username);
|
||||
}
|
||||
|
||||
/**
|
||||
* 用户登录
|
||||
* @param username 用户名
|
||||
* @param password 密码
|
||||
* @return JWT token
|
||||
*/
|
||||
public String login(String username, String password) {
|
||||
Optional<User> userOptional = userRepository.findByUsername(username);
|
||||
if (!userOptional.isPresent()) {
|
||||
throw new UserException("用户不存在", 400);
|
||||
}
|
||||
|
||||
User user = userOptional.get();
|
||||
|
||||
// 验证密码
|
||||
if (!passwordUtil.verifyPassword(password, "", user.getPasswordHash())) {
|
||||
throw new UserException("密码错误", 400);
|
||||
}
|
||||
|
||||
// 更新最后登录时间
|
||||
user.setLastLoginAt(LocalDateTime.now());
|
||||
userRepository.save(user);
|
||||
|
||||
// 生成JWT token
|
||||
return jwtUtil.generateToken(username);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取用户信息
|
||||
* @param userId 用户ID
|
||||
* @return 用户信息
|
||||
*/
|
||||
public User getUserInfo(Long userId) {
|
||||
Optional<User> userOptional = userRepository.findById(userId);
|
||||
if (!userOptional.isPresent()) {
|
||||
throw new UserException("用户不存在", 404);
|
||||
}
|
||||
|
||||
return userOptional.get();
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新用户信息
|
||||
* @param userId 用户ID
|
||||
* @param nickname 昵称
|
||||
* @param avatarUrl 头像URL
|
||||
* @param gender 性别
|
||||
* @param birthday 生日
|
||||
* @param realName 真实姓名
|
||||
* @return 更新后的用户信息
|
||||
*/
|
||||
public User updateUserInfo(Long userId, String nickname, String avatarUrl, Integer gender,
|
||||
LocalDateTime birthday, String realName) {
|
||||
Optional<User> userOptional = userRepository.findById(userId);
|
||||
if (!userOptional.isPresent()) {
|
||||
throw new UserException("用户不存在", 404);
|
||||
}
|
||||
|
||||
User user = userOptional.get();
|
||||
user.setNickname(nickname);
|
||||
user.setAvatarUrl(avatarUrl);
|
||||
user.setGender(gender);
|
||||
user.setBirthday(birthday);
|
||||
user.setRealName(realName);
|
||||
user.setUpdatedAt(LocalDateTime.now());
|
||||
|
||||
return userRepository.save(user);
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改用户密码
|
||||
* @param userId 用户ID
|
||||
* @param oldPassword 旧密码
|
||||
* @param newPassword 新密码
|
||||
*/
|
||||
public void changePassword(Long userId, String oldPassword, String newPassword) {
|
||||
Optional<User> userOptional = userRepository.findById(userId);
|
||||
if (!userOptional.isPresent()) {
|
||||
throw new UserException("用户不存在", 404);
|
||||
}
|
||||
|
||||
User user = userOptional.get();
|
||||
|
||||
// 验证旧密码
|
||||
if (!passwordUtil.verifyPassword(oldPassword, "", user.getPasswordHash())) {
|
||||
throw new UserException("旧密码错误", 400);
|
||||
}
|
||||
|
||||
// 加密新密码
|
||||
String salt = passwordUtil.generateSalt();
|
||||
String hashedPassword = passwordUtil.hashPassword(newPassword, salt);
|
||||
user.setPasswordHash(hashedPassword);
|
||||
user.setUpdatedAt(LocalDateTime.now());
|
||||
|
||||
userRepository.save(user);
|
||||
}
|
||||
|
||||
/**
|
||||
* 管理员获取用户列表
|
||||
* @return 用户列表
|
||||
*/
|
||||
public List<User> getUserList() {
|
||||
return userRepository.findAll();
|
||||
}
|
||||
|
||||
/**
|
||||
* 管理员更新用户状态
|
||||
* @param userId 用户ID
|
||||
* @param status 状态
|
||||
* @return 更新后的用户信息
|
||||
*/
|
||||
public User updateUserStatus(Long userId, Integer status) {
|
||||
Optional<User> userOptional = userRepository.findById(userId);
|
||||
if (!userOptional.isPresent()) {
|
||||
throw new UserException("用户不存在", 404);
|
||||
}
|
||||
|
||||
User user = userOptional.get();
|
||||
user.setStatus(status);
|
||||
user.setUpdatedAt(LocalDateTime.now());
|
||||
|
||||
return userRepository.save(user);
|
||||
}
|
||||
}
|
||||
@@ -1,29 +0,0 @@
|
||||
package com.xlxumu.user.util;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
@Component
|
||||
public class JwtTokenUtil {
|
||||
|
||||
@Autowired
|
||||
private JwtUtil jwtUtil;
|
||||
|
||||
/**
|
||||
* 从请求中获取用户ID
|
||||
* @param request HTTP请求
|
||||
* @return 用户ID
|
||||
*/
|
||||
public Long getUserIdFromRequest(HttpServletRequest request) {
|
||||
String authorizationHeader = request.getHeader("Authorization");
|
||||
|
||||
if (authorizationHeader != null && authorizationHeader.startsWith("Bearer ")) {
|
||||
String token = authorizationHeader.substring(7);
|
||||
return jwtUtil.getUserIdFromToken(token);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -1,114 +0,0 @@
|
||||
package com.xlxumu.user.util;
|
||||
|
||||
import io.jsonwebtoken.Claims;
|
||||
import io.jsonwebtoken.Jwts;
|
||||
import io.jsonwebtoken.SignatureAlgorithm;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.function.Function;
|
||||
|
||||
/**
|
||||
* JWT工具类
|
||||
*
|
||||
* @author xlxumu
|
||||
* @since 2024-01-15
|
||||
*/
|
||||
@Component
|
||||
public class JwtUtil {
|
||||
|
||||
@Value("${jwt.secret}")
|
||||
private String secret;
|
||||
|
||||
@Value("${jwt.expiration}")
|
||||
private Long expiration;
|
||||
|
||||
/**
|
||||
* 从token中获取用户ID
|
||||
* @param token JWT token
|
||||
* @return 用户ID
|
||||
*/
|
||||
public Long getUserIdFromToken(String token) {
|
||||
return Long.parseLong(getClaimFromToken(token, Claims::getSubject));
|
||||
}
|
||||
|
||||
/**
|
||||
* 从token中获取过期时间
|
||||
* @param token JWT token
|
||||
* @return 过期时间
|
||||
*/
|
||||
public Date getExpirationDateFromToken(String token) {
|
||||
return getClaimFromToken(token, Claims::getExpiration);
|
||||
}
|
||||
|
||||
/**
|
||||
* 从token中获取自定义声明
|
||||
* @param token JWT token
|
||||
* @param claimsResolver 声明解析器
|
||||
* @param <T> 声明类型
|
||||
* @return 声明值
|
||||
*/
|
||||
public <T> T getClaimFromToken(String token, Function<Claims, T> claimsResolver) {
|
||||
final Claims claims = getAllClaimsFromToken(token);
|
||||
return claimsResolver.apply(claims);
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析token中的所有声明
|
||||
* @param token JWT token
|
||||
* @return 所有声明
|
||||
*/
|
||||
private Claims getAllClaimsFromToken(String token) {
|
||||
return Jwts.parser().setSigningKey(secret).parseClaimsJws(token).getBody();
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查token是否过期
|
||||
* @param token JWT token
|
||||
* @return 是否过期
|
||||
*/
|
||||
private Boolean isTokenExpired(String token) {
|
||||
final Date expiration = getExpirationDateFromToken(token);
|
||||
return expiration.before(new Date());
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成token
|
||||
* @param userId 用户ID
|
||||
* @return JWT token
|
||||
*/
|
||||
public String generateToken(Long userId) {
|
||||
Map<String, Object> claims = new HashMap<>();
|
||||
return doGenerateToken(claims, userId.toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建token
|
||||
* @param claims 声明
|
||||
* @param subject 主题(用户ID)
|
||||
* @return JWT token
|
||||
*/
|
||||
private String doGenerateToken(Map<String, Object> claims, String subject) {
|
||||
return Jwts.builder()
|
||||
.setClaims(claims)
|
||||
.setSubject(subject)
|
||||
.setIssuedAt(new Date(System.currentTimeMillis()))
|
||||
.setExpiration(new Date(System.currentTimeMillis() + expiration))
|
||||
.signWith(SignatureAlgorithm.HS512, secret)
|
||||
.compact();
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证token
|
||||
* @param token JWT token
|
||||
* @param userId 用户ID
|
||||
* @return 是否有效
|
||||
*/
|
||||
public Boolean validateToken(String token, Long userId) {
|
||||
final Long tokenUserId = getUserIdFromToken(token);
|
||||
return (tokenUserId.equals(userId) && !isTokenExpired(token));
|
||||
}
|
||||
}
|
||||
@@ -1,73 +0,0 @@
|
||||
package com.xlxumu.user.util;
|
||||
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.SecureRandom;
|
||||
|
||||
/**
|
||||
* 密码工具类
|
||||
*
|
||||
* @author xlxumu
|
||||
* @since 2024-01-15
|
||||
*/
|
||||
@Component
|
||||
public class PasswordUtil {
|
||||
|
||||
private static final String ALGORITHM = "SHA-256";
|
||||
private static final int SALT_LENGTH = 32;
|
||||
|
||||
/**
|
||||
* 生成随机盐值
|
||||
* @return 盐值
|
||||
*/
|
||||
public String generateSalt() {
|
||||
SecureRandom random = new SecureRandom();
|
||||
byte[] salt = new byte[SALT_LENGTH];
|
||||
random.nextBytes(salt);
|
||||
return bytesToHex(salt);
|
||||
}
|
||||
|
||||
/**
|
||||
* 对密码进行哈希处理
|
||||
* @param password 密码
|
||||
* @param salt 盐值
|
||||
* @return 哈希值
|
||||
*/
|
||||
public String hashPassword(String password, String salt) {
|
||||
try {
|
||||
MessageDigest md = MessageDigest.getInstance(ALGORITHM);
|
||||
md.update(salt.getBytes());
|
||||
byte[] hashedPassword = md.digest(password.getBytes());
|
||||
return bytesToHex(hashedPassword);
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
throw new RuntimeException("Error hashing password", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证密码
|
||||
* @param password 密码
|
||||
* @param salt 盐值
|
||||
* @param hashedPassword 哈希值
|
||||
* @return 是否匹配
|
||||
*/
|
||||
public boolean verifyPassword(String password, String salt, String hashedPassword) {
|
||||
String newHash = hashPassword(password, salt);
|
||||
return newHash.equals(hashedPassword);
|
||||
}
|
||||
|
||||
/**
|
||||
* 将字节数组转换为十六进制字符串
|
||||
* @param bytes 字节数组
|
||||
* @return 十六进制字符串
|
||||
*/
|
||||
private String bytesToHex(byte[] bytes) {
|
||||
StringBuilder result = new StringBuilder();
|
||||
for (byte b : bytes) {
|
||||
result.append(String.format("%02x", b));
|
||||
}
|
||||
return result.toString();
|
||||
}
|
||||
}
|
||||
@@ -1,335 +0,0 @@
|
||||
openapi: 3.0.3
|
||||
info:
|
||||
title: 用户中心服务 - 收货地址管理API
|
||||
description: 用户收货地址管理接口
|
||||
version: 1.0.0
|
||||
|
||||
paths:
|
||||
/api/addresses:
|
||||
post:
|
||||
summary: 创建收货地址
|
||||
description: 创建新的收货地址
|
||||
parameters:
|
||||
- name: Authorization
|
||||
in: header
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
description: JWT访问令牌 (Bearer token)
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
name:
|
||||
type: string
|
||||
description: 收货人姓名
|
||||
phone:
|
||||
type: string
|
||||
description: 收货人电话
|
||||
province:
|
||||
type: string
|
||||
description: 省份
|
||||
city:
|
||||
type: string
|
||||
description: 城市
|
||||
district:
|
||||
type: string
|
||||
description: 区县
|
||||
detailAddress:
|
||||
type: string
|
||||
description: 详细地址
|
||||
isDefault:
|
||||
type: boolean
|
||||
description: 是否默认地址
|
||||
required:
|
||||
- name
|
||||
- phone
|
||||
- province
|
||||
- city
|
||||
- district
|
||||
- detailAddress
|
||||
responses:
|
||||
'200':
|
||||
description: 地址创建成功
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
code:
|
||||
type: integer
|
||||
example: 200
|
||||
message:
|
||||
type: string
|
||||
example: "地址创建成功"
|
||||
data:
|
||||
$ref: '#/components/schemas/Address'
|
||||
'401':
|
||||
description: 未授权访问
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ErrorResponse'
|
||||
get:
|
||||
summary: 获取收货地址列表
|
||||
description: 获取当前用户的所有收货地址
|
||||
parameters:
|
||||
- name: Authorization
|
||||
in: header
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
description: JWT访问令牌 (Bearer token)
|
||||
responses:
|
||||
'200':
|
||||
description: 获取成功
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
code:
|
||||
type: integer
|
||||
example: 200
|
||||
message:
|
||||
type: string
|
||||
example: "获取成功"
|
||||
data:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/Address'
|
||||
'401':
|
||||
description: 未授权访问
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ErrorResponse'
|
||||
|
||||
/api/addresses/{addressId):
|
||||
get:
|
||||
summary: 获取收货地址详情
|
||||
description: 获取指定收货地址的详细信息
|
||||
parameters:
|
||||
- name: Authorization
|
||||
in: header
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
description: JWT访问令牌 (Bearer token)
|
||||
- name: addressId
|
||||
in: path
|
||||
required: true
|
||||
schema:
|
||||
type: integer
|
||||
format: int64
|
||||
description: 地址ID
|
||||
responses:
|
||||
'200':
|
||||
description: 获取成功
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
code:
|
||||
type: integer
|
||||
example: 200
|
||||
message:
|
||||
type: string
|
||||
example: "获取成功"
|
||||
data:
|
||||
$ref: '#/components/schemas/Address'
|
||||
'401':
|
||||
description: 未授权访问
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ErrorResponse'
|
||||
'404':
|
||||
description: 地址不存在
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ErrorResponse'
|
||||
put:
|
||||
summary: 更新收货地址
|
||||
description: 更新指定收货地址的信息
|
||||
parameters:
|
||||
- name: Authorization
|
||||
in: header
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
description: JWT访问令牌 (Bearer token)
|
||||
- name: addressId
|
||||
in: path
|
||||
required: true
|
||||
schema:
|
||||
type: integer
|
||||
format: int64
|
||||
description: 地址ID
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
name:
|
||||
type: string
|
||||
description: 收货人姓名
|
||||
phone:
|
||||
type: string
|
||||
description: 收货人电话
|
||||
province:
|
||||
type: string
|
||||
description: 省份
|
||||
city:
|
||||
type: string
|
||||
description: 城市
|
||||
district:
|
||||
type: string
|
||||
description: 区县
|
||||
detailAddress:
|
||||
type: string
|
||||
description: 详细地址
|
||||
isDefault:
|
||||
type: boolean
|
||||
description: 是否默认地址
|
||||
responses:
|
||||
'200':
|
||||
description: 地址更新成功
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
code:
|
||||
type: integer
|
||||
example: 200
|
||||
message:
|
||||
type: string
|
||||
example: "地址更新成功"
|
||||
data:
|
||||
$ref: '#/components/schemas/Address'
|
||||
'401':
|
||||
description: 未授权访问
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ErrorResponse'
|
||||
'404':
|
||||
description: 地址不存在
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ErrorResponse'
|
||||
delete:
|
||||
summary: 删除收货地址
|
||||
description: 删除指定收货地址
|
||||
parameters:
|
||||
- name: Authorization
|
||||
in: header
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
description: JWT访问令牌 (Bearer token)
|
||||
- name: addressId
|
||||
in: path
|
||||
required: true
|
||||
schema:
|
||||
type: integer
|
||||
format: int64
|
||||
description: 地址ID
|
||||
responses:
|
||||
'200':
|
||||
description: 地址删除成功
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
code:
|
||||
type: integer
|
||||
example: 200
|
||||
message:
|
||||
type: string
|
||||
example: "地址删除成功"
|
||||
'401':
|
||||
description: 未授权访问
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ErrorResponse'
|
||||
'404':
|
||||
description: 地址不存在
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ErrorResponse'
|
||||
|
||||
components:
|
||||
schemas:
|
||||
Address:
|
||||
type: object
|
||||
properties:
|
||||
id:
|
||||
type: integer
|
||||
format: int64
|
||||
description: 地址ID
|
||||
userId:
|
||||
type: integer
|
||||
format: int64
|
||||
description: 用户ID
|
||||
name:
|
||||
type: string
|
||||
description: 收货人姓名
|
||||
phone:
|
||||
type: string
|
||||
description: 收货人电话
|
||||
province:
|
||||
type: string
|
||||
description: 省份
|
||||
city:
|
||||
type: string
|
||||
description: 城市
|
||||
district:
|
||||
type: string
|
||||
description: 区县
|
||||
detailAddress:
|
||||
type: string
|
||||
description: 详细地址
|
||||
isDefault:
|
||||
type: boolean
|
||||
description: 是否默认地址
|
||||
status:
|
||||
type: integer
|
||||
description: 地址状态 (1-正常, 0-删除)
|
||||
createdAt:
|
||||
type: string
|
||||
format: date-time
|
||||
description: 创建时间
|
||||
updatedAt:
|
||||
type: string
|
||||
format: date-time
|
||||
description: 更新时间
|
||||
|
||||
ErrorResponse:
|
||||
type: object
|
||||
properties:
|
||||
timestamp:
|
||||
type: string
|
||||
format: date-time
|
||||
description: 错误时间戳
|
||||
status:
|
||||
type: integer
|
||||
description: HTTP状态码
|
||||
error:
|
||||
type: string
|
||||
description: 错误信息
|
||||
path:
|
||||
type: string
|
||||
description: 请求路径
|
||||
@@ -1,156 +0,0 @@
|
||||
openapi: 3.0.3
|
||||
info:
|
||||
title: 用户中心服务 - 用户反馈API
|
||||
description: 用户反馈提交、查询等接口
|
||||
version: 1.0.0
|
||||
|
||||
paths:
|
||||
/api/feedback:
|
||||
post:
|
||||
summary: 提交反馈
|
||||
description: 用户提交反馈意见
|
||||
parameters:
|
||||
- name: Authorization
|
||||
in: header
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
description: JWT访问令牌 (Bearer token)
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
title:
|
||||
type: string
|
||||
description: 反馈标题
|
||||
content:
|
||||
type: string
|
||||
description: 反馈内容
|
||||
type:
|
||||
type: string
|
||||
description: 反馈类型
|
||||
contactInfo:
|
||||
type: string
|
||||
description: 联系方式
|
||||
required:
|
||||
- title
|
||||
- content
|
||||
responses:
|
||||
'200':
|
||||
description: 反馈提交成功
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
code:
|
||||
type: integer
|
||||
example: 200
|
||||
message:
|
||||
type: string
|
||||
example: "反馈提交成功"
|
||||
data:
|
||||
$ref: '#/components/schemas/Feedback'
|
||||
'400':
|
||||
description: 请求参数错误
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ErrorResponse'
|
||||
'401':
|
||||
description: 未授权访问
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ErrorResponse'
|
||||
get:
|
||||
summary: 获取反馈列表
|
||||
description: 获取当前用户的反馈列表
|
||||
parameters:
|
||||
- name: Authorization
|
||||
in: header
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
description: JWT访问令牌 (Bearer token)
|
||||
responses:
|
||||
'200':
|
||||
description: 获取成功
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
code:
|
||||
type: integer
|
||||
example: 200
|
||||
message:
|
||||
type: string
|
||||
example: "获取成功"
|
||||
data:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/Feedback'
|
||||
'401':
|
||||
description: 未授权访问
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ErrorResponse'
|
||||
|
||||
components:
|
||||
schemas:
|
||||
Feedback:
|
||||
type: object
|
||||
properties:
|
||||
id:
|
||||
type: integer
|
||||
format: int64
|
||||
description: 反馈ID
|
||||
userId:
|
||||
type: integer
|
||||
format: int64
|
||||
description: 用户ID
|
||||
title:
|
||||
type: string
|
||||
description: 反馈标题
|
||||
content:
|
||||
type: string
|
||||
description: 反馈内容
|
||||
type:
|
||||
type: string
|
||||
description: 反馈类型
|
||||
contactInfo:
|
||||
type: string
|
||||
description: 联系方式
|
||||
status:
|
||||
type: integer
|
||||
description: 反馈状态 (1-待处理, 2-处理中, 3-已处理)
|
||||
createdAt:
|
||||
type: string
|
||||
format: date-time
|
||||
description: 创建时间
|
||||
updatedAt:
|
||||
type: string
|
||||
format: date-time
|
||||
description: 更新时间
|
||||
|
||||
ErrorResponse:
|
||||
type: object
|
||||
properties:
|
||||
timestamp:
|
||||
type: string
|
||||
format: date-time
|
||||
description: 错误时间戳
|
||||
status:
|
||||
type: integer
|
||||
description: HTTP状态码
|
||||
error:
|
||||
type: string
|
||||
description: 错误信息
|
||||
path:
|
||||
type: string
|
||||
description: 请求路径
|
||||
@@ -1,190 +0,0 @@
|
||||
openapi: 3.0.3
|
||||
info:
|
||||
title: 用户中心服务 - 消息通知API
|
||||
description: 用户消息查询、标记已读、删除等接口
|
||||
version: 1.0.0
|
||||
|
||||
paths:
|
||||
/api/messages:
|
||||
get:
|
||||
summary: 获取消息列表
|
||||
description: 获取当前用户的消息列表
|
||||
parameters:
|
||||
- name: Authorization
|
||||
in: header
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
description: JWT访问令牌 (Bearer token)
|
||||
responses:
|
||||
'200':
|
||||
description: 获取成功
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
code:
|
||||
type: integer
|
||||
example: 200
|
||||
message:
|
||||
type: string
|
||||
example: "获取成功"
|
||||
data:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/Message'
|
||||
'401':
|
||||
description: 未授权访问
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ErrorResponse'
|
||||
|
||||
/api/messages/{messageId}/read:
|
||||
put:
|
||||
summary: 标记消息为已读
|
||||
description: 将指定消息标记为已读状态
|
||||
parameters:
|
||||
- name: Authorization
|
||||
in: header
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
description: JWT访问令牌 (Bearer token)
|
||||
- name: messageId
|
||||
in: path
|
||||
required: true
|
||||
schema:
|
||||
type: integer
|
||||
format: int64
|
||||
description: 消息ID
|
||||
responses:
|
||||
'200':
|
||||
description: 标记成功
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
code:
|
||||
type: integer
|
||||
example: 200
|
||||
message:
|
||||
type: string
|
||||
example: "标记成功"
|
||||
'401':
|
||||
description: 未授权访问
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ErrorResponse'
|
||||
'404':
|
||||
description: 消息不存在
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ErrorResponse'
|
||||
|
||||
/api/messages/{messageId}:
|
||||
delete:
|
||||
summary: 删除消息
|
||||
description: 删除指定消息
|
||||
parameters:
|
||||
- name: Authorization
|
||||
in: header
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
description: JWT访问令牌 (Bearer token)
|
||||
- name: messageId
|
||||
in: path
|
||||
required: true
|
||||
schema:
|
||||
type: integer
|
||||
format: int64
|
||||
description: 消息ID
|
||||
responses:
|
||||
'200':
|
||||
description: 删除成功
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
code:
|
||||
type: integer
|
||||
example: 200
|
||||
message:
|
||||
type: string
|
||||
example: "删除成功"
|
||||
'401':
|
||||
description: 未授权访问
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ErrorResponse'
|
||||
'404':
|
||||
description: 消息不存在
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ErrorResponse'
|
||||
|
||||
components:
|
||||
schemas:
|
||||
Message:
|
||||
type: object
|
||||
properties:
|
||||
id:
|
||||
type: integer
|
||||
format: int64
|
||||
description: 消息ID
|
||||
userId:
|
||||
type: integer
|
||||
format: int64
|
||||
description: 用户ID
|
||||
title:
|
||||
type: string
|
||||
description: 消息标题
|
||||
content:
|
||||
type: string
|
||||
description: 消息内容
|
||||
type:
|
||||
type: string
|
||||
description: 消息类型
|
||||
isRead:
|
||||
type: boolean
|
||||
description: 是否已读
|
||||
readAt:
|
||||
type: string
|
||||
format: date-time
|
||||
description: 阅读时间
|
||||
status:
|
||||
type: integer
|
||||
description: 消息状态 (1-正常, 0-删除)
|
||||
createdAt:
|
||||
type: string
|
||||
format: date-time
|
||||
description: 创建时间
|
||||
updatedAt:
|
||||
type: string
|
||||
format: date-time
|
||||
description: 更新时间
|
||||
|
||||
ErrorResponse:
|
||||
type: object
|
||||
properties:
|
||||
timestamp:
|
||||
type: string
|
||||
format: date-time
|
||||
description: 错误时间戳
|
||||
status:
|
||||
type: integer
|
||||
description: HTTP状态码
|
||||
error:
|
||||
type: string
|
||||
description: 错误信息
|
||||
path:
|
||||
type: string
|
||||
description: 请求路径
|
||||
@@ -1,69 +0,0 @@
|
||||
openapi: 3.0.3
|
||||
info:
|
||||
title: 用户中心服务API
|
||||
description: 用户中心服务提供用户管理、收货地址、积分、消息通知、用户反馈等核心功能的RESTful API接口
|
||||
version: 1.0.0
|
||||
|
||||
servers:
|
||||
- url: http://localhost:8080
|
||||
description: 本地开发环境
|
||||
|
||||
paths:
|
||||
# 用户管理相关接口
|
||||
/api/users/register:
|
||||
$ref: './user-api.yaml#/paths/~1api~1users~1register'
|
||||
/api/users/login:
|
||||
$ref: './user-api.yaml#/paths/~1api~1users~1login'
|
||||
/api/users/info:
|
||||
$ref: './user-api.yaml#/paths/~1api~1users~1info'
|
||||
/api/users/password:
|
||||
$ref: './user-api.yaml#/paths/~1api~1users~1password'
|
||||
/api/users/list:
|
||||
$ref: './user-api.yaml#/paths/~1api~1users~1list'
|
||||
/api/users/{userId}/status:
|
||||
$ref: './user-api.yaml#/paths/~1api~1users~1{userId}~1status'
|
||||
|
||||
# 收货地址相关接口
|
||||
/api/addresses:
|
||||
$ref: './address-api.yaml#/paths/~1api~1addresses'
|
||||
/api/addresses/{addressId}:
|
||||
$ref: './address-api.yaml#/paths/~1api~1addresses~1{addressId}'
|
||||
|
||||
# 积分管理相关接口
|
||||
/api/points/balance:
|
||||
$ref: './points-api.yaml#/paths/~1api~1points~1balance'
|
||||
/api/points/records:
|
||||
$ref: './points-api.yaml#/paths/~1api~1points~1records'
|
||||
/api/points/level:
|
||||
$ref: './points-api.yaml#/paths/~1api~1points~1level'
|
||||
/api/points/levels:
|
||||
$ref: './points-api.yaml#/paths/~1api~1points~1levels'
|
||||
|
||||
# 消息通知相关接口
|
||||
/api/messages:
|
||||
$ref: './message-api.yaml#/paths/~1api~1messages'
|
||||
/api/messages/{messageId}/read:
|
||||
$ref: './message-api.yaml#/paths/~1api~1messages~1{messageId}~1read'
|
||||
/api/messages/{messageId}:
|
||||
$ref: './message-api.yaml#/paths/~1api~1messages~1{messageId}'
|
||||
|
||||
# 用户反馈相关接口
|
||||
/api/feedback:
|
||||
$ref: './feedback-api.yaml#/paths/~1api~1feedback'
|
||||
|
||||
components:
|
||||
schemas:
|
||||
User:
|
||||
$ref: './user-api.yaml#/components/schemas/User'
|
||||
Address:
|
||||
$ref: './address-api.yaml#/components/schemas/Address'
|
||||
PointsRecord:
|
||||
$ref: './points-api.yaml#/components/schemas/PointsRecord'
|
||||
Level:
|
||||
$ref: './points-api.yaml#/components/schemas/Level'
|
||||
Message:
|
||||
$ref: './message-api.yaml#/components/schemas/Message'
|
||||
Feedback:
|
||||
$ref: './feedback-api.yaml#/components/schemas/Feedback'
|
||||
ErrorResponse:
|
||||
$ref: './user-api.yaml#/components/schemas/ErrorResponse'
|
||||
@@ -1,213 +0,0 @@
|
||||
openapi: 3.0.3
|
||||
info:
|
||||
title: 用户中心服务 - 积分管理API
|
||||
description: 用户积分查询、积分记录查询等接口
|
||||
version: 1.0.0
|
||||
|
||||
paths:
|
||||
/api/points/balance:
|
||||
get:
|
||||
summary: 获取用户积分余额
|
||||
description: 获取当前用户的积分余额
|
||||
parameters:
|
||||
- name: Authorization
|
||||
in: header
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
description: JWT访问令牌 (Bearer token)
|
||||
responses:
|
||||
'200':
|
||||
description: 获取成功
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
code:
|
||||
type: integer
|
||||
example: 200
|
||||
message:
|
||||
type: string
|
||||
example: "获取成功"
|
||||
data:
|
||||
type: object
|
||||
properties:
|
||||
balance:
|
||||
type: integer
|
||||
description: 积分余额
|
||||
'401':
|
||||
description: 未授权访问
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ErrorResponse'
|
||||
|
||||
/api/points/records:
|
||||
get:
|
||||
summary: 获取积分记录列表
|
||||
description: 获取当前用户的积分变动记录列表
|
||||
parameters:
|
||||
- name: Authorization
|
||||
in: header
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
description: JWT访问令牌 (Bearer token)
|
||||
responses:
|
||||
'200':
|
||||
description: 获取成功
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
code:
|
||||
type: integer
|
||||
example: 200
|
||||
message:
|
||||
type: string
|
||||
example: "获取成功"
|
||||
data:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/PointsRecord'
|
||||
'401':
|
||||
description: 未授权访问
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ErrorResponse'
|
||||
|
||||
/api/points/level:
|
||||
get:
|
||||
summary: 获取用户当前等级
|
||||
description: 获取当前用户的等级信息
|
||||
parameters:
|
||||
- name: Authorization
|
||||
in: header
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
description: JWT访问令牌 (Bearer token)
|
||||
responses:
|
||||
'200':
|
||||
description: 获取成功
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
code:
|
||||
type: integer
|
||||
example: 200
|
||||
message:
|
||||
type: string
|
||||
example: "获取成功"
|
||||
data:
|
||||
$ref: '#/components/schemas/Level'
|
||||
'401':
|
||||
description: 未授权访问
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ErrorResponse'
|
||||
|
||||
/api/points/levels:
|
||||
get:
|
||||
summary: 获取等级列表
|
||||
description: 获取所有可用的用户等级列表
|
||||
responses:
|
||||
'200':
|
||||
description: 获取成功
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
code:
|
||||
type: integer
|
||||
example: 200
|
||||
message:
|
||||
type: string
|
||||
example: "获取成功"
|
||||
data:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/Level'
|
||||
|
||||
components:
|
||||
schemas:
|
||||
PointsRecord:
|
||||
type: object
|
||||
properties:
|
||||
id:
|
||||
type: integer
|
||||
format: int64
|
||||
description: 记录ID
|
||||
userId:
|
||||
type: integer
|
||||
format: int64
|
||||
description: 用户ID
|
||||
changeType:
|
||||
type: string
|
||||
description: 变动类型 (earn-获得, consume-消费)
|
||||
points:
|
||||
type: integer
|
||||
description: 积分数量
|
||||
description:
|
||||
type: string
|
||||
description: 描述
|
||||
createdAt:
|
||||
type: string
|
||||
format: date-time
|
||||
description: 创建时间
|
||||
|
||||
Level:
|
||||
type: object
|
||||
properties:
|
||||
id:
|
||||
type: integer
|
||||
format: int64
|
||||
description: 等级ID
|
||||
name:
|
||||
type: string
|
||||
description: 等级名称
|
||||
minPoints:
|
||||
type: integer
|
||||
description: 最小积分要求
|
||||
maxPoints:
|
||||
type: integer
|
||||
description: 最大积分要求
|
||||
discountRate:
|
||||
type: number
|
||||
format: double
|
||||
description: 折扣率
|
||||
status:
|
||||
type: integer
|
||||
description: 状态 (1-启用, 0-禁用)
|
||||
createdAt:
|
||||
type: string
|
||||
format: date-time
|
||||
description: 创建时间
|
||||
updatedAt:
|
||||
type: string
|
||||
format: date-time
|
||||
description: 更新时间
|
||||
|
||||
ErrorResponse:
|
||||
type: object
|
||||
properties:
|
||||
timestamp:
|
||||
type: string
|
||||
format: date-time
|
||||
description: 错误时间戳
|
||||
status:
|
||||
type: integer
|
||||
description: HTTP状态码
|
||||
error:
|
||||
type: string
|
||||
description: 错误信息
|
||||
path:
|
||||
type: string
|
||||
description: 请求路径
|
||||
@@ -1,413 +0,0 @@
|
||||
openapi: 3.0.3
|
||||
info:
|
||||
title: 用户中心服务 - 用户管理API
|
||||
description: 用户注册、登录、信息管理等接口
|
||||
version: 1.0.0
|
||||
|
||||
paths:
|
||||
/api/users/register:
|
||||
post:
|
||||
summary: 用户注册
|
||||
description: 用户注册接口,创建新用户账户
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
username:
|
||||
type: string
|
||||
description: 用户名
|
||||
password:
|
||||
type: string
|
||||
description: 密码
|
||||
email:
|
||||
type: string
|
||||
description: 邮箱
|
||||
phone:
|
||||
type: string
|
||||
description: 手机号
|
||||
required:
|
||||
- username
|
||||
- password
|
||||
responses:
|
||||
'200':
|
||||
description: 注册成功
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
code:
|
||||
type: integer
|
||||
example: 200
|
||||
message:
|
||||
type: string
|
||||
example: "注册成功"
|
||||
data:
|
||||
$ref: '#/components/schemas/User'
|
||||
'400':
|
||||
description: 请求参数错误
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ErrorResponse'
|
||||
|
||||
/api/users/login:
|
||||
post:
|
||||
summary: 用户登录
|
||||
description: 用户登录接口,获取访问令牌
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
username:
|
||||
type: string
|
||||
description: 用户名
|
||||
password:
|
||||
type: string
|
||||
description: 密码
|
||||
required:
|
||||
- username
|
||||
- password
|
||||
responses:
|
||||
'200':
|
||||
description: 登录成功
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
code:
|
||||
type: integer
|
||||
example: 200
|
||||
message:
|
||||
type: string
|
||||
example: "登录成功"
|
||||
data:
|
||||
type: object
|
||||
properties:
|
||||
token:
|
||||
type: string
|
||||
description: JWT访问令牌
|
||||
'401':
|
||||
description: 用户名或密码错误
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ErrorResponse'
|
||||
|
||||
/api/users/info:
|
||||
get:
|
||||
summary: 获取用户信息
|
||||
description: 获取当前登录用户的详细信息
|
||||
parameters:
|
||||
- name: Authorization
|
||||
in: header
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
description: JWT访问令牌 (Bearer token)
|
||||
responses:
|
||||
'200':
|
||||
description: 获取成功
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
code:
|
||||
type: integer
|
||||
example: 200
|
||||
message:
|
||||
type: string
|
||||
example: "获取成功"
|
||||
data:
|
||||
$ref: '#/components/schemas/User'
|
||||
'401':
|
||||
description: 未授权访问
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ErrorResponse'
|
||||
put:
|
||||
summary: 更新用户信息
|
||||
description: 更新当前登录用户的个人信息
|
||||
parameters:
|
||||
- name: Authorization
|
||||
in: header
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
description: JWT访问令牌 (Bearer token)
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
nickname:
|
||||
type: string
|
||||
description: 昵称
|
||||
avatar:
|
||||
type: string
|
||||
description: 头像URL
|
||||
gender:
|
||||
type: string
|
||||
description: 性别
|
||||
birthday:
|
||||
type: string
|
||||
format: date
|
||||
description: 生日
|
||||
responses:
|
||||
'200':
|
||||
description: 更新成功
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
code:
|
||||
type: integer
|
||||
example: 200
|
||||
message:
|
||||
type: string
|
||||
example: "更新成功"
|
||||
data:
|
||||
$ref: '#/components/schemas/User'
|
||||
'401':
|
||||
description: 未授权访问
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ErrorResponse'
|
||||
|
||||
/api/users/password:
|
||||
put:
|
||||
summary: 修改密码
|
||||
description: 修改用户登录密码
|
||||
parameters:
|
||||
- name: Authorization
|
||||
in: header
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
description: JWT访问令牌 (Bearer token)
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
oldPassword:
|
||||
type: string
|
||||
description: 旧密码
|
||||
newPassword:
|
||||
type: string
|
||||
description: 新密码
|
||||
required:
|
||||
- oldPassword
|
||||
- newPassword
|
||||
responses:
|
||||
'200':
|
||||
description: 密码修改成功
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
code:
|
||||
type: integer
|
||||
example: 200
|
||||
message:
|
||||
type: string
|
||||
example: "密码修改成功"
|
||||
'401':
|
||||
description: 未授权访问或旧密码错误
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ErrorResponse'
|
||||
|
||||
/api/users/list:
|
||||
get:
|
||||
summary: 获取用户列表
|
||||
description: 管理员获取用户列表(分页)
|
||||
parameters:
|
||||
- name: Authorization
|
||||
in: header
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
description: JWT访问令牌 (Bearer token)
|
||||
- name: page
|
||||
in: query
|
||||
schema:
|
||||
type: integer
|
||||
default: 1
|
||||
description: 页码
|
||||
- name: size
|
||||
in: query
|
||||
schema:
|
||||
type: integer
|
||||
default: 10
|
||||
description: 每页数量
|
||||
responses:
|
||||
'200':
|
||||
description: 获取成功
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
code:
|
||||
type: integer
|
||||
example: 200
|
||||
message:
|
||||
type: string
|
||||
example: "获取成功"
|
||||
data:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/User'
|
||||
'401':
|
||||
description: 未授权访问
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ErrorResponse'
|
||||
'403':
|
||||
description: 权限不足
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ErrorResponse'
|
||||
|
||||
/api/users/{userId}/status:
|
||||
put:
|
||||
summary: 更新用户状态
|
||||
description: 管理员更新用户状态
|
||||
parameters:
|
||||
- name: Authorization
|
||||
in: header
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
description: JWT访问令牌 (Bearer token)
|
||||
- name: userId
|
||||
in: path
|
||||
required: true
|
||||
schema:
|
||||
type: integer
|
||||
format: int64
|
||||
description: 用户ID
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
status:
|
||||
type: integer
|
||||
description: 用户状态 (1-正常, 0-禁用)
|
||||
required:
|
||||
- status
|
||||
responses:
|
||||
'200':
|
||||
description: 状态更新成功
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
code:
|
||||
type: integer
|
||||
example: 200
|
||||
message:
|
||||
type: string
|
||||
example: "状态更新成功"
|
||||
'401':
|
||||
description: 未授权访问
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ErrorResponse'
|
||||
'403':
|
||||
description: 权限不足
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ErrorResponse'
|
||||
'404':
|
||||
description: 用户不存在
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ErrorResponse'
|
||||
|
||||
components:
|
||||
schemas:
|
||||
User:
|
||||
type: object
|
||||
properties:
|
||||
id:
|
||||
type: integer
|
||||
format: int64
|
||||
description: 用户ID
|
||||
username:
|
||||
type: string
|
||||
description: 用户名
|
||||
email:
|
||||
type: string
|
||||
description: 邮箱
|
||||
phone:
|
||||
type: string
|
||||
description: 手机号
|
||||
nickname:
|
||||
type: string
|
||||
description: 昵称
|
||||
avatar:
|
||||
type: string
|
||||
description: 头像URL
|
||||
gender:
|
||||
type: string
|
||||
description: 性别
|
||||
birthday:
|
||||
type: string
|
||||
format: date
|
||||
description: 生日
|
||||
status:
|
||||
type: integer
|
||||
description: 用户状态 (1-正常, 0-禁用)
|
||||
createdAt:
|
||||
type: string
|
||||
format: date-time
|
||||
description: 创建时间
|
||||
updatedAt:
|
||||
type: string
|
||||
format: date-time
|
||||
description: 更新时间
|
||||
|
||||
ErrorResponse:
|
||||
type: object
|
||||
properties:
|
||||
timestamp:
|
||||
type: string
|
||||
format: date-time
|
||||
description: 错误时间戳
|
||||
status:
|
||||
type: integer
|
||||
description: HTTP状态码
|
||||
error:
|
||||
type: string
|
||||
description: 错误信息
|
||||
path:
|
||||
type: string
|
||||
description: 请求路径
|
||||
@@ -1,17 +0,0 @@
|
||||
spring.application.name=user-center-service
|
||||
server.port=8080
|
||||
|
||||
# 数据库配置
|
||||
spring.datasource.url=jdbc:mysql://localhost:3306/xlxumu_user?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai
|
||||
spring.datasource.username=root
|
||||
spring.datasource.password=root
|
||||
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
|
||||
|
||||
# JPA配置
|
||||
spring.jpa.hibernate.ddl-auto=update
|
||||
spring.jpa.show-sql=true
|
||||
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL8Dialect
|
||||
|
||||
# JWT配置
|
||||
jwt.secret=xlxumu_user_center_secret_key_2024
|
||||
jwt.expiration=86400000
|
||||
@@ -1,10 +0,0 @@
|
||||
server.port=8082
|
||||
|
||||
spring.datasource.url=jdbc:mysql://localhost:3306/xlxumu_user?useSSL=false&serverTimezone=UTC
|
||||
spring.datasource.username=root
|
||||
spring.datasource.password=
|
||||
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
|
||||
|
||||
spring.jpa.hibernate.ddl-auto=update
|
||||
spring.jpa.show-sql=true
|
||||
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL8Dialect
|
||||
Binary file not shown.
@@ -1 +0,0 @@
|
||||
com/xlxumu/user/UserCenterApplication.class
|
||||
@@ -1 +0,0 @@
|
||||
/Users/ainongkeji/code/vue/xlxumu/backend-java/services/user-center-service/src/main/java/com/xlxumu/user/UserCenterApplication.java
|
||||
Reference in New Issue
Block a user