/**
|
* @author 韩天尊
|
* @time 2024-01-15
|
* @version 1.0.0
|
* @description API服务层 - 统一管理所有后端接口调用
|
*/
|
import axios, { AxiosResponse } from 'axios';
|
import { ApiResponse, PointsOverview, CommunityPointsOverview, VolunteerRegisterForm, QRCodeScanResult } from '../types';
|
import { APP_CONFIG } from '../config/appConfig';
|
|
// API基础配置
|
const HUB_BASE_URL = APP_CONFIG.API.HUB_BASE_URL;
|
const SYS_BASE_URL = APP_CONFIG.API.SYS_BASE_URL;
|
|
// 创建主要业务API的axios实例 (grid-hub)
|
const apiClient = axios.create({
|
baseURL: HUB_BASE_URL,
|
timeout: 10000,
|
headers: {
|
'Content-Type': 'application/json',
|
},
|
});
|
|
// 创建系统管理API的axios实例 (grid-sys)
|
const sysApiClient = axios.create({
|
baseURL: SYS_BASE_URL,
|
timeout: 10000,
|
headers: {
|
'Content-Type': 'application/json',
|
},
|
});
|
|
// 请求拦截器 - 添加token (主要业务API)
|
apiClient.interceptors.request.use(
|
(config) => {
|
const token = localStorage.getItem('token');
|
if (token) {
|
config.headers.Authorization = token;
|
}
|
return config;
|
},
|
(error) => {
|
return Promise.reject(error);
|
}
|
);
|
|
// 请求拦截器 - 添加token (系统管理API)
|
sysApiClient.interceptors.request.use(
|
(config) => {
|
// 如果请求已经设置了Authorization header,则不覆盖
|
if (!config.headers.Authorization) {
|
const token = localStorage.getItem('token');
|
if (token) {
|
config.headers.Authorization = token;
|
}
|
}
|
return config;
|
},
|
(error) => {
|
return Promise.reject(error);
|
}
|
);
|
|
// 响应拦截器 - 统一处理响应 (主要业务API)
|
apiClient.interceptors.response.use(
|
(response) => {
|
return response.data;
|
},
|
(error) => {
|
console.error('API请求错误:', error);
|
if (error.response?.status === 401) {
|
// token过期,清除所有本地存储并跳转到登录页
|
localStorage.removeItem('fwmPhone');
|
localStorage.removeItem('token');
|
localStorage.removeItem('user');
|
localStorage.removeItem('adminInfo');
|
window.location.href = '/login';
|
}
|
return Promise.reject(error);
|
}
|
);
|
|
// 响应拦截器 - 统一处理响应 (系统管理API)
|
sysApiClient.interceptors.response.use(
|
(response) => {
|
return response.data;
|
},
|
(error) => {
|
console.error('系统API请求错误:', error);
|
if (error.response?.status === 401) {
|
// token过期,清除所有本地存储并跳转到登录页
|
localStorage.removeItem('fwmPhone');
|
localStorage.removeItem('token');
|
localStorage.removeItem('user');
|
localStorage.removeItem('adminInfo');
|
window.location.href = '/login';
|
}
|
return Promise.reject(error);
|
}
|
);
|
|
// 用户认证相关接口
|
export const authAPI = {
|
// 用户登录
|
login: (phone: string, password: string): Promise<ApiResponse> => {
|
return apiClient.post('/dingTalk/api/users/login', {
|
phone,
|
password,
|
}, {
|
headers: {
|
'Authorization': 'sys'
|
}
|
});
|
},
|
|
// 用户注册
|
register: (name: string, phone: string, password: string, idCard: string): Promise<ApiResponse> => {
|
return apiClient.post('/dingTalk/api/users/register', {
|
name,
|
phone,
|
password,
|
idCard,
|
}, {
|
headers: {
|
'Authorization': 'sys'
|
}
|
});
|
},
|
|
// 根据手机号获取用户信息
|
getUserByPhone: (phone: string): Promise<ApiResponse> => {
|
return apiClient.get('/dingTalk/api/users/getByPhone', {
|
params: { phone }
|
});
|
},
|
|
// 退出登录
|
logout: (): Promise<ApiResponse> => {
|
return apiClient.post('/dingTalk/api/users/logout');
|
},
|
};
|
|
// 志愿者注册相关接口
|
export const volunteerAPI = {
|
// 志愿者注册申请 - 使用sys认证,不需要登录
|
register: (formData: VolunteerRegisterForm): Promise<ApiResponse> => {
|
return sysApiClient.post('/dingTalk/api/vol/register', formData, {
|
headers: {
|
'Authorization': 'sys'
|
}
|
});
|
},
|
|
// 获取志愿者注册状态
|
getStatus: (): Promise<ApiResponse> => {
|
return apiClient.get('/dingTalk/api/vol/status');
|
},
|
};
|
|
// 活动相关接口
|
export const activityAPI = {
|
// 获取活动列表
|
getList: (params: {
|
page?: number;
|
size?: number;
|
status?: string;
|
category?: string;
|
keyword?: string;
|
community?: string;
|
}): Promise<ApiResponse> => {
|
return apiClient.get('/dingTalk/api/activities/list', { params });
|
},
|
|
// 获取活动详情
|
getDetail: (id: number): Promise<ApiResponse> => {
|
return apiClient.get(`/dingTalk/api/activities/detail/${id}`);
|
},
|
|
// 报名活动
|
join: (activityId: number): Promise<ApiResponse> => {
|
return apiClient.post('/dingTalk/api/activities/join', {
|
activityId,
|
});
|
},
|
|
// 取消报名
|
cancel: (activityId: number): Promise<ApiResponse> => {
|
return apiClient.post('/dingTalk/api/activities/cancel', {
|
activityId,
|
});
|
},
|
};
|
|
// 签到相关接口
|
export const checkinAPI = {
|
// 扫码签到
|
scanCheckin: (activityId: number, qrCode: string, latitude: string, longitude: string, location: string): Promise<ApiResponse> => {
|
return apiClient.post('/dingTalk/api/checkin/scan', {
|
activityId,
|
qrCode,
|
latitude,
|
longitude,
|
location,
|
});
|
},
|
|
// 签退
|
checkout: (activityId: number, latitude: string, longitude: string, location: string): Promise<ApiResponse> => {
|
return apiClient.post('/dingTalk/api/checkin/checkout', {
|
activityId,
|
latitude,
|
longitude,
|
location,
|
});
|
},
|
|
// 获取签到记录
|
getRecords: (params: {
|
page?: number;
|
size?: number;
|
activityId?: number;
|
status?: string;
|
}): Promise<ApiResponse> => {
|
return apiClient.get('/dingTalk/api/checkin/records', { params });
|
},
|
|
// 签到/签退接口
|
scanCheck: (activityId: number, latitude?: number, longitude?: number, location?: string): Promise<ApiResponse> => {
|
return apiClient.post('/dingTalk/api/checkin/scanCheck', {
|
activityId,
|
latitude,
|
longitude,
|
location,
|
});
|
},
|
};
|
|
// 积分相关接口
|
export const pointsAPI = {
|
// 提交积分申报
|
declare: (data: {
|
category: string;
|
categoryDesc: string;
|
secondary: string;
|
activityName: string;
|
startTime: string;
|
endTime: string;
|
serviceHours: number;
|
expectedPoints: number;
|
ownerId: string;
|
}): Promise<ApiResponse> => {
|
return apiClient.post('/dingTalk/api/points/declare', data);
|
},
|
|
// 获取积分申报列表
|
getDeclarations: (params: {
|
page?: number;
|
size?: number;
|
status?: string;
|
category?: string;
|
}): Promise<ApiResponse> => {
|
return apiClient.get('/dingTalk/api/points/declarations', { params });
|
},
|
|
// 获取积分申报详情
|
getDeclarationDetail: (id: number): Promise<ApiResponse> => {
|
return apiClient.get(`/dingTalk/api/points/declarations/${id}`);
|
},
|
|
// 获取积分概览
|
getOverview: (): Promise<ApiResponse<PointsOverview | CommunityPointsOverview>> => {
|
return apiClient.get('/dingTalk/api/points/overview');
|
},
|
|
// 获取积分记录
|
getRecords: (params: {
|
page?: number;
|
size?: number;
|
type?: string;
|
startTime?: string;
|
endTime?: string;
|
}): Promise<ApiResponse> => {
|
return apiClient.get('/dingTalk/api/points/records', { params });
|
},
|
|
// 生成核销二维码
|
generateRedemptionQR: (points: number, productNum: number, productName: string, description: string): Promise<ApiResponse> => {
|
return apiClient.post('/dingTalk/api/points/redemption/qrcode', {
|
points,
|
productNum,
|
productName,
|
description,
|
});
|
},
|
|
// 处理积分核销
|
processRedemption: (qrCode: string, points: number, productNum: number, productName: string, description: string): Promise<ApiResponse> => {
|
return apiClient.post('/dingTalk/api/points/redemption/process', {
|
qrCode,
|
points,
|
productNum,
|
productName,
|
description,
|
});
|
},
|
|
// 扫描二维码获取用户信息
|
scanQRCodeUser: (communityCode: string): Promise<ApiResponse<QRCodeScanResult>> => {
|
return apiClient.post('/dingTalk/api/points/redemption/qrcodeUser', {
|
communityCode
|
});
|
},
|
|
// 获取核销记录
|
getRedemptionRecords: (params: {
|
page?: number;
|
size?: number;
|
startTime?: string;
|
endTime?: string;
|
}): Promise<ApiResponse> => {
|
return apiClient.get('/dingTalk/api/points/redemption/records', { params });
|
},
|
};
|
|
// 消息相关接口
|
export const messageAPI = {
|
// 获取消息列表
|
getList: (params?: {
|
page?: number;
|
size?: number;
|
type?: string;
|
isRead?: string;
|
userId?: number;
|
}): Promise<ApiResponse> => {
|
return apiClient.get('/dingTalk/api/messages/list', { params });
|
},
|
|
// 获取消息详情
|
getDetail: (id: number): Promise<ApiResponse> => {
|
return apiClient.get(`/dingTalk/api/messages/detail/${id}`);
|
},
|
|
// 标记消息为已读
|
markAsRead: (messageId: number): Promise<ApiResponse> => {
|
return apiClient.post('/dingTalk/api/messages/read', { messageId });
|
},
|
};
|
|
// 管理员相关接口
|
export const adminAPI = {
|
// 管理员登录
|
login: (username: string, password: string): Promise<ApiResponse> => {
|
return apiClient.post('/dingTalk/api/admin/login', {
|
username,
|
password,
|
});
|
},
|
|
// 获取管理员信息
|
getAdminInfo: (phone: string): Promise<ApiResponse> => {
|
return apiClient.get(`/dingTalk/api/admin/users/info/${phone}`);
|
},
|
|
// 获取管理端统计数据
|
getDashboardStats: (): Promise<ApiResponse> => {
|
return apiClient.get('/dingTalk/api/admin/stats/dashboard');
|
},
|
|
// 获取活动统计
|
getActivityStats: (params: {
|
startDate?: string;
|
endDate?: string;
|
}): Promise<ApiResponse> => {
|
return apiClient.get('/dingTalk/api/admin/stats/activities', { params });
|
},
|
|
// 获取积分统计
|
getPointsStats: (params: {
|
startDate?: string;
|
endDate?: string;
|
}): Promise<ApiResponse> => {
|
return apiClient.get('/dingTalk/api/admin/stats/points', { params });
|
},
|
|
// 获取活动列表(管理员)
|
getActivityList: (params: {
|
page?: number;
|
size?: number;
|
status?: string;
|
communityCode?: string;
|
}): Promise<ApiResponse> => {
|
return apiClient.get('/dingTalk/api/admin/activities/list', { params });
|
},
|
|
// 获取活动详情(管理员)
|
getActivityDetail: (id: number): Promise<ApiResponse> => {
|
return apiClient.get(`/dingTalk/api/admin/activities/detail/${id}`);
|
},
|
|
// 创建活动
|
createActivity: (data: {
|
title: string;
|
category: string;
|
categoryDesc: string;
|
startTime: string;
|
endTime: string;
|
location: string;
|
content: string;
|
maxParticipants: number;
|
deadline: string;
|
points: number;
|
ownerId: string;
|
img?: string;
|
communityCode: string;
|
communityName: string;
|
subdistrictCode: string;
|
subdistrictName: string;
|
districtCode: string;
|
districtName: string;
|
creatorId: number;
|
creatorName: string;
|
}): Promise<ApiResponse> => {
|
return apiClient.post('/dingTalk/api/admin/activities/create', data);
|
},
|
|
// 更新活动状态
|
updateActivityStatus: (activityId: number, status: string): Promise<ApiResponse> => {
|
return apiClient.post('/dingTalk/api/admin/activities/updateStatus', {
|
activityId,
|
status,
|
});
|
},
|
|
// 生成活动签到二维码
|
generateActivityQRCode: (id: number): Promise<ApiResponse> => {
|
return apiClient.get(`/dingTalk/api/admin/activities/qrcode/${id}`);
|
},
|
|
// 获取积分审核列表
|
getPointsReviewList: (params: {
|
page?: number;
|
size?: number;
|
status?: string;
|
}): Promise<ApiResponse> => {
|
return apiClient.get('/dingTalk/api/admin/points/review/list', { params });
|
},
|
|
// 获取积分审核详情
|
getPointsReviewDetail: (id: number): Promise<ApiResponse> => {
|
return apiClient.get(`/dingTalk/api/admin/points/review/detail/${id}`);
|
},
|
|
// 批量审核积分申报
|
batchReviewPointsDeclaration: (data: {
|
declarationIds: number[];
|
action: string;
|
comment: string;
|
}): Promise<ApiResponse> => {
|
return apiClient.post('/dingTalk/api/admin/points/review', data);
|
},
|
|
// 单个审核积分申报
|
singleReviewPointsDeclaration: (data: {
|
declarationId: number;
|
action: string;
|
comment: string;
|
}): Promise<ApiResponse> => {
|
return apiClient.post('/dingTalk/api/admin/points/review/single', data);
|
},
|
|
// 获取志愿者审核列表
|
getVolunteerReviewList: (params: {
|
page?: number;
|
size?: number;
|
status?: string;
|
}): Promise<ApiResponse> => {
|
return apiClient.get('/dingTalk/api/admin/volunteer/review/list', { params });
|
},
|
|
// 获取志愿者审核详情
|
getVolunteerReviewDetail: (id: number): Promise<ApiResponse> => {
|
return apiClient.get(`/dingTalk/api/admin/volunteer/review/detail/${id}`);
|
},
|
|
// 批量审核志愿者申请
|
batchReviewVolunteerApplication: (data: {
|
applicationIds: number[];
|
action: string;
|
comment: string;
|
}): Promise<ApiResponse> => {
|
return apiClient.post('/dingTalk/api/admin/volunteer/review', data);
|
},
|
|
// 单个审核志愿者申请
|
singleReviewVolunteerApplication: (data: {
|
applicationId: number;
|
action: string;
|
comment: string;
|
}): Promise<ApiResponse> => {
|
return apiClient.post('/dingTalk/api/admin/volunteer/review/single', data);
|
},
|
|
// 扫码核销积分
|
redeemPoints: (data: {
|
qrCode: string;
|
communityCode: string;
|
volunteerId: string;
|
points: number;
|
productNum: number;
|
productName: string;
|
description: string;
|
}): Promise<ApiResponse> => {
|
return apiClient.post('/dingTalk/api/admin/points/redemption', data);
|
},
|
|
// 根据二维码参数获取用户信息
|
getQRCodeUserInfo: (data: {
|
communityCode: string;
|
userId: string;
|
}): Promise<ApiResponse> => {
|
return apiClient.post('/dingTalk/api/points/redemption/qrcodeUser', data);
|
},
|
|
// 获取核销记录
|
getRedemptionRecords: (params: {
|
page?: number;
|
size?: number;
|
startDate?: string;
|
endDate?: string;
|
}): Promise<ApiResponse> => {
|
return apiClient.get('/dingTalk/api/admin/points/redemption/records', { params });
|
},
|
|
// 获取用户列表
|
getUserList: (params: {
|
page?: number;
|
size?: number;
|
keyword?: string;
|
communityCode?: string;
|
}): Promise<ApiResponse> => {
|
return apiClient.get('/dingTalk/api/admin/users/list', { params });
|
},
|
|
// 获取用户详情
|
getUserDetail: (id: number): Promise<ApiResponse> => {
|
return apiClient.get(`/dingTalk/api/admin/users/detail/${id}`);
|
},
|
|
// 上传文件
|
uploadFile: (formData: FormData, ownerId: string, ownerType: string = '35001'): Promise<ApiResponse> => {
|
return sysApiClient.post(`/dingTalk/api/fileInfo/upload?ownerId=${ownerId}&ownerType=${ownerType}`, formData, {
|
headers: {
|
'Content-Type': 'multipart/form-data',
|
},
|
});
|
},
|
|
// 删除文件
|
deleteFile: (fileId: string): Promise<ApiResponse> => {
|
return sysApiClient.get(`/dingTalk/api/fileInfo/deleteById?id=${fileId}`);
|
},
|
};
|
|
export default apiClient;
|