地址路径修改
This commit is contained in:
883
dist/services/apiService.js
vendored
Normal file
883
dist/services/apiService.js
vendored
Normal file
@@ -0,0 +1,883 @@
|
||||
"use strict";
|
||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const roleUtils_1 = require("../utils/roleUtils");
|
||||
const locationTrackingService_1 = __importDefault(require("./locationTrackingService"));
|
||||
/**
|
||||
* API服务基类
|
||||
* 提供与后端API交互的核心功能
|
||||
*/
|
||||
// API基础URL配置
|
||||
const IS_LOCAL_DEV = true; // true: 本地开发环境, false: 生产环境
|
||||
const API_BASE_URL = IS_LOCAL_DEV ? 'http://localhost:8080' : 'https://www.doubleyin.cn';
|
||||
console.log(`当前API地址: ${API_BASE_URL} (${IS_LOCAL_DEV ? '本地开发环境' : '生产环境'})`);
|
||||
/**
|
||||
* 是否启用模拟模式
|
||||
* 该配置控制是否使用模拟数据进行开发测试
|
||||
*/
|
||||
/**
|
||||
* API服务类
|
||||
* 封装了所有与后端API交互的方法,并按照功能模块进行组织
|
||||
*/
|
||||
class ApiService {
|
||||
/**
|
||||
* 构造函数
|
||||
*/
|
||||
constructor() {
|
||||
this.locationWebSocket = null;
|
||||
}
|
||||
/**
|
||||
* 基础请求方法
|
||||
* @param endpoint API端点路径
|
||||
* @param options 请求配置选项
|
||||
* @returns Promise<T> 返回泛型类型的响应数据
|
||||
*/
|
||||
async request(endpoint, options = {}) {
|
||||
const requestUrl = `${API_BASE_URL}${endpoint}`;
|
||||
// 获取全局token
|
||||
const app = getApp();
|
||||
const token = app.globalData.token;
|
||||
// 构建请求头,自动添加Authorization头(如果存在token)
|
||||
const headers = {
|
||||
'Content-Type': 'application/json',
|
||||
...options.headers,
|
||||
};
|
||||
if (token) {
|
||||
headers['Authorization'] = `Bearer ${token}`;
|
||||
}
|
||||
const requestOptions = {
|
||||
method: options.method || 'GET',
|
||||
data: options.data,
|
||||
header: headers,
|
||||
};
|
||||
// 打印请求信息
|
||||
console.log('\n========== API Request ==========');
|
||||
console.log(`Method: ${requestOptions.method}`);
|
||||
console.log(`URL: ${requestUrl}`);
|
||||
console.log(`Headers:`, requestOptions.header);
|
||||
console.log(`Data:`, requestOptions.data);
|
||||
console.log('================================');
|
||||
return new Promise((resolve, reject) => {
|
||||
wx.request({
|
||||
url: requestUrl,
|
||||
method: requestOptions.method,
|
||||
data: requestOptions.data,
|
||||
header: requestOptions.header,
|
||||
success: (res) => {
|
||||
// 打印响应信息
|
||||
console.log('\n========== API Response ==========');
|
||||
console.log(`URL: ${requestUrl}`);
|
||||
console.log(`Status: ${res.statusCode}`);
|
||||
console.log(`Response Data:`, res.data);
|
||||
console.log('==================================');
|
||||
if (res.statusCode >= 200 && res.statusCode < 300) {
|
||||
resolve(res.data);
|
||||
}
|
||||
else {
|
||||
// 优先使用服务器返回的具体错误信息,如果没有则使用默认错误信息
|
||||
const errorMessage = res.data || res.errMsg || '请求失败';
|
||||
console.error(`API Error: HTTP ${res.statusCode}: ${errorMessage}`);
|
||||
reject(new Error(`HTTP ${res.statusCode}: ${errorMessage}`));
|
||||
}
|
||||
},
|
||||
fail: (err) => {
|
||||
console.error('\n========== API Request Failed ==========');
|
||||
console.error(`URL: ${requestUrl}`);
|
||||
console.error(`Error: ${err.errMsg}`);
|
||||
console.error('=======================================');
|
||||
reject(new Error(`Request failed: ${err.errMsg}`));
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
// ==================== 用户模块 ====================
|
||||
// ====== 认证相关 ======
|
||||
/**
|
||||
* 微信登录接口
|
||||
* @param code 微信登录授权码
|
||||
* @returns 用户信息及认证令牌
|
||||
*/
|
||||
async ServerLogin(code) {
|
||||
console.log('API wxLogin调用,参数code:', code);
|
||||
return await this.request('/user/wxlogin', {
|
||||
method: 'POST',
|
||||
data: { code: code },
|
||||
});
|
||||
}
|
||||
/**
|
||||
* 签到接口
|
||||
* @param userId 用户ID
|
||||
* @param initialLocation 初始位置数据(必须)
|
||||
* @returns 签到结果和员工信息
|
||||
*/
|
||||
async userSignIn(userId, initialLocation) {
|
||||
console.log('API userSignIn调用,参数userId:', userId, 'initialLocation:', initialLocation);
|
||||
// 构建请求数据,必须包含位置数据
|
||||
const requestData = {
|
||||
latitude: initialLocation.latitude,
|
||||
longitude: initialLocation.longitude,
|
||||
timestamp: initialLocation.timestamp
|
||||
};
|
||||
// 服务器现在返回统一的DTO格式,直接使用
|
||||
const response = await this.request('/user/signin', {
|
||||
method: 'POST',
|
||||
data: requestData,
|
||||
});
|
||||
// 服务器返回格式:{ success: boolean, userInfo: UserInfoResponse }
|
||||
return {
|
||||
success: response.success,
|
||||
employeeInfo: {
|
||||
id: response.userInfo.id,
|
||||
name: response.userInfo.name,
|
||||
phone: response.userInfo.phone,
|
||||
role: response.userInfo.role || roleUtils_1.Role.DELIVERY_PERSON
|
||||
},
|
||||
message: response.message
|
||||
};
|
||||
}
|
||||
/**
|
||||
* 绑定接口
|
||||
* @param userInfo 绑定用户信息
|
||||
* @returns 绑定结果和员工信息
|
||||
*/
|
||||
async userRegister(userInfo) {
|
||||
console.log('API userRegister调用,参数userInfo:', userInfo);
|
||||
// 服务器返回直接的用户信息格式:{id, name, phone, role, openid}
|
||||
const response = await this.request('/user/register', {
|
||||
method: 'POST',
|
||||
data: userInfo,
|
||||
});
|
||||
// 检查响应格式,兼容不同的返回格式
|
||||
if (response.id) {
|
||||
// 直接返回用户信息格式
|
||||
return {
|
||||
success: true,
|
||||
employeeInfo: {
|
||||
id: response.id,
|
||||
name: response.name || userInfo.name,
|
||||
phone: response.phone || userInfo.phone,
|
||||
role: response.role || roleUtils_1.Role.DELIVERY_PERSON
|
||||
},
|
||||
message: '绑定成功'
|
||||
};
|
||||
}
|
||||
else if (response.userInfo && response.userInfo.id) {
|
||||
// 包装格式:{success, userInfo, message}
|
||||
return {
|
||||
success: response.success !== false,
|
||||
employeeInfo: {
|
||||
id: response.userInfo.id,
|
||||
name: response.userInfo.name || userInfo.name,
|
||||
phone: response.userInfo.phone || userInfo.phone,
|
||||
role: response.userInfo.role || roleUtils_1.Role.DELIVERY_PERSON
|
||||
},
|
||||
message: response.message
|
||||
};
|
||||
}
|
||||
else {
|
||||
// 未知格式,返回错误
|
||||
console.error('未知的绑定响应格式:', response);
|
||||
return {
|
||||
success: false,
|
||||
employeeInfo: {
|
||||
id: 0,
|
||||
name: userInfo.name,
|
||||
phone: userInfo.phone,
|
||||
role: roleUtils_1.Role.DELIVERY_PERSON
|
||||
},
|
||||
message: '绑定响应格式错误'
|
||||
};
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 用户登出
|
||||
*/
|
||||
async logout() {
|
||||
return await this.request('/user/logout', { method: 'POST' });
|
||||
}
|
||||
/**
|
||||
* 解绑微信接口
|
||||
* 清除当前用户的openid绑定,允许重新注册其他账号
|
||||
* @returns 解绑结果
|
||||
*/
|
||||
async unbindWechat() {
|
||||
console.log('API unbindWechat调用');
|
||||
const response = await this.request('/user/unbind', {
|
||||
method: 'POST',
|
||||
data: {}
|
||||
});
|
||||
return {
|
||||
success: response.success,
|
||||
message: response.message
|
||||
};
|
||||
}
|
||||
/**
|
||||
* 签退接口
|
||||
* @param userId 用户ID
|
||||
* @returns 签退结果
|
||||
*/
|
||||
async userSignOut(userId) {
|
||||
console.log('API userSignOut调用,参数userId:', userId);
|
||||
// 服务器现在返回统一的DTO格式:{ success: boolean, message: string }
|
||||
const response = await this.request('/user/signout', {
|
||||
method: 'POST',
|
||||
data: { userId },
|
||||
});
|
||||
return {
|
||||
success: response.success,
|
||||
message: response.message
|
||||
};
|
||||
}
|
||||
/**
|
||||
* 获取用户签到状态
|
||||
* @returns 用户状态信息
|
||||
*/
|
||||
async getUserStatus() {
|
||||
return await this.request('/user/status', { method: 'GET' });
|
||||
}
|
||||
// ====== 信息相关 ======
|
||||
/**
|
||||
* 获取当前用户信息
|
||||
* @returns 用户详细信息
|
||||
*/
|
||||
async getUserInfo() {
|
||||
return await this.request('/user/info');
|
||||
}
|
||||
/**
|
||||
* 更新用户信息
|
||||
* @param userInfo 待更新的用户信息
|
||||
* @returns 更新后的用户信息
|
||||
*/
|
||||
async updateUserInfo(userInfo) {
|
||||
return await this.request('/user/update', {
|
||||
method: 'PUT',
|
||||
data: userInfo,
|
||||
});
|
||||
}
|
||||
/**
|
||||
* 获取用户权限列表
|
||||
* @returns 权限字符串数组
|
||||
*/
|
||||
async getUserPermissions() {
|
||||
return await this.request('/user/permissions');
|
||||
}
|
||||
/**
|
||||
* 检查用户是否在线
|
||||
* @returns 在线状态
|
||||
*/
|
||||
async checkUserOnline() {
|
||||
return await this.request('/user/online');
|
||||
}
|
||||
/**
|
||||
* 获取用户会话信息
|
||||
* @returns 会话详细信息
|
||||
*/
|
||||
async getSessionInfo() {
|
||||
return await this.request('/user/session');
|
||||
}
|
||||
/**
|
||||
* 刷新用户令牌
|
||||
* @param oldToken 旧令牌
|
||||
* @returns 新令牌及过期时间
|
||||
*/
|
||||
async refreshToken(oldToken) {
|
||||
return await this.request('/user/refresh-token', {
|
||||
method: 'POST',
|
||||
data: { token: oldToken },
|
||||
});
|
||||
}
|
||||
/**
|
||||
* 验证用户权限
|
||||
* @param permission 待验证的权限
|
||||
* @returns 是否拥有该权限
|
||||
*/
|
||||
async verifyPermission(permission) {
|
||||
return await this.request(`/user/verify-permission?permission=${permission}`);
|
||||
}
|
||||
// ====== 管理相关 ======
|
||||
/**
|
||||
* 搜索用户
|
||||
* @param query 搜索关键词
|
||||
* @param page 页码
|
||||
* @param pageSize 每页数量
|
||||
* @returns 用户列表及分页信息
|
||||
*/
|
||||
async searchUsers(query, page = 1, pageSize = 20) {
|
||||
return await this.request(`/user/search?query=${query}&page=${page}&pageSize=${pageSize}`);
|
||||
}
|
||||
/**
|
||||
* 批量操作用户状态
|
||||
* @param userIds 用户ID列表
|
||||
* @param status 目标状态
|
||||
*/
|
||||
async batchUpdateUserStatus(userIds, status) {
|
||||
return await this.request('/user/batch-update-status', {
|
||||
method: 'POST',
|
||||
data: { userIds, status },
|
||||
});
|
||||
}
|
||||
// ====== 员工管理接口 ======
|
||||
/**
|
||||
* 获取所有员工列表
|
||||
* @returns 员工信息数组
|
||||
*/
|
||||
async getEmployees() {
|
||||
return await this.request('/employees');
|
||||
}
|
||||
/**
|
||||
* 添加新员工
|
||||
* @param employeeInfo 员工信息
|
||||
* @returns 添加结果
|
||||
*/
|
||||
async addEmployee(employeeInfo) {
|
||||
return await this.request('/employees', {
|
||||
method: 'POST',
|
||||
data: employeeInfo,
|
||||
});
|
||||
}
|
||||
/**
|
||||
* 删除员工
|
||||
* @param employeeId 员工ID
|
||||
* @returns 删除结果
|
||||
*/
|
||||
async deleteEmployee(employeeId) {
|
||||
return await this.request(`/employees/${employeeId}`, {
|
||||
method: 'DELETE',
|
||||
});
|
||||
}
|
||||
/**
|
||||
* 更新员工信息
|
||||
* @param employeeId 员工ID
|
||||
* @param employeeInfo 员工信息
|
||||
* @returns 更新结果
|
||||
*/
|
||||
async updateEmployee(employeeId, employeeInfo) {
|
||||
return await this.request(`/employees/${employeeId}`, {
|
||||
method: 'PUT',
|
||||
data: employeeInfo,
|
||||
});
|
||||
}
|
||||
/**
|
||||
* 上传员工头像
|
||||
* @param employeeId 员工ID
|
||||
* @param filePath 头像文件路径
|
||||
* @returns 上传结果
|
||||
*/
|
||||
async uploadEmployeeAvatar(employeeId, filePath) {
|
||||
return new Promise((resolve, reject) => {
|
||||
// 使用微信小程序的文件上传API
|
||||
wx.uploadFile({
|
||||
url: `${API_BASE_URL}/employees/${employeeId}/avatar`,
|
||||
filePath: filePath,
|
||||
name: 'avatar',
|
||||
header: {
|
||||
'Authorization': `Bearer ${getApp().globalData.token}`
|
||||
},
|
||||
success: (res) => {
|
||||
if (res.statusCode >= 200 && res.statusCode < 300) {
|
||||
try {
|
||||
const data = JSON.parse(res.data);
|
||||
resolve({
|
||||
success: true,
|
||||
avatarUrl: data.avatarUrl
|
||||
});
|
||||
}
|
||||
catch (error) {
|
||||
resolve({
|
||||
success: true,
|
||||
avatarUrl: `${API_BASE_URL}/avatars/${employeeId}.jpg`
|
||||
});
|
||||
}
|
||||
}
|
||||
else {
|
||||
reject(new Error(`上传失败: HTTP ${res.statusCode}`));
|
||||
}
|
||||
},
|
||||
fail: (err) => {
|
||||
reject(new Error(`上传失败: ${err.errMsg}`));
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
/**
|
||||
* 获取员工头像
|
||||
* @param employeeId 员工ID
|
||||
* @returns 头像URL
|
||||
*/
|
||||
async getEmployeeAvatar(employeeId) {
|
||||
try {
|
||||
// 尝试获取头像信息
|
||||
const response = await this.request(`/employees/${employeeId}/avatar`);
|
||||
return response.avatarUrl || `${API_BASE_URL}/avatars/${employeeId}.jpg`;
|
||||
}
|
||||
catch (error) {
|
||||
// 如果获取失败,返回默认头像URL
|
||||
return `${API_BASE_URL}/avatars/${employeeId}.jpg`;
|
||||
}
|
||||
}
|
||||
// ==================== 仓库相关接口 ====================
|
||||
/**
|
||||
* 获取所有仓库列表
|
||||
* @returns 仓库信息数组
|
||||
*/
|
||||
async getWarehouses() {
|
||||
return await this.request('/warehouses');
|
||||
}
|
||||
/**
|
||||
* 获取指定仓库详情
|
||||
* @param id 仓库ID
|
||||
* @returns 仓库详细信息
|
||||
*/
|
||||
async getWarehouseById(id) {
|
||||
return await this.request(`/warehouses/${id}`);
|
||||
}
|
||||
/**
|
||||
* 获取仓库相关订单
|
||||
* @param warehouseId 仓库ID
|
||||
* @returns 订单列表
|
||||
*/
|
||||
async getWarehouseOrders(warehouseId) {
|
||||
return await this.request(`/warehouses/${warehouseId}/orders`);
|
||||
}
|
||||
/**
|
||||
* 创建仓库
|
||||
* @param warehouseData 仓库数据
|
||||
* @returns 创建结果
|
||||
*/
|
||||
async createWarehouse(warehouseData) {
|
||||
return await this.request('/warehouses', {
|
||||
method: 'POST',
|
||||
data: warehouseData
|
||||
});
|
||||
}
|
||||
/**
|
||||
* 更新仓库信息
|
||||
* @param warehouseId 仓库ID
|
||||
* @param warehouseInfo 仓库信息
|
||||
* @returns 更新结果
|
||||
*/
|
||||
async updateWarehouse(warehouseId, warehouseInfo) {
|
||||
return await this.request(`/warehouses/${warehouseId}`, {
|
||||
method: 'PUT',
|
||||
data: warehouseInfo
|
||||
});
|
||||
}
|
||||
/**
|
||||
* 删除仓库
|
||||
* @param warehouseId 仓库ID
|
||||
* @returns 删除结果
|
||||
*/
|
||||
async deleteWarehouse(warehouseId) {
|
||||
return await this.request(`/warehouses/${warehouseId}`, {
|
||||
method: 'DELETE',
|
||||
});
|
||||
}
|
||||
// ==================== 货运人员接口 ====================
|
||||
/**
|
||||
* 获取所有货运人员
|
||||
* @returns 货运人员列表
|
||||
*/
|
||||
async getDeliveryPersons() {
|
||||
return await this.request('/delivery-persons');
|
||||
}
|
||||
/**
|
||||
* 获取所有配送员实时位置
|
||||
* @returns 所有配送员实时位置信息
|
||||
*/
|
||||
async getAllDeliveryPersonLocations() {
|
||||
return await this.request('/location-sync/delivery-persons/locations');
|
||||
}
|
||||
/**
|
||||
* 获取指定货运人员详情
|
||||
* @param id 货运人员ID
|
||||
* @returns 货运人员详细信息
|
||||
*/
|
||||
async getDeliveryPersonById(id) {
|
||||
return await this.request(`/delivery-persons/${id}`);
|
||||
}
|
||||
/**
|
||||
* 更新货运人员位置
|
||||
* @param id 货运人员ID
|
||||
* @param location 位置信息
|
||||
*/
|
||||
async updateDeliveryPersonLocation(id, location) {
|
||||
return await this.request(`/delivery-persons/${id}/location`, {
|
||||
method: 'PUT',
|
||||
data: location,
|
||||
});
|
||||
}
|
||||
// 地图相关接口支持
|
||||
/**
|
||||
* 批量更新货运人员位置(兼容mapService参数)
|
||||
* @param locations 位置信息数组
|
||||
*/
|
||||
async batchUpdateDeliveryPersonLocations(locations) {
|
||||
// 转换参数格式以匹配原有API
|
||||
const formattedLocations = locations.map(loc => ({
|
||||
deliveryPersonId: loc.userId,
|
||||
longitude: loc.longitude,
|
||||
latitude: loc.latitude,
|
||||
timestamp: loc.timestamp
|
||||
}));
|
||||
await this.request('/delivery-persons/locations/batch', {
|
||||
method: 'POST',
|
||||
data: { locations: formattedLocations }
|
||||
});
|
||||
}
|
||||
/**
|
||||
* 获取空闲的货运人员
|
||||
* @returns 空闲货运人员列表
|
||||
*/
|
||||
async getIdleDeliveryPersons() {
|
||||
return await this.request('/delivery-persons/idle');
|
||||
}
|
||||
/**
|
||||
* 获取忙碌的货运人员
|
||||
* @returns 忙碌货运人员列表
|
||||
*/
|
||||
async getBusyDeliveryPersons() {
|
||||
return await this.request('/delivery-persons/busy');
|
||||
}
|
||||
/**
|
||||
* 获取位置历史记录
|
||||
* @param deliveryPersonId 货运人员ID
|
||||
* @param limit 记录数量
|
||||
* @returns 位置历史记录
|
||||
*/
|
||||
async getLocationHistory(deliveryPersonId, limit = 50) {
|
||||
return await this.request(`/delivery-persons/${deliveryPersonId}/location-history?limit=${limit}`);
|
||||
}
|
||||
/**
|
||||
* 订阅实时位置更新(接收货运人员ID列表)
|
||||
* @param deliveryPersonIds 货运人员ID列表
|
||||
* @returns 订阅信息
|
||||
*/
|
||||
async subscribeToRealTimeLocations(deliveryPersonIds) {
|
||||
// 真实环境中调用API
|
||||
try {
|
||||
return await this.request('/locations/subscribe', {
|
||||
method: 'POST',
|
||||
data: { deliveryPersonIds }
|
||||
});
|
||||
}
|
||||
catch (error) {
|
||||
console.error('订阅实时位置更新失败:', error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 取消订阅实时位置更新
|
||||
* @param subscriptionId 订阅ID
|
||||
*/
|
||||
async unsubscribeFromRealTimeLocations(subscriptionId) {
|
||||
// 真实环境中调用API
|
||||
try {
|
||||
await this.request('/locations/unsubscribe', {
|
||||
method: 'POST',
|
||||
data: { subscriptionId }
|
||||
});
|
||||
}
|
||||
catch (error) {
|
||||
console.error('取消订阅实时位置更新失败:', error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
// ===== 私有属性和方法 =====
|
||||
/**
|
||||
* 初始化位置更新WebSocket连接
|
||||
*/
|
||||
async initLocationWebSocket() {
|
||||
if (this.locationWebSocket) {
|
||||
console.log('WebSocket连接已存在');
|
||||
return;
|
||||
}
|
||||
try {
|
||||
if (typeof wx !== 'undefined' && typeof wx.connectSocket === 'function') {
|
||||
console.log('初始化位置更新WebSocket连接(小程序环境)');
|
||||
// 连接到服务端的WebSocket地址,使用配置的服务器地址
|
||||
const serverUrl = API_BASE_URL.replace('http', 'ws');
|
||||
const wsUrl = `${serverUrl}/ws/location`;
|
||||
// 获取当前用户ID(从全局应用数据中获取)
|
||||
const app = getApp();
|
||||
const userInfo = app.globalData.userInfo;
|
||||
const userId = userInfo?.id;
|
||||
// 构建带用户ID参数的WebSocket URL
|
||||
const finalWsUrl = userId ? `${wsUrl}?userId=${userId}` : wsUrl;
|
||||
console.log(`WebSocket连接URL: ${finalWsUrl}`);
|
||||
this.locationWebSocket = wx.connectSocket({
|
||||
url: finalWsUrl,
|
||||
header: {
|
||||
'content-type': 'application/json'
|
||||
}
|
||||
});
|
||||
// WebSocket连接打开事件
|
||||
wx.onSocketOpen(() => {
|
||||
console.log('WebSocket连接已打开');
|
||||
});
|
||||
// WebSocket消息接收事件
|
||||
wx.onSocketMessage((res) => {
|
||||
try {
|
||||
const message = JSON.parse(typeof res.data === 'string' ? res.data : String(res.data));
|
||||
this.handleWebSocketMessage(message);
|
||||
}
|
||||
catch (error) {
|
||||
console.error('解析WebSocket消息失败:', error);
|
||||
}
|
||||
});
|
||||
// WebSocket连接关闭事件
|
||||
wx.onSocketClose((res) => {
|
||||
console.log('WebSocket连接已关闭', res);
|
||||
this.locationWebSocket = null;
|
||||
// 如果是非主动关闭,尝试重连
|
||||
if (res.code !== 1000) { // 1000表示正常关闭
|
||||
console.log('WebSocket连接异常关闭,将在3秒后尝试重连');
|
||||
setTimeout(() => {
|
||||
if (!this.locationWebSocket) {
|
||||
this.initLocationWebSocket().catch(err => {
|
||||
console.error('WebSocket重连失败:', err);
|
||||
});
|
||||
}
|
||||
}, 3000);
|
||||
}
|
||||
});
|
||||
// WebSocket错误事件
|
||||
wx.onSocketError((error) => {
|
||||
console.error('WebSocket连接错误:', error);
|
||||
this.locationWebSocket = null;
|
||||
});
|
||||
}
|
||||
else {
|
||||
console.warn('当前环境不支持WebSocket连接');
|
||||
}
|
||||
}
|
||||
catch (error) {
|
||||
console.error('初始化位置更新WebSocket连接失败:', error);
|
||||
this.locationWebSocket = null;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 检查WebSocket连接是否已建立
|
||||
*/
|
||||
isWebSocketConnected() {
|
||||
return this.locationWebSocket !== null && this.locationWebSocket !== undefined;
|
||||
}
|
||||
/**
|
||||
* 关闭位置更新WebSocket连接
|
||||
*/
|
||||
async closeLocationWebSocket() {
|
||||
if (this.locationWebSocket && typeof wx !== 'undefined' && typeof wx.closeSocket === 'function') {
|
||||
try {
|
||||
// 先检查WebSocket状态,避免在连接过程中关闭
|
||||
wx.closeSocket();
|
||||
this.locationWebSocket = null;
|
||||
console.log('WebSocket连接已关闭');
|
||||
}
|
||||
catch (error) {
|
||||
console.warn('关闭WebSocket连接时出现异常:', error);
|
||||
// 即使关闭失败,也重置连接状态
|
||||
this.locationWebSocket = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 处理WebSocket消息
|
||||
* @param message 接收到的消息
|
||||
*/
|
||||
handleWebSocketMessage(message) {
|
||||
if (!message || typeof message.type !== 'string') {
|
||||
console.warn('收到无效的WebSocket消息:', message);
|
||||
return;
|
||||
}
|
||||
locationTrackingService_1.default.handleWebSocketMessage(message);
|
||||
}
|
||||
/**
|
||||
* 发送WebSocket消息
|
||||
* @param message 要发送的消息对象
|
||||
*/
|
||||
sendWebSocketMessage(message) {
|
||||
if (!this.locationWebSocket) {
|
||||
console.warn('WebSocket连接未建立,无法发送消息');
|
||||
return;
|
||||
}
|
||||
try {
|
||||
const messageStr = JSON.stringify(message);
|
||||
if (typeof wx !== 'undefined' && typeof wx.sendSocketMessage === 'function') {
|
||||
wx.sendSocketMessage({
|
||||
data: messageStr
|
||||
});
|
||||
}
|
||||
}
|
||||
catch (error) {
|
||||
console.error('发送WebSocket消息失败:', error);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 订阅位置更新(服务器自动处理,无需发送消息)
|
||||
* @param userId 用户ID
|
||||
*/
|
||||
async subscribeToLocationUpdates() {
|
||||
// 确保WebSocket连接已建立
|
||||
if (!this.locationWebSocket) {
|
||||
this.initLocationWebSocket();
|
||||
}
|
||||
// 服务器会自动处理订阅逻辑,无需发送订阅消息
|
||||
console.log('位置订阅已初始化,服务器将自动处理订阅逻辑');
|
||||
}
|
||||
/**
|
||||
* 取消订阅位置更新(服务器自动处理,无需发送消息)
|
||||
* @param userId 用户ID
|
||||
*/
|
||||
async unsubscribeFromLocationUpdates(_userId) {
|
||||
// 服务器会自动处理取消订阅逻辑,无需发送取消订阅消息
|
||||
console.log('位置取消订阅已初始化,服务器将自动处理取消订阅逻辑');
|
||||
}
|
||||
/**
|
||||
* 发送位置更新
|
||||
* @param userId 用户ID
|
||||
* @param latitude 纬度
|
||||
* @param longitude 经度
|
||||
*/
|
||||
async sendLocationUpdate(userId, latitude, longitude) {
|
||||
// 确保WebSocket连接已建立
|
||||
if (!this.locationWebSocket) {
|
||||
this.initLocationWebSocket();
|
||||
}
|
||||
// 发送位置更新消息
|
||||
const locationMessage = {
|
||||
type: 'updateLocation',
|
||||
userId: userId,
|
||||
latitude: latitude,
|
||||
longitude: longitude,
|
||||
timestamp: Date.now()
|
||||
};
|
||||
this.sendWebSocketMessage(locationMessage);
|
||||
}
|
||||
// ==================== 订单接口 ====================
|
||||
/**
|
||||
* 获取待指派订单
|
||||
* @returns 待指派订单列表
|
||||
*/
|
||||
async getPendingOrders() {
|
||||
return await this.request('/orders/pending');
|
||||
}
|
||||
/**
|
||||
* 指派订单给货运人员
|
||||
* @param orderId 订单ID
|
||||
* @param deliveryPersonId 货运人员ID
|
||||
*/
|
||||
async assignOrder(orderId, deliveryPersonId) {
|
||||
return await this.request(`/orders/${orderId}/assign`, {
|
||||
method: 'POST',
|
||||
data: { deliveryPersonId },
|
||||
});
|
||||
}
|
||||
/**
|
||||
* 获取货运人员当前订单
|
||||
* @param deliveryPersonId 货运人员ID
|
||||
* @returns 订单列表
|
||||
*/
|
||||
async getDeliveryPersonOrders(deliveryPersonId) {
|
||||
return await this.request(`/delivery-persons/${deliveryPersonId}/orders`);
|
||||
}
|
||||
/**
|
||||
* 根据ID获取订单
|
||||
* @param id 订单ID
|
||||
* @returns 订单详细信息
|
||||
*/
|
||||
async getOrderById(id) {
|
||||
return await this.request(`/orders/${id}`);
|
||||
}
|
||||
/**
|
||||
* 更新订单状态
|
||||
* @param orderId 订单ID
|
||||
* @param status 目标状态
|
||||
*/
|
||||
async updateOrderStatus(orderId, status) {
|
||||
return await this.request(`/orders/${orderId}/status`, {
|
||||
method: 'PUT',
|
||||
data: { status },
|
||||
});
|
||||
}
|
||||
/**
|
||||
* 创建新订单
|
||||
* @param orderData 订单数据
|
||||
* @returns 创建的订单信息
|
||||
*/
|
||||
async createOrder(orderData) {
|
||||
return await this.request('/orders', {
|
||||
method: 'POST',
|
||||
data: orderData,
|
||||
});
|
||||
}
|
||||
/**
|
||||
* 删除订单
|
||||
* @param orderId 订单ID
|
||||
*/
|
||||
async deleteOrder(orderId) {
|
||||
return await this.request(`/orders/${orderId}`, {
|
||||
method: 'DELETE',
|
||||
});
|
||||
}
|
||||
// ==================== 统计和日志接口 ====================
|
||||
/**
|
||||
* 获取系统统计信息
|
||||
* @returns 系统统计数据
|
||||
*/
|
||||
async getSystemStats() {
|
||||
return await this.request('/stats/system');
|
||||
}
|
||||
/**
|
||||
* 获取订单统计信息
|
||||
* @param timeRange 时间范围
|
||||
* @returns 订单统计数据
|
||||
*/
|
||||
async getOrderStats(timeRange) {
|
||||
return await this.request(`/stats/orders?timeRange=${timeRange}`);
|
||||
}
|
||||
/**
|
||||
* 获取用户统计信息
|
||||
* @returns 用户统计数据
|
||||
*/
|
||||
async getUserStats() {
|
||||
return await this.request('/user/stats');
|
||||
}
|
||||
/**
|
||||
* 获取用户活动日志
|
||||
* @param userId 用户ID
|
||||
* @param limit 日志数量
|
||||
* @returns 活动日志列表
|
||||
*/
|
||||
async getUserActivityLogs(userId, limit = 20) {
|
||||
return await this.request(`/user/${userId}/activity-logs?limit=${limit}`);
|
||||
}
|
||||
/**
|
||||
* 上传错误日志
|
||||
* @param error 错误信息
|
||||
*/
|
||||
async uploadErrorLog(error) {
|
||||
await this.request('/logs/error', {
|
||||
method: 'POST',
|
||||
data: {
|
||||
error: error instanceof Error ? error.message : String(error),
|
||||
stack: error instanceof Error ? error.stack : undefined,
|
||||
timestamp: Date.now(),
|
||||
userAgent: 'miniprogram/' + (typeof wx !== 'undefined' ? wx.getSystemInfoSync().platform : 'unknown')
|
||||
}
|
||||
});
|
||||
}
|
||||
// ==================== 系统接口 ====================
|
||||
/**
|
||||
* 健康检查
|
||||
* @returns 系统健康状态
|
||||
*/
|
||||
async healthCheck() {
|
||||
return await this.request('/health');
|
||||
}
|
||||
}
|
||||
/**
|
||||
* API服务单例实例
|
||||
* 导出供应用程序全局使用
|
||||
*/
|
||||
exports.default = new ApiService();
|
||||
Reference in New Issue
Block a user