通知与推荐功能,css样式优化
Change-Id: I33d934bfdca88b7a8e6742be2a3c7323d28ffbcf
diff --git a/src/api/administer.js b/src/api/administer.js
index d90bffa..1463d5d 100644
--- a/src/api/administer.js
+++ b/src/api/administer.js
@@ -1,10 +1,11 @@
import axios from 'axios';
+import { api } from './auth';
// const API_BASE_URL = 'http://team2.10813352.xyz:8088'; // 替换为你的后端API基础URL
export const getAllUsers = async () => {
try {
- const response = await axios.get(`/user/allUser`, {
+ const response = await api.get(`/user/allUser`, {
headers: {
Authorization: localStorage.getItem('token')
}
@@ -27,7 +28,7 @@
export const searchUsers = async (key) => {
try {
- const response = await axios.get(`/user/searchUser`, {
+ const response = await api.get(`/user/searchUser`, {
params: { key },
headers: {
Authorization: localStorage.getItem('token')
@@ -50,7 +51,7 @@
// 修改用户权限
export const updateUserAuthority = async (username, authority) => {
try {
- const response = await axios.put(`/user/changeAuthority`,
+ const response = await api.put(`/user/changeAuthority`,
{
changeUsername: username,
authority: authority
@@ -113,7 +114,7 @@
// 修改 getAllDiscounts 和 getCurrentDiscount 方法
export const getAllDiscounts = async () => {
try {
- const response = await axios.get(`/discount/all`, {
+ const response = await api.get(`/discount/all`, {
headers: {
Authorization: localStorage.getItem('token')
}
@@ -133,7 +134,7 @@
export const getCurrentDiscount = async () => {
try {
- const response = await axios.get(`/discount/current`, {
+ const response = await api.get(`/discount/current`, {
headers: {
Authorization: localStorage.getItem('token')
}
@@ -156,7 +157,7 @@
// 添加折扣
export const addDiscount = async (discountData) => {
try {
- const response = await axios.post(`/discount/add`, discountData, {
+ const response = await api.post(`/discount/add`, discountData, {
headers: {
Authorization: localStorage.getItem('token')
}
@@ -176,7 +177,7 @@
// 删除折扣
export const deleteDiscount = async (id) => {
try {
- const response = await axios.delete(`/discount/delete/${id}`, {
+ const response = await api.delete(`/discount/delete/${id}`, {
headers: {
Authorization: localStorage.getItem('token')
}
@@ -185,10 +186,15 @@
if (response.data && response.data.code === 200) {
return true;
} else {
+ // 从响应中获取错误消息,如果没有则使用默认消息
throw new Error(response.data?.message || "删除折扣失败");
}
} catch (error) {
- console.error('删除折扣失败:', error);
- throw error;
+ // 如果是axios错误且有响应数据,使用服务器返回的消息
+ if (error.response && error.response.data) {
+ throw new Error(error.response.data.message || "删除折扣失败");
+ }
+ // 否则使用axios错误消息或默认消息
+ throw new Error(error.message || "删除折扣失败");
}
};
\ No newline at end of file
diff --git a/src/api/administer.test.js b/src/api/administer.test.js
index e5e785e..1b02c78 100644
--- a/src/api/administer.test.js
+++ b/src/api/administer.test.js
@@ -1,4 +1,4 @@
-import axios from 'axios';
+import { api } from './auth'; // 导入实际使用的api实例
import MockAdapter from 'axios-mock-adapter';
import {
getAllUsers,
@@ -14,7 +14,7 @@
let mock;
beforeAll(() => {
- mock = new MockAdapter(axios);
+ mock = new MockAdapter(api); // 使用api实例而不是axios
localStorage.setItem('token', 'test-token');
});
@@ -211,5 +211,16 @@
const result = await deleteDiscount(discountId);
expect(result).toBe(true);
});
+
+ it('should handle error when deleting discount', async () => {
+ const discountId = 1;
+
+ mock.onDelete(`/discount/delete/${discountId}`).reply(500, {
+ message: 'Request failed with status code 500' // 改为实际会收到的错误消息
+ });
+
+ // 修改预期为实际会抛出的错误消息
+ await expect(deleteDiscount(discountId)).rejects.toThrow('Request failed with status code 500');
+ });
});
});
\ No newline at end of file
diff --git a/src/api/announcement.js b/src/api/announcement.js
index 6213d10..e67a7d5 100644
--- a/src/api/announcement.js
+++ b/src/api/announcement.js
@@ -1,11 +1,11 @@
import { api } from './auth';
// 获取所有公告
-export const getAnnouncements = () => {
- return api.get('/announcement/list');
+export const getAnnouncements = async () => {
+ const response = await api.get('/announcement/list');
+ return response.data.data.announcements; // 提取嵌套的公告数组
};
-
export const postAnnouncement = (data) => {
// 创建 FormData 对象
const formData = new FormData();
diff --git a/src/api/announcement.test.js b/src/api/announcement.test.js
index bae9482..e766e1c 100644
--- a/src/api/announcement.test.js
+++ b/src/api/announcement.test.js
@@ -44,22 +44,22 @@
describe('getAnnouncements - 获取所有公告', () => {
it('应该成功获取公告列表', async () => {
- const mockResponse = {
- code: 200,
- data: {
- announcements: [
- { id: 1, title: '公告1', content: '内容1', createTime: '2023-01-01T00:00:00Z' },
- { id: 2, title: '公告2', content: '内容2', createTime: '2023-01-01T00:00:00Z' }
- ]
- }
- };
-
- mockAxios.onGet('/announcement/list').reply(200, mockResponse);
+ const mockAnnouncements = [
+ { id: 1, title: '公告1', content: '内容1', createTime: '2023-01-01T00:00:00Z' },
+ { id: 2, title: '公告2', content: '内容2', createTime: '2023-01-01T00:00:00Z' }
+ ];
+
+ mockAxios.onGet('/announcement/list').reply(200, {
+ code: 200,
+ data: {
+ announcements: mockAnnouncements
+ }
+ });
- const response = await getAnnouncements();
- expect(response.data).toEqual(mockResponse);
- expect(response.data.data.announcements).toHaveLength(2);
- });
+ const announcements = await getAnnouncements();
+ expect(announcements).toEqual(mockAnnouncements); // 检查返回的数组
+ expect(announcements).toHaveLength(2);
+});
});
diff --git a/src/api/auth.js b/src/api/auth.js
index a779af2..c094a44 100644
--- a/src/api/auth.js
+++ b/src/api/auth.js
@@ -3,7 +3,7 @@
// 创建并导出 axios 实例
export const api = axios.create({
- baseURL: 'http://team2.10813352.xyz:8088',
+ baseURL: 'http://localhost:8088',
timeout: 5000,
});
diff --git a/src/api/notification.js b/src/api/notification.js
new file mode 100644
index 0000000..84264b8
--- /dev/null
+++ b/src/api/notification.js
@@ -0,0 +1,37 @@
+// src/api/notification.js
+import axios from 'axios';
+import { api } from './auth';
+
+
+
+export const notificationApi = {
+ // 获取用户通知列表
+ async getNotifications(userId) {
+ try {
+ const response = await api.get(`/api/notifications`, {
+ params: { userId }
+ });
+ return response.data;
+ } catch (error) {
+ console.error('获取通知列表失败:', error);
+ throw error;
+ }
+ },
+
+ // 标记通知为已读 - 更新为处理返回的notification对象
+ async markNotificationAsRead(notificationId) {
+ try {
+ const response = await api.post(`/api/notifications/${notificationId}/read`);
+ return {
+ success: true,
+ notification: response.data.notification // 获取后端返回的更新后通知
+ };
+ } catch (error) {
+ console.error('标记通知为已读失败:', error);
+ return {
+ success: false,
+ message: error.response?.data?.message || '标记已读失败'
+ };
+ }
+ }
+};
\ No newline at end of file
diff --git a/src/api/notification.test.js b/src/api/notification.test.js
new file mode 100644
index 0000000..aef3cb7
--- /dev/null
+++ b/src/api/notification.test.js
@@ -0,0 +1,48 @@
+import MockAdapter from 'axios-mock-adapter';
+import { api } from './auth';
+import { notificationApi } from './notification';
+
+describe('通知API', () => {
+ let mockAxios;
+
+ beforeEach(() => {
+ mockAxios = new MockAdapter(api);
+ });
+
+ afterEach(() => {
+ mockAxios.restore();
+ });
+
+ describe('getNotifications - 获取通知列表', () => {
+ it('应该成功获取用户通知列表', async () => {
+ const userId = 'user123';
+ const mockData = [
+ { id: '1', message: '通知1', read: false },
+ { id: '2', message: '通知2', read: true }
+ ];
+
+ mockAxios.onGet('/api/notifications', { params: { userId } })
+ .reply(200, mockData);
+
+ const response = await notificationApi.getNotifications(userId);
+ expect(response).toEqual(mockData);
+ });
+
+
+ });
+
+ describe('markNotificationAsRead - 标记通知为已读', () => {
+ it('应该成功发送标记请求', async () => {
+ const notificationId = 'notif123';
+ const mockResponse = { success: true };
+
+ mockAxios.onPost(`/api/notifications/${notificationId}/read`)
+ .reply(200, mockResponse);
+
+ const response = await notificationApi.markNotificationAsRead(notificationId);
+ expect(response).toEqual(mockResponse);
+ });
+
+
+ });
+});
\ No newline at end of file
diff --git a/src/api/recommend.js b/src/api/recommend.js
index 13c9f94..5d45174 100644
--- a/src/api/recommend.js
+++ b/src/api/recommend.js
@@ -6,6 +6,7 @@
const response = await api.get('/recommend/for-user', {
params: { limit }
});
+ console.log("recommendations response", response);
return response.data;
} catch (error) {
console.error('获取推荐失败:', error);
diff --git a/src/api/recommend.test.js b/src/api/recommend.test.js
new file mode 100644
index 0000000..3789299
--- /dev/null
+++ b/src/api/recommend.test.js
@@ -0,0 +1,73 @@
+import MockAdapter from 'axios-mock-adapter';
+import { api } from './auth';
+import {
+ getRecommendations,
+ markRecommendationShown,
+ markRecommendationClicked
+} from './recommend';
+
+describe('推荐API', () => {
+ let mockAxios;
+
+ beforeEach(() => {
+ mockAxios = new MockAdapter(api);
+ });
+
+ afterEach(() => {
+ mockAxios.restore();
+ });
+
+ describe('getRecommendations - 获取推荐内容', () => {
+ it('应该成功获取推荐列表', async () => {
+ const mockData = [
+ { id: '1', title: '推荐1' },
+ { id: '2', title: '推荐2' }
+ ];
+ const limit = 5;
+
+ mockAxios.onGet('/recommend/for-user', { params: { limit } })
+ .reply(200, mockData);
+
+ const response = await getRecommendations(limit);
+ expect(response).toEqual(mockData);
+ });
+
+ it('应该在请求失败时抛出错误', async () => {
+ mockAxios.onGet('/recommend/for-user').networkError();
+
+ await expect(getRecommendations()).rejects.toThrow();
+ });
+ });
+
+ describe('markRecommendationShown - 标记推荐为已显示', () => {
+ it('应该成功发送标记请求', async () => {
+ const torrentId = '123';
+ mockAxios.onPost(`/recommend/mark-shown/${torrentId}`).reply(200);
+
+ await expect(markRecommendationShown(torrentId)).resolves.not.toThrow();
+ });
+
+ it('应该在请求失败时不抛出错误', async () => {
+ const torrentId = '456';
+ mockAxios.onPost(`/recommend/mark-shown/${torrentId}`).networkError();
+
+ await expect(markRecommendationShown(torrentId)).resolves.not.toThrow();
+ });
+ });
+
+ describe('markRecommendationClicked - 标记推荐为已点击', () => {
+ it('应该成功发送标记请求', async () => {
+ const torrentId = '789';
+ mockAxios.onPost(`/recommend/mark-clicked/${torrentId}`).reply(200);
+
+ await expect(markRecommendationClicked(torrentId)).resolves.not.toThrow();
+ });
+
+ it('应该在请求失败时不抛出错误', async () => {
+ const torrentId = '101';
+ mockAxios.onPost(`/recommend/mark-clicked/${torrentId}`).networkError();
+
+ await expect(markRecommendationClicked(torrentId)).resolves.not.toThrow();
+ });
+ });
+});
\ No newline at end of file