Compare commits
8 Commits
1540fe6dab
...
master
Author | SHA1 | Date | |
---|---|---|---|
6e89255f1e | |||
272c674b4a | |||
c33cbd799d | |||
74c0908b58 | |||
c173c480b2 | |||
050fdd7137 | |||
ca14774891 | |||
349cc22069 |
@@ -40,7 +40,9 @@ jobs:
|
||||
- name: 安装 Maven
|
||||
run: |
|
||||
echo "安装 Maven..."
|
||||
sudo apt update
|
||||
# 修复GPG签名错误问题
|
||||
sudo apt-get clean
|
||||
sudo apt-get update --allow-releaseinfo-change
|
||||
sudo apt install -y maven
|
||||
echo "Maven 版本:"
|
||||
mvn --version
|
||||
@@ -90,14 +92,7 @@ jobs:
|
||||
docker stop light-delivery-container 2>/dev/null || echo "没有运行中的容器"
|
||||
docker rm light-delivery-container 2>/dev/null || echo "没有可删除的容器"
|
||||
|
||||
- name: 备份当前镜像(可选)
|
||||
run: |
|
||||
# 为当前运行中的镜像创建备份标签
|
||||
if docker images light-delivery-app:latest --quiet | grep -q .; then
|
||||
BACKUP_TAG="backup-$(date +%Y%m%d-%H%M%S)"
|
||||
docker tag light-delivery-app:latest light-delivery-app:$BACKUP_TAG
|
||||
echo "已创建备份: light-delivery-app:$BACKUP_TAG"
|
||||
fi
|
||||
# 已移除备份镜像逻辑,节省存储空间
|
||||
|
||||
- name: 运行新容器
|
||||
run: |
|
||||
@@ -140,15 +135,6 @@ jobs:
|
||||
|
||||
- name: 清理资源
|
||||
run: |
|
||||
# 清理旧的备份镜像(保留最近5个)
|
||||
echo "清理旧的备份镜像..."
|
||||
docker images light-delivery-app --filter "reference=light-delivery-app:backup-*" \
|
||||
--format "{{.Tag}}\t{{.CreatedAt}}" | \
|
||||
sort -k2 -r | \
|
||||
tail -n +6 | \
|
||||
awk '{print $1}' | \
|
||||
xargs -r -I {} docker rmi light-delivery-app:{} || echo "无需清理"
|
||||
|
||||
# 清理无用镜像和容器
|
||||
docker system prune -f
|
||||
|
||||
|
248
README.md
248
README.md
@@ -86,6 +86,99 @@ src
|
||||
|
||||
位置信息现在存储在服务器内存缓存中,而不是持久化到数据库,以提高访问速度和减少数据库负载。
|
||||
|
||||
#### WebSocket接口和交互逻辑
|
||||
|
||||
系统通过WebSocket实现实时位置同步,端点为:`/ws/location`。
|
||||
|
||||
##### 连接建立
|
||||
客户端通过WebSocket连接到`/ws/location?userId={userId}`端点建立连接,需要在查询参数中提供用户ID。
|
||||
|
||||
##### 消息格式
|
||||
所有消息都使用JSON格式。
|
||||
|
||||
###### 1. 客户端发送的消息类型
|
||||
|
||||
1. **updateLocation(位置更新)** - 更新用户位置
|
||||
```json
|
||||
{
|
||||
"type": "updateLocation",
|
||||
"userId": 123,
|
||||
"latitude": 25.0342,
|
||||
"longitude": 102.7057,
|
||||
"timestamp": 1634567890000
|
||||
}
|
||||
```
|
||||
|
||||
###### 2. 服务器发送的消息类型
|
||||
|
||||
1. **subscribed(订阅成功响应)** - 服务器确认订阅成功
|
||||
```json
|
||||
{
|
||||
"type": "subscribed",
|
||||
"userId": 123
|
||||
}
|
||||
```
|
||||
|
||||
2. **onlineUserList(在线用户列表)** - 服务器发送当前在线用户列表
|
||||
```json
|
||||
{
|
||||
"type": "onlineUserList",
|
||||
"users": [
|
||||
{
|
||||
"userId": 123,
|
||||
"name": "张三",
|
||||
"role": "DELIVERY_PERSON",
|
||||
"userStatus": true,
|
||||
"lastUpdateTime": 1634567890000,
|
||||
"locationData": {
|
||||
"latitude": 25.0342,
|
||||
"longitude": 102.7057,
|
||||
"timestamp": 1634567890000
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
3. **userLocationList(用户位置列表)** - 服务器每30秒发送所有在线用户的位置列表
|
||||
```json
|
||||
{
|
||||
"type": "userLocationList",
|
||||
"users": [
|
||||
{
|
||||
"userId": 123,
|
||||
"locationData": {
|
||||
"latitude": 25.0342,
|
||||
"longitude": 102.7057,
|
||||
"timestamp": 1634567890000
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
##### 交互流程
|
||||
|
||||
```
|
||||
[用户签到] --> B{签到成功?}
|
||||
B -->|是| C[建立WebSocket连接]
|
||||
B -->|否| D[签到失败]
|
||||
C --> E[自动订阅位置更新]
|
||||
E --> F[接收subscribed确认]
|
||||
F --> G[接收在线用户列表]
|
||||
G --> H[开始位置更新循环]
|
||||
H --> I[发送位置更新]
|
||||
I --> J[每30秒接收一次位置列表]
|
||||
K[用户签退] --> L{签退成功?}
|
||||
L -->|是| M[自动取消订阅并关闭WebSocket连接]
|
||||
L -->|否| N[签退失败]
|
||||
```
|
||||
|
||||
##### 角色区分
|
||||
- 管理员(ADMIN)和配送员(DELIVERY_PERSON)都可以接收位置更新
|
||||
- 位置广播消息中包含用户角色信息,便于客户端区分显示
|
||||
- 只有已签到用户才会收到位置更新广播
|
||||
|
||||
### 数据模型
|
||||
|
||||
主要实体包括:
|
||||
@@ -167,6 +260,12 @@ java -jar target/light-delivery-1.0.0.jar --spring.profiles.active=local
|
||||
java -jar target/light-delivery-1.0.0.jar --spring.profiles.active=test
|
||||
```
|
||||
|
||||
在PowerShell中也可以使用以下命令运行本地环境:
|
||||
```powershell
|
||||
$env:SPRING_PROFILES_ACTIVE = "local"
|
||||
mvn spring-boot:run
|
||||
```
|
||||
|
||||
### 运行Docker容器
|
||||
|
||||
```bash
|
||||
@@ -238,6 +337,7 @@ deploy.bat
|
||||
- `GET /user/info` - 获取用户信息
|
||||
- `POST /user/logout` - 用户登出
|
||||
- `POST /user/signin` - 用户签到
|
||||
- `POST /user/signout` - 用户签退
|
||||
- `POST /user/register` - 注册为配送员
|
||||
|
||||
### 订单相关
|
||||
@@ -248,7 +348,7 @@ deploy.bat
|
||||
### 配送员相关
|
||||
- `GET /delivery-persons` - 获取配送员列表
|
||||
- `GET /delivery-persons/{id}` - 获取配送员详情
|
||||
- `PUT /delivery-persons/{id}/location` - 更新配送员位置
|
||||
- `GET /delivery-persons/{id}/orders` - 获取配送员订单
|
||||
|
||||
### 员工管理相关(仅限管理员访问)
|
||||
- `GET /employees` - 获取员工列表
|
||||
@@ -258,9 +358,151 @@ deploy.bat
|
||||
|
||||
### 位置同步相关
|
||||
- `GET /location-sync/delivery-persons/locations` - 获取所有配送员位置
|
||||
- WebSocket端点: `/ws/location` - 实时位置同步
|
||||
|
||||
### WebSocket消息格式
|
||||
|
||||
客户端和服务器通过WebSocket发送JSON格式的消息。
|
||||
|
||||
#### 客户端发送的消息类型
|
||||
|
||||
1. **updateLocation(位置更新)** - 更新用户位置
|
||||
```json
|
||||
{
|
||||
"type": "updateLocation",
|
||||
"userId": 123,
|
||||
"latitude": 25.0342,
|
||||
"longitude": 102.7057,
|
||||
"timestamp": 1634567890000
|
||||
}
|
||||
```
|
||||
|
||||
#### 服务器发送的消息类型
|
||||
|
||||
1. **subscribed(订阅成功响应)** - 服务器确认订阅成功
|
||||
```json
|
||||
{
|
||||
"type": "subscribed",
|
||||
"userId": 123
|
||||
}
|
||||
```
|
||||
|
||||
2. **onlineUserList(在线用户列表)** - 服务器发送当前在线用户列表
|
||||
```json
|
||||
{
|
||||
"type": "onlineUserList",
|
||||
"users": [
|
||||
{
|
||||
"userId": 123,
|
||||
"name": "张三",
|
||||
"role": "DELIVERY_PERSON",
|
||||
"userStatus": true,
|
||||
"lastUpdateTime": 1634567890000,
|
||||
"locationData": {
|
||||
"latitude": 25.0342,
|
||||
"longitude": 102.7057,
|
||||
"timestamp": 1634567890000
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
3. **userLocationList(用户位置列表)** - 服务器每30秒发送所有在线用户的位置列表
|
||||
```json
|
||||
{
|
||||
"type": "userLocationList",
|
||||
"users": [
|
||||
{
|
||||
"userId": 123,
|
||||
"locationData": {
|
||||
"latitude": 25.0342,
|
||||
"longitude": 102.7057,
|
||||
"timestamp": 1634567890000
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## API接口响应格式
|
||||
|
||||
### 用户签到接口 `/user/signin`
|
||||
|
||||
#### 请求参数
|
||||
- Method: `POST`
|
||||
- Headers: `Authorization: Bearer <token>`
|
||||
- Body:
|
||||
```json
|
||||
{
|
||||
"latitude": 25.0342,
|
||||
"longitude": 102.7057,
|
||||
"timestamp": 1634567890000
|
||||
}
|
||||
```
|
||||
|
||||
#### 成功响应
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"userInfo": {
|
||||
"id": 123,
|
||||
"name": "张三",
|
||||
"phone": "13800138000",
|
||||
"role": "DELIVERY_PERSON",
|
||||
"openid": "oK4fS5ABCDEF123456"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### 失败响应
|
||||
```json
|
||||
{
|
||||
"success": false,
|
||||
"message": "错误信息"
|
||||
}
|
||||
```
|
||||
|
||||
### 用户签退接口 `/user/signout`
|
||||
|
||||
#### 请求参数
|
||||
- Method: `POST`
|
||||
- Headers: `Authorization: Bearer <token>`
|
||||
|
||||
#### 成功响应
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"message": "签退成功"
|
||||
}
|
||||
```
|
||||
|
||||
#### 失败响应
|
||||
```json
|
||||
{
|
||||
"success": false,
|
||||
"message": "错误信息"
|
||||
}
|
||||
```
|
||||
|
||||
## 最近更新
|
||||
|
||||
### WebSocket使用方式变更(重要变更)
|
||||
为了更好地分离关注点和提高系统安全性,我们对WebSocket使用方式进行了重要变更:
|
||||
- 移除了WebSocket中的签到/签退功能,这些操作现在完全通过REST API进行
|
||||
- WebSocket现在仅用于位置同步,不再处理用户状态变更
|
||||
- 用户需要先通过REST API签到,然后才能建立WebSocket连接并接收位置更新
|
||||
- 用户签退时,服务器会自动取消订阅并关闭WebSocket连接
|
||||
- 客户端不再需要发送subscribe/unsubscribe消息,这些操作由服务器自动处理
|
||||
- 服务器现在每30秒批量发送一次所有在线用户的位置信息,而不是实时发送单个用户位置更新
|
||||
|
||||
### WebSocket位置同步增强(新增)
|
||||
为了支持管理员和配送员都能接收位置更新信息,我们对WebSocket位置同步功能进行了增强:
|
||||
- 修改了LocationWebSocketHandler,使其支持所有用户类型(包括管理员和配送员)
|
||||
- 在位置消息中添加了用户角色信息,便于客户端区分并使用不同图标显示
|
||||
- 重构了WebSocket处理逻辑,使其更加通用和可扩展
|
||||
- 实现了在线用户列表管理和广播机制
|
||||
|
||||
### 用户角色管理优化(新增)
|
||||
为解决数据一致性问题,我们优化了用户角色管理机制:
|
||||
- 移除了User表中的role字段
|
||||
@@ -292,4 +534,6 @@ deploy.bat
|
||||
3. 配送员位置信息具有时效性,默认5分钟内有效
|
||||
4. 位置历史记录功能已被移除,如有需要可使用第三方服务进行位置追踪
|
||||
5. 员工管理接口仅限管理员角色访问
|
||||
6. 用户角色信息现在通过员工表动态获取,确保数据一致性
|
||||
6. 用户角色信息现在通过员工表动态获取,确保数据一致性
|
||||
7. WebSocket位置同步现在支持所有已签到用户(包括管理员和配送员)
|
||||
8. WebSocket仅用于位置同步,签到/签退操作需通过REST API完成
|
@@ -68,18 +68,6 @@ public class DeliveryPersonController {
|
||||
response.setCurrentLocation(location);
|
||||
return ResponseEntity.ok(response);
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新指定货运人员位置。
|
||||
* @param id 货运人员ID
|
||||
* @param locationRequest 包含经纬度
|
||||
* @return 操作结果
|
||||
*/
|
||||
@PutMapping("/{id}/location")
|
||||
public ResponseEntity<String> updateLocation(@PathVariable Long id, @RequestBody LocationRequest locationRequest) {
|
||||
deliveryPersonService.updateLocation(id, locationRequest.getLongitude(), locationRequest.getLatitude());
|
||||
return ResponseEntity.ok("位置更新成功");
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取货运人员的当前订单。
|
||||
@@ -112,13 +100,4 @@ public class DeliveryPersonController {
|
||||
}).collect(Collectors.toList());
|
||||
return ResponseEntity.ok(orders);
|
||||
}
|
||||
|
||||
/**
|
||||
* 位置请求体
|
||||
*/
|
||||
@Data
|
||||
public static class LocationRequest {
|
||||
private Double longitude;
|
||||
private Double latitude;
|
||||
}
|
||||
}
|
@@ -0,0 +1,138 @@
|
||||
package com.light.delivery.controller;
|
||||
|
||||
import com.light.delivery.model.Employee;
|
||||
import com.light.delivery.model.User;
|
||||
import com.light.delivery.model.UserRole;
|
||||
import com.light.delivery.service.EmployeeService;
|
||||
import com.light.delivery.service.UserService;
|
||||
import com.light.delivery.service.impl.UserServiceImpl;
|
||||
import com.light.delivery.util.JwtUtil;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 员工管理控制器,提供员工信息的增删改查功能。
|
||||
* 仅限管理员角色访问。
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/employees")
|
||||
public class EmployeeController {
|
||||
|
||||
@Autowired
|
||||
private EmployeeService employeeService;
|
||||
|
||||
@Autowired
|
||||
private UserService userService;
|
||||
|
||||
@Autowired
|
||||
private JwtUtil jwtUtil;
|
||||
|
||||
@Autowired
|
||||
private UserServiceImpl userServiceImpl;
|
||||
|
||||
/**
|
||||
* 获取所有员工列表
|
||||
* @return 员工信息列表
|
||||
*/
|
||||
@GetMapping
|
||||
public ResponseEntity<?> getAllEmployees(HttpServletRequest request) {
|
||||
try {
|
||||
User user = getUserFromToken(request);
|
||||
UserRole userRole = userServiceImpl.getUserRole(user);
|
||||
if (!UserRole.ADMIN.equals(userRole)) {
|
||||
return ResponseEntity.status(403).body("权限不足,仅管理员可访问");
|
||||
}
|
||||
|
||||
List<Employee> employees = employeeService.getAllEmployees();
|
||||
return ResponseEntity.ok(employees);
|
||||
} catch (Exception e) {
|
||||
return ResponseEntity.status(401).body("认证失败: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加新员工
|
||||
* @param employee 员工信息
|
||||
* @return 添加结果
|
||||
*/
|
||||
@PostMapping
|
||||
public ResponseEntity<?> addEmployee(@RequestBody Employee employee, HttpServletRequest request) {
|
||||
try {
|
||||
User user = getUserFromToken(request);
|
||||
UserRole userRole = userServiceImpl.getUserRole(user);
|
||||
if (!UserRole.ADMIN.equals(userRole)) {
|
||||
return ResponseEntity.status(403).body("权限不足,仅管理员可访问");
|
||||
}
|
||||
|
||||
Employee savedEmployee = employeeService.saveEmployee(employee);
|
||||
return ResponseEntity.ok(savedEmployee);
|
||||
} catch (Exception e) {
|
||||
return ResponseEntity.status(401).body("认证失败: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新员工信息
|
||||
* @param id 员工ID
|
||||
* @param employee 员工信息
|
||||
* @return 更新结果
|
||||
*/
|
||||
@PutMapping("/{id}")
|
||||
public ResponseEntity<?> updateEmployee(@PathVariable Long id, @RequestBody Employee employee, HttpServletRequest request) {
|
||||
try {
|
||||
User user = getUserFromToken(request);
|
||||
UserRole userRole = userServiceImpl.getUserRole(user);
|
||||
if (!UserRole.ADMIN.equals(userRole)) {
|
||||
return ResponseEntity.status(403).body("权限不足,仅管理员可访问");
|
||||
}
|
||||
|
||||
Employee updatedEmployee = employeeService.updateEmployee(id, employee);
|
||||
if (updatedEmployee == null) {
|
||||
return ResponseEntity.status(404).body("员工不存在");
|
||||
}
|
||||
return ResponseEntity.ok(updatedEmployee);
|
||||
} catch (Exception e) {
|
||||
return ResponseEntity.status(401).body("认证失败: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除员工
|
||||
* @param id 员工ID
|
||||
* @return 删除结果
|
||||
*/
|
||||
@DeleteMapping("/{id}")
|
||||
public ResponseEntity<?> deleteEmployee(@PathVariable Long id, HttpServletRequest request) {
|
||||
try {
|
||||
User user = getUserFromToken(request);
|
||||
UserRole userRole = userServiceImpl.getUserRole(user);
|
||||
if (!UserRole.ADMIN.equals(userRole)) {
|
||||
return ResponseEntity.status(403).body("权限不足,仅管理员可访问");
|
||||
}
|
||||
|
||||
employeeService.deleteEmployee(id);
|
||||
return ResponseEntity.ok("员工删除成功");
|
||||
} catch (Exception e) {
|
||||
return ResponseEntity.status(401).body("认证失败: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 从请求中提取用户信息
|
||||
* @param request HTTP请求
|
||||
* @return 用户对象
|
||||
*/
|
||||
private User getUserFromToken(HttpServletRequest request) {
|
||||
String bearerToken = request.getHeader("Authorization");
|
||||
if (bearerToken != null && bearerToken.startsWith("Bearer ")) {
|
||||
String token = bearerToken.substring(7);
|
||||
String openid = jwtUtil.extractUsername(token);
|
||||
return userService.getUserInfo(token);
|
||||
}
|
||||
throw new IllegalArgumentException("Authorization token is missing");
|
||||
}
|
||||
}
|
@@ -1,76 +0,0 @@
|
||||
package com.light.delivery.controller;
|
||||
|
||||
import com.light.delivery.model.DeliveryPerson;
|
||||
import com.light.delivery.service.DeliveryPersonService;
|
||||
import lombok.Data;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 位置同步控制器,提供配送员位置信息查询接口。
|
||||
* 用于获取所有已签到配送员的实时位置信息。
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/location-sync")
|
||||
public class LocationSyncController {
|
||||
|
||||
/**
|
||||
* 配送员服务依赖注入
|
||||
*/
|
||||
@Autowired
|
||||
private DeliveryPersonService deliveryPersonService;
|
||||
|
||||
/**
|
||||
* 获取所有已签到配送员的实时位置。
|
||||
* 仅返回有位置信息的配送员(最近有更新位置的)。
|
||||
* @return 配送员位置列表
|
||||
*/
|
||||
@GetMapping("/delivery-persons/locations")
|
||||
public ResponseEntity<List<DeliveryPersonLocation>> getDeliveryPersonLocations() {
|
||||
List<DeliveryPerson> allDeliveryPersons = deliveryPersonService.getAllDeliveryPersons();
|
||||
|
||||
// 过滤出有位置信息的配送员(最近有更新位置的)
|
||||
List<DeliveryPersonLocation> locations = allDeliveryPersons.stream()
|
||||
.filter(person -> person.getLatitude() != null && person.getLongitude() != null)
|
||||
.map(person -> {
|
||||
DeliveryPersonLocation location = new DeliveryPersonLocation();
|
||||
location.setDeliveryPersonId(person.getId());
|
||||
location.setLatitude(person.getLatitude());
|
||||
location.setLongitude(person.getLongitude());
|
||||
location.setStatus(person.getStatus());
|
||||
return location;
|
||||
})
|
||||
.collect(Collectors.toList());
|
||||
|
||||
return ResponseEntity.ok(locations);
|
||||
}
|
||||
|
||||
/**
|
||||
* 配送员位置信息DTO,用于向前端返回配送员位置数据。
|
||||
*/
|
||||
@Data
|
||||
public static class DeliveryPersonLocation {
|
||||
/**
|
||||
* 配送员ID
|
||||
*/
|
||||
private Long deliveryPersonId;
|
||||
|
||||
/**
|
||||
* 纬度
|
||||
*/
|
||||
private Double latitude;
|
||||
|
||||
/**
|
||||
* 经度
|
||||
*/
|
||||
private Double longitude;
|
||||
|
||||
/**
|
||||
* 状态
|
||||
*/
|
||||
private String status;
|
||||
}
|
||||
}
|
@@ -1,17 +1,21 @@
|
||||
package com.light.delivery.controller;
|
||||
|
||||
import com.light.delivery.dto.UserInfoResponse;
|
||||
import com.light.delivery.dto.SignOutResponse;
|
||||
import com.light.delivery.dto.SignInResponse;
|
||||
import com.light.delivery.model.LoginResponse;
|
||||
import com.light.delivery.model.RegisterRequest;
|
||||
import com.light.delivery.model.User;
|
||||
import com.light.delivery.model.UserRole;
|
||||
import com.light.delivery.model.WxLoginRequest;
|
||||
import com.light.delivery.service.LocationWebSocketHandler;
|
||||
import com.light.delivery.service.UserService;
|
||||
import com.light.delivery.service.impl.UserServiceImpl;
|
||||
import com.light.delivery.util.JwtUtil;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
@@ -45,6 +49,12 @@ public class UserController {
|
||||
*/
|
||||
@Autowired
|
||||
private UserServiceImpl userServiceImpl;
|
||||
|
||||
/**
|
||||
* ApplicationContext依赖注入,用于获取其他Bean。
|
||||
*/
|
||||
@Autowired
|
||||
private ApplicationContext applicationContext;
|
||||
|
||||
/**
|
||||
* 获取当前用户状态接口。
|
||||
@@ -172,33 +182,82 @@ public class UserController {
|
||||
/**
|
||||
* 用户签到接口。
|
||||
* @param request HTTP请求对象,用于提取认证令牌
|
||||
* @param initialLocation 初始位置信息
|
||||
* @return 更新后的用户信息
|
||||
*/
|
||||
@PostMapping("/signin")
|
||||
public ResponseEntity<?> signIn(HttpServletRequest request) {
|
||||
public ResponseEntity<?> signIn(HttpServletRequest request, @RequestBody LocationWebSocketHandler.LocationData initialLocation) {
|
||||
String token = extractToken(request);
|
||||
if (token == null) {
|
||||
return ResponseEntity.badRequest().body("Authorization token is missing");
|
||||
return ResponseEntity.badRequest().body(new SignInResponse(false, "Authorization token is missing"));
|
||||
}
|
||||
|
||||
// 检查位置信息是否为空
|
||||
if (initialLocation == null) {
|
||||
return ResponseEntity.badRequest().body(new SignInResponse(false, "Initial location information is required"));
|
||||
}
|
||||
|
||||
// 检查位置信息的必要字段是否为空
|
||||
if (initialLocation.getLatitude() == null || initialLocation.getLongitude() == null) {
|
||||
return ResponseEntity.badRequest().body(new SignInResponse(false, "Latitude and longitude are required in location information"));
|
||||
}
|
||||
|
||||
try {
|
||||
User user = userService.getUserInfo(token);
|
||||
User updatedUser = userService.signIn(user.getId());
|
||||
UserInfoResponse response = toUserInfoResponse(updatedUser);
|
||||
return ResponseEntity.ok(response);
|
||||
UserInfoResponse userInfoResponse = toUserInfoResponse(updatedUser);
|
||||
|
||||
// 通知WebSocket处理器用户已签到并自动订阅
|
||||
try {
|
||||
LocationWebSocketHandler handler = applicationContext.getBean(LocationWebSocketHandler.class);
|
||||
handler.userSignedIn(user.getId(), initialLocation);
|
||||
} catch (Exception e) {
|
||||
System.err.println("通知WebSocket签到状态时出错: " + e.getMessage());
|
||||
}
|
||||
|
||||
return ResponseEntity.ok(new SignInResponse(true, userInfoResponse));
|
||||
} catch (Exception e) {
|
||||
return ResponseEntity.badRequest().body("Invalid token: " + e.getMessage());
|
||||
return ResponseEntity.badRequest().body(new SignInResponse(false, "Invalid token: " + e.getMessage()));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 注册为骑手接口。
|
||||
* 用户签退接口。
|
||||
* @param request HTTP请求对象,用于提取认证令牌
|
||||
* @return 操作结果
|
||||
*/
|
||||
@PostMapping("/signout")
|
||||
public ResponseEntity<?> signOut(HttpServletRequest request) {
|
||||
String token = extractToken(request);
|
||||
if (token == null) {
|
||||
return ResponseEntity.badRequest().body(new SignOutResponse(false, "Authorization token is missing"));
|
||||
}
|
||||
|
||||
try {
|
||||
User user = userService.getUserInfo(token);
|
||||
|
||||
// 通知WebSocket处理器用户已签退并自动取消订阅
|
||||
try {
|
||||
LocationWebSocketHandler handler = applicationContext.getBean(LocationWebSocketHandler.class);
|
||||
handler.userSignedOut(user.getId());
|
||||
} catch (Exception e) {
|
||||
System.err.println("通知WebSocket签退状态时出错: " + e.getMessage());
|
||||
}
|
||||
|
||||
return ResponseEntity.ok(new SignOutResponse(true, "签退成功"));
|
||||
} catch (Exception e) {
|
||||
return ResponseEntity.badRequest().body(new SignOutResponse(false, "Invalid token: " + e.getMessage()));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 注册为正式员工接口。
|
||||
* @param request HTTP请求对象,用于提取认证令牌
|
||||
* @param registerRequest 注册请求对象,包含姓名和手机号
|
||||
* @return 更新后的用户信息
|
||||
*/
|
||||
@PostMapping("/register")
|
||||
public ResponseEntity<UserInfoResponse> registerAsDeliveryPerson(
|
||||
public ResponseEntity<UserInfoResponse> registerAsEmployee(
|
||||
HttpServletRequest request,
|
||||
@RequestBody RegisterRequest registerRequest) {
|
||||
try {
|
||||
@@ -213,7 +272,7 @@ public class UserController {
|
||||
User user = userService.getUserInfo(token);
|
||||
System.out.println("获取到用户信息: " + user);
|
||||
|
||||
User updatedUser = userService.registerAsDeliveryPerson(
|
||||
User updatedUser = userService.registerAsEmployee(
|
||||
user.getId(),
|
||||
registerRequest.getName(),
|
||||
registerRequest.getPhone());
|
||||
@@ -221,12 +280,12 @@ public class UserController {
|
||||
return ResponseEntity.ok(response);
|
||||
} catch (IllegalArgumentException e) {
|
||||
// 记录错误日志
|
||||
System.err.println("注册配送员时发生错误: " + e.getMessage());
|
||||
System.err.println("注册员工时发生错误: " + e.getMessage());
|
||||
e.printStackTrace();
|
||||
return ResponseEntity.badRequest().build();
|
||||
} catch (Exception e) {
|
||||
// 记录未预期的错误
|
||||
System.err.println("注册配送员时发生未预期错误: " + e.getMessage());
|
||||
System.err.println("注册员工时发生未预期错误: " + e.getMessage());
|
||||
e.printStackTrace();
|
||||
return ResponseEntity.status(500).build();
|
||||
}
|
||||
|
15
src/main/java/com/light/delivery/dto/EmployeeDto.java
Normal file
15
src/main/java/com/light/delivery/dto/EmployeeDto.java
Normal file
@@ -0,0 +1,15 @@
|
||||
package com.light.delivery.dto;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 员工信息DTO,用于员工信息的传输
|
||||
*/
|
||||
@Data
|
||||
public class EmployeeDto {
|
||||
private Long id;
|
||||
private String name;
|
||||
private String phone;
|
||||
private String role;
|
||||
private String openid;
|
||||
}
|
42
src/main/java/com/light/delivery/dto/SignInResponse.java
Normal file
42
src/main/java/com/light/delivery/dto/SignInResponse.java
Normal file
@@ -0,0 +1,42 @@
|
||||
package com.light.delivery.dto;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 签到响应 DTO,用于统一签到接口的响应格式
|
||||
*/
|
||||
@Data
|
||||
public class SignInResponse {
|
||||
/**
|
||||
* 操作是否成功
|
||||
*/
|
||||
private boolean success;
|
||||
|
||||
/**
|
||||
* 响应消息(可选)
|
||||
*/
|
||||
private String message;
|
||||
|
||||
/**
|
||||
* 用户信息(签到成功时返回)
|
||||
*/
|
||||
private UserInfoResponse userInfo;
|
||||
|
||||
public SignInResponse() {}
|
||||
|
||||
public SignInResponse(boolean success, String message) {
|
||||
this.success = success;
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
public SignInResponse(boolean success, UserInfoResponse userInfo) {
|
||||
this.success = success;
|
||||
this.userInfo = userInfo;
|
||||
}
|
||||
|
||||
public SignInResponse(boolean success, String message, UserInfoResponse userInfo) {
|
||||
this.success = success;
|
||||
this.message = message;
|
||||
this.userInfo = userInfo;
|
||||
}
|
||||
}
|
26
src/main/java/com/light/delivery/dto/SignOutResponse.java
Normal file
26
src/main/java/com/light/delivery/dto/SignOutResponse.java
Normal file
@@ -0,0 +1,26 @@
|
||||
package com.light.delivery.dto;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 签退响应 DTO,用于统一签退接口的响应格式
|
||||
*/
|
||||
@Data
|
||||
public class SignOutResponse {
|
||||
/**
|
||||
* 操作是否成功
|
||||
*/
|
||||
private boolean success;
|
||||
|
||||
/**
|
||||
* 响应消息(可选)
|
||||
*/
|
||||
private String message;
|
||||
|
||||
public SignOutResponse() {}
|
||||
|
||||
public SignOutResponse(boolean success, String message) {
|
||||
this.success = success;
|
||||
this.message = message;
|
||||
}
|
||||
}
|
@@ -0,0 +1,49 @@
|
||||
package com.light.delivery.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 java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 全局异常处理器,用于统一处理系统中的异常
|
||||
*/
|
||||
@ControllerAdvice
|
||||
public class GlobalExceptionHandler {
|
||||
|
||||
/**
|
||||
* 处理权限不足异常
|
||||
*/
|
||||
@ExceptionHandler(SecurityException.class)
|
||||
public ResponseEntity<Map<String, String>> handleSecurityException(SecurityException e) {
|
||||
Map<String, String> errorResponse = new HashMap<>();
|
||||
errorResponse.put("error", "权限不足");
|
||||
errorResponse.put("message", e.getMessage());
|
||||
return ResponseEntity.status(HttpStatus.FORBIDDEN).body(errorResponse);
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理非法参数异常
|
||||
*/
|
||||
@ExceptionHandler(IllegalArgumentException.class)
|
||||
public ResponseEntity<Map<String, String>> handleIllegalArgumentException(IllegalArgumentException e) {
|
||||
Map<String, String> errorResponse = new HashMap<>();
|
||||
errorResponse.put("error", "参数错误");
|
||||
errorResponse.put("message", e.getMessage());
|
||||
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(errorResponse);
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理通用异常
|
||||
*/
|
||||
@ExceptionHandler(Exception.class)
|
||||
public ResponseEntity<Map<String, String>> handleGenericException(Exception e) {
|
||||
Map<String, String> errorResponse = new HashMap<>();
|
||||
errorResponse.put("error", "系统错误");
|
||||
errorResponse.put("message", e.getMessage());
|
||||
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(errorResponse);
|
||||
}
|
||||
}
|
@@ -20,13 +20,6 @@ public interface DeliveryPersonService {
|
||||
* @return 配送员对象
|
||||
*/
|
||||
DeliveryPerson getDeliveryPersonById(Long id);
|
||||
/**
|
||||
* 更新配送员当前位置。
|
||||
* @param id 配送员ID
|
||||
* @param longitude 经度
|
||||
* @param latitude 纬度
|
||||
*/
|
||||
void updateLocation(Long id, Double longitude, Double latitude);
|
||||
/**
|
||||
* 获取指定配送员的所有订单。
|
||||
* @param id 配送员ID
|
||||
|
@@ -0,0 +1,52 @@
|
||||
package com.light.delivery.service;
|
||||
|
||||
import com.light.delivery.dto.EmployeeDto;
|
||||
import com.light.delivery.model.Employee;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 员工服务接口,定义员工相关的业务操作。
|
||||
*/
|
||||
public interface EmployeeService {
|
||||
/**
|
||||
* 获取所有员工信息
|
||||
* @return 员工列表
|
||||
*/
|
||||
List<Employee> getAllEmployees();
|
||||
|
||||
/**
|
||||
* 保存员工信息
|
||||
* @param employee 员工信息
|
||||
* @return 保存后的员工信息
|
||||
*/
|
||||
Employee saveEmployee(Employee employee);
|
||||
|
||||
/**
|
||||
* 更新员工信息
|
||||
* @param id 员工ID
|
||||
* @param employee 员工信息
|
||||
* @return 更新后的员工信息
|
||||
*/
|
||||
Employee updateEmployee(Long id, Employee employee);
|
||||
|
||||
/**
|
||||
* 删除员工
|
||||
* @param id 员工ID
|
||||
*/
|
||||
void deleteEmployee(Long id);
|
||||
|
||||
/**
|
||||
* 将Employee实体转换为EmployeeDto
|
||||
* @param employee 员工实体
|
||||
* @return 员工DTO
|
||||
*/
|
||||
EmployeeDto toDto(Employee employee);
|
||||
|
||||
/**
|
||||
* 将EmployeeDto转换为Employee实体
|
||||
* @param dto 员工DTO
|
||||
* @return 员工实体
|
||||
*/
|
||||
Employee toEntity(EmployeeDto dto);
|
||||
}
|
@@ -5,14 +5,6 @@ package com.light.delivery.service;
|
||||
*/
|
||||
public interface LocationSyncService {
|
||||
|
||||
/**
|
||||
* 处理配送员位置更新
|
||||
* @param deliveryPersonId 配送员ID
|
||||
* @param longitude 经度
|
||||
* @param latitude 纬度
|
||||
*/
|
||||
void handleLocationUpdate(Long deliveryPersonId, Double longitude, Double latitude);
|
||||
|
||||
/**
|
||||
* 订阅位置更新
|
||||
* @param sessionId 会话ID
|
||||
|
File diff suppressed because it is too large
Load Diff
@@ -23,11 +23,14 @@ public interface UserService {
|
||||
|
||||
/**
|
||||
* 微信小程序登录,接收code,返回登录响应。
|
||||
* @param code 微信登录凭证
|
||||
* @return 登录响应
|
||||
*/
|
||||
LoginResponse wxLogin(String code);
|
||||
|
||||
/**
|
||||
* 获取当前已登录用户(从上下文或模拟实现中)
|
||||
* @return 当前用户
|
||||
*/
|
||||
User getCurrentUser();
|
||||
|
||||
@@ -39,19 +42,25 @@ public interface UserService {
|
||||
*/
|
||||
User signIn(Long userId);
|
||||
|
||||
/**
|
||||
* 注册为骑手
|
||||
* @param userId 用户ID
|
||||
* @param name 姓名
|
||||
* @param phone 手机号
|
||||
* @return 注册结果
|
||||
*/
|
||||
User registerAsDeliveryPerson(Long userId, String name, String phone);
|
||||
|
||||
/**
|
||||
* 检查用户是否已签到
|
||||
* @param userId 用户ID
|
||||
* @return true表示已签到,false表示未签到
|
||||
*/
|
||||
boolean isUserSignedIn(Long userId);
|
||||
|
||||
/**
|
||||
* 用户签退功能
|
||||
* @param userId 用户ID
|
||||
*/
|
||||
void signOut(Long userId);
|
||||
|
||||
/**
|
||||
* 注册为正式员工
|
||||
* @param userId 用户ID
|
||||
* @param name 姓名
|
||||
* @param phone 手机号
|
||||
* @return 注册结果
|
||||
*/
|
||||
User registerAsEmployee(Long userId, String name, String phone);
|
||||
}
|
@@ -34,12 +34,6 @@ public class DeliveryPersonServiceImpl implements DeliveryPersonService {
|
||||
return person.orElse(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateLocation(Long id, Double longitude, Double latitude) {
|
||||
// 使用 LocationSyncService 更新位置信息到服务器缓存,而不是直接更新数据库
|
||||
locationSyncService.handleLocationUpdate(id, longitude, latitude);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Order> getCurrentOrders(Long id) {
|
||||
return orderRepository.findByDeliveryPersonId(id);
|
||||
|
@@ -0,0 +1,80 @@
|
||||
package com.light.delivery.service.impl;
|
||||
|
||||
import com.light.delivery.dto.EmployeeDto;
|
||||
import com.light.delivery.model.Employee;
|
||||
import com.light.delivery.repository.EmployeeRepository;
|
||||
import com.light.delivery.service.EmployeeService;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 员工服务实现类,处理员工相关的业务逻辑。
|
||||
*/
|
||||
@Service
|
||||
public class EmployeeServiceImpl implements EmployeeService {
|
||||
|
||||
@Autowired
|
||||
private EmployeeRepository employeeRepository;
|
||||
|
||||
@Override
|
||||
public List<Employee> getAllEmployees() {
|
||||
return employeeRepository.findAll();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Employee saveEmployee(Employee employee) {
|
||||
return employeeRepository.save(employee);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Employee updateEmployee(Long id, Employee employee) {
|
||||
Optional<Employee> existingEmployee = employeeRepository.findById(id);
|
||||
if (existingEmployee.isPresent()) {
|
||||
Employee emp = existingEmployee.get();
|
||||
emp.setName(employee.getName());
|
||||
emp.setPhone(employee.getPhone());
|
||||
emp.setRole(employee.getRole());
|
||||
// 注意:不更新openid字段,该字段由用户注册时自动填充
|
||||
return employeeRepository.save(emp);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteEmployee(Long id) {
|
||||
employeeRepository.deleteById(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* 将Employee实体转换为EmployeeDto
|
||||
* @param employee 员工实体
|
||||
* @return 员工DTO
|
||||
*/
|
||||
public EmployeeDto toDto(Employee employee) {
|
||||
if (employee == null) {
|
||||
return null;
|
||||
}
|
||||
EmployeeDto dto = new EmployeeDto();
|
||||
BeanUtils.copyProperties(employee, dto);
|
||||
return dto;
|
||||
}
|
||||
|
||||
/**
|
||||
* 将EmployeeDto转换为Employee实体
|
||||
* @param dto 员工DTO
|
||||
* @return 员工实体
|
||||
*/
|
||||
public Employee toEntity(EmployeeDto dto) {
|
||||
if (dto == null) {
|
||||
return null;
|
||||
}
|
||||
Employee employee = new Employee();
|
||||
BeanUtils.copyProperties(dto, employee);
|
||||
return employee;
|
||||
}
|
||||
}
|
@@ -34,19 +34,7 @@ public class LocationSyncServiceImpl implements LocationSyncService {
|
||||
// 位置过期时间(分钟)
|
||||
private static final int LOCATION_EXPIRE_MINUTES = 5;
|
||||
|
||||
@Override
|
||||
public void handleLocationUpdate(Long deliveryPersonId, Double longitude, Double latitude) {
|
||||
try {
|
||||
// 更新内存缓存中的配送员位置,而不是数据库
|
||||
deliveryPersonLongitudeMap.put(deliveryPersonId, longitude);
|
||||
deliveryPersonLatitudeMap.put(deliveryPersonId, latitude);
|
||||
|
||||
// 更新最后更新时间
|
||||
lastUpdateTimes.put(deliveryPersonId, LocalDateTime.now());
|
||||
} catch (Exception e) {
|
||||
System.err.println("更新配送员位置时出错: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void subscribe(String sessionId, Long deliveryPersonId) {
|
||||
|
@@ -15,6 +15,7 @@ import com.light.delivery.service.UserService;
|
||||
import com.light.delivery.util.JwtUtil;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
|
||||
@@ -43,16 +44,16 @@ public class UserServiceImpl implements UserService {
|
||||
private EmployeeRepository employeeRepository;
|
||||
|
||||
/**
|
||||
* JWT工具类,用于生成和解析JWT令牌
|
||||
* Jwt工具类,用于生成和解析JWT令牌
|
||||
*/
|
||||
@Autowired
|
||||
private JwtUtil jwtUtil;
|
||||
|
||||
/**
|
||||
* WebSocket处理器,用于管理WebSocket连接
|
||||
* Spring应用上下文,用于获取其他Bean
|
||||
*/
|
||||
@Autowired
|
||||
private LocationWebSocketHandler locationWebSocketHandler;
|
||||
private ApplicationContext applicationContext;
|
||||
|
||||
/**
|
||||
* 微信小程序appId
|
||||
@@ -103,6 +104,25 @@ public class UserServiceImpl implements UserService {
|
||||
throw new IllegalArgumentException("Invalid token: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据用户ID获取用户信息。
|
||||
* @param userId 用户ID
|
||||
* @return 用户实体对象
|
||||
* @throws IllegalArgumentException 当用户不存在时抛出异常
|
||||
*/
|
||||
public User getUserInfoById(Long userId) {
|
||||
if (userId == null) {
|
||||
throw new IllegalArgumentException("User ID is null");
|
||||
}
|
||||
|
||||
Optional<User> userOptional = userRepository.findById(userId);
|
||||
if (!userOptional.isPresent()) {
|
||||
throw new IllegalArgumentException("用户不存在");
|
||||
}
|
||||
|
||||
return userOptional.get();
|
||||
}
|
||||
|
||||
/**
|
||||
* 用户登出逻辑。
|
||||
@@ -127,14 +147,18 @@ public class UserServiceImpl implements UserService {
|
||||
return;
|
||||
}
|
||||
|
||||
// 如果用户是配送员,通知WebSocket处理器清理连接
|
||||
// 注意:这里需要根据实际业务逻辑获取配送员ID
|
||||
// 可能需要通过其他方式关联用户ID和配送员ID
|
||||
// 这里假设用户ID和配送员ID相同(根据项目实际情况调整)
|
||||
// locationWebSocketHandler.removeUserConnection(user.getId());
|
||||
// 通知WebSocket处理器清理连接
|
||||
try {
|
||||
LocationWebSocketHandler handler = applicationContext.getBean(LocationWebSocketHandler.class);
|
||||
// 清理用户状态
|
||||
handler.cleanupUserConnection(user.getId());
|
||||
} catch (Exception e) {
|
||||
// 记录日志但不中断登出流程
|
||||
System.err.println("清理WebSocket连接时出错: " + e.getMessage());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
// 记录日志但不中断登出流程
|
||||
System.err.println("清理WebSocket连接时出错: " + e.getMessage());
|
||||
System.err.println("登出时出错: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -227,6 +251,12 @@ public class UserServiceImpl implements UserService {
|
||||
|
||||
return user;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void signOut(Long userId) {
|
||||
// 签退操作在REST控制器中通过WebSocket处理器完成
|
||||
// 这里可以添加其他签退逻辑(如记录签退时间等)
|
||||
}
|
||||
|
||||
/**
|
||||
* 用户注册成为配送员。
|
||||
@@ -239,8 +269,8 @@ public class UserServiceImpl implements UserService {
|
||||
* @throws IllegalArgumentException 当用户不存在、手机号未找到或姓名不匹配时抛出异常
|
||||
*/
|
||||
@Override
|
||||
public User registerAsDeliveryPerson(Long userId, String name, String phone) {
|
||||
System.out.println("尝试注册配送员,用户ID: " + userId);
|
||||
public User registerAsEmployee(Long userId, String name, String phone) {
|
||||
System.out.println("尝试注册员工,用户ID: " + userId);
|
||||
|
||||
Optional<User> userOptional = userRepository.findById(userId);
|
||||
if (!userOptional.isPresent()) {
|
||||
@@ -330,22 +360,18 @@ public class UserServiceImpl implements UserService {
|
||||
*/
|
||||
@Override
|
||||
public boolean isUserSignedIn(Long userId) {
|
||||
// 只有配送员角色才有签到状态
|
||||
Optional<User> userOptional = userRepository.findById(userId);
|
||||
if (!userOptional.isPresent()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
User user = userOptional.get();
|
||||
UserRole userRole = getUserRole(user);
|
||||
|
||||
if (userRole != UserRole.DELIVERY_PERSON) {
|
||||
// 非配送员角色没有签到状态概念
|
||||
return false;
|
||||
}
|
||||
|
||||
// 检查WebSocket中的签到状态
|
||||
return locationWebSocketHandler.isDeliveryPersonSignedIn(userId);
|
||||
// 注意:由于循环依赖问题,这里不能直接注入LocationWebSocketHandler
|
||||
// 在实际应用中,可能需要通过其他方式获取签到状态
|
||||
// 现在通过静态方法或上下文获取LocationWebSocketHandler实例
|
||||
try {
|
||||
// 使用Spring上下文获取LocationWebSocketHandler实例
|
||||
LocationWebSocketHandler handler = applicationContext.getBean(LocationWebSocketHandler.class);
|
||||
return handler.isUserSignedIn(userId);
|
||||
} catch (Exception e) {
|
||||
System.err.println("获取WebSocket签到状态时出错: " + e.getMessage());
|
||||
return false; // 默认返回false
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -1,8 +1,10 @@
|
||||
spring.application.name=Light
|
||||
server.port=443
|
||||
|
||||
# 默认禁用SSL,通过profile启用
|
||||
server.ssl.enabled=false
|
||||
server.ssl.enabled=true
|
||||
server.ssl.key-store-type=JKS
|
||||
server.ssl.key-store=/etc/ssl/certs/www.doubleyin.cn.jks
|
||||
server.ssl.key-store-password=${KEY_STORE_PASSWORD}
|
||||
|
||||
spring.datasource.url=jdbc:mysql://115.190.121.151:3306/light_delivery?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true
|
||||
spring.datasource.username=double
|
||||
|
Reference in New Issue
Block a user