884 lines
29 KiB
JavaScript
884 lines
29 KiB
JavaScript
"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();
|