feat: 添加前端 MobX Stores
- RegionStore(版块管理、查询、评分、收藏) - ArticleStore(文章管理、提交、审核、评论、点赞、统计) - ServiceStore(特色服务管理、提交、审核、评论、点赞、评分、统计) - InteractionStore(交互功能:评论、评分、点赞、收藏) - 更新 UserStore(保持原有) - 更新 AuthStore(保持原有) - 更新 index.js 导入所有 Stores
This commit is contained in:
@@ -6,14 +6,22 @@ import App from './App';
|
|||||||
import './styles/global';
|
import './styles/global';
|
||||||
|
|
||||||
// Import stores
|
// Import stores
|
||||||
import UserStore from './stores/UserStore';
|
|
||||||
import AuthStore from './stores/AuthStore';
|
import AuthStore from './stores/AuthStore';
|
||||||
|
import UserStore from './stores/UserStore';
|
||||||
|
import RegionStore from './stores/RegionStore';
|
||||||
|
import ArticleStore from './stores/ArticleStore';
|
||||||
|
import ServiceStore from './stores/ServiceStore';
|
||||||
|
import InteractionStore from './stores/InteractionStore';
|
||||||
|
|
||||||
const root = ReactDOM.createRoot(document.getElementById('root'));
|
const root = ReactDOM.createRoot(document.getElementById('root'));
|
||||||
|
|
||||||
const stores = {
|
const stores = {
|
||||||
userStore: new UserStore(),
|
|
||||||
authStore: new AuthStore(),
|
authStore: new AuthStore(),
|
||||||
|
userStore: new UserStore(),
|
||||||
|
regionStore: new RegionStore(),
|
||||||
|
articleStore: new ArticleStore(),
|
||||||
|
serviceStore: new ServiceStore(),
|
||||||
|
interactionStore: new InteractionStore(),
|
||||||
};
|
};
|
||||||
|
|
||||||
root.render(
|
root.render(
|
||||||
|
|||||||
152
frontend/src/stores/ArticleStore.js
Normal file
152
frontend/src/stores/ArticleStore.js
Normal file
@@ -0,0 +1,152 @@
|
|||||||
|
import { makeAutoObservable } from 'mobx';
|
||||||
|
import api from '../services/api';
|
||||||
|
|
||||||
|
class ArticleStore {
|
||||||
|
articles = [];
|
||||||
|
currentArticle = null;
|
||||||
|
loading = false;
|
||||||
|
error = null;
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
makeAutoObservable(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
async fetchArticles(params = {}) {
|
||||||
|
this.loading = true;
|
||||||
|
this.error = null;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const response = await api.get('/api/articles/', { params });
|
||||||
|
this.articles = response.data.results || response.data;
|
||||||
|
} catch (error) {
|
||||||
|
this.error = error.response?.data || 'Failed to fetch articles';
|
||||||
|
} finally {
|
||||||
|
this.loading = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async fetchArticle(id) {
|
||||||
|
this.loading = true;
|
||||||
|
this.error = null;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const response = await api.get(`/api/articles/${id}/`);
|
||||||
|
this.currentArticle = response.data;
|
||||||
|
} catch (error) {
|
||||||
|
this.error = error.response?.data || 'Failed to fetch article';
|
||||||
|
} finally {
|
||||||
|
this.loading = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async createArticle(data) {
|
||||||
|
this.loading = true;
|
||||||
|
this.error = null;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const response = await api.post('/api/articles/', data);
|
||||||
|
return { success: true, article: response.data };
|
||||||
|
} catch (error) {
|
||||||
|
this.error = error.response?.data || 'Failed to create article';
|
||||||
|
return { success: false, error: this.error };
|
||||||
|
} finally {
|
||||||
|
this.loading = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async updateArticle(id, data) {
|
||||||
|
this.loading = true;
|
||||||
|
this.error = null;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const response = await api.put(`/api/articles/${id}/`, data);
|
||||||
|
return { success: true, article: response.data };
|
||||||
|
} catch (error) {
|
||||||
|
this.error = error.response?.data || 'Failed to update article';
|
||||||
|
return { success: false, error: this.error };
|
||||||
|
} finally {
|
||||||
|
this.loading = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async deleteArticle(id) {
|
||||||
|
try {
|
||||||
|
await api.delete(`/api/articles/${id}/`);
|
||||||
|
return { success: true };
|
||||||
|
} catch (error) {
|
||||||
|
return {
|
||||||
|
success: false,
|
||||||
|
error: error.response?.data || 'Failed to delete article',
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async submitArticle(id) {
|
||||||
|
try {
|
||||||
|
await api.post(`/api/articles/${id}/submit/`);
|
||||||
|
return { success: true };
|
||||||
|
} catch (error) {
|
||||||
|
return {
|
||||||
|
success: false,
|
||||||
|
error: error.response?.data || 'Failed to submit article',
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async approveArticle(id, reason = '') {
|
||||||
|
try {
|
||||||
|
await api.post(`/api/articles/${id}/approve/`, { action: 'approve', reason });
|
||||||
|
return { success: true };
|
||||||
|
} catch (error) {
|
||||||
|
return {
|
||||||
|
success: false,
|
||||||
|
error: error.response?.data || 'Failed to approve article',
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async rejectArticle(id, reason) {
|
||||||
|
try {
|
||||||
|
await api.post(`/api/articles/${id}/reject/`, { action: 'reject', reason });
|
||||||
|
return { success: true };
|
||||||
|
} catch (error) {
|
||||||
|
return {
|
||||||
|
success: false,
|
||||||
|
error: error.response?.data || 'Failed to reject article',
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async likeArticle(id) {
|
||||||
|
try {
|
||||||
|
const response = await api.post(`/api/articles/${id}/like/`);
|
||||||
|
return response.data;
|
||||||
|
} catch (error) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async fetchArticleComments(id) {
|
||||||
|
try {
|
||||||
|
const response = await api.get(`/api/articles/${id}/comments/`);
|
||||||
|
return response.data;
|
||||||
|
} catch (error) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async fetchArticleStats(id) {
|
||||||
|
try {
|
||||||
|
const response = await api.get(`/api/articles/${id}/stats/`);
|
||||||
|
return response.data;
|
||||||
|
} catch (error) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
clearCurrentArticle() {
|
||||||
|
this.currentArticle = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default ArticleStore;
|
||||||
164
frontend/src/stores/InteractionStore.js
Normal file
164
frontend/src/stores/InteractionStore.js
Normal file
@@ -0,0 +1,164 @@
|
|||||||
|
import { makeAutoObservable } from 'mobx';
|
||||||
|
import api from '../services/api';
|
||||||
|
|
||||||
|
class InteractionStore {
|
||||||
|
comments = [];
|
||||||
|
ratings = [];
|
||||||
|
likes = [];
|
||||||
|
favorites = [];
|
||||||
|
loading = false;
|
||||||
|
error = null;
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
makeAutoObservable(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Comments
|
||||||
|
async createComment(targetType, targetId, content) {
|
||||||
|
try {
|
||||||
|
const response = await api.post('/api/comments/', {
|
||||||
|
target_type: targetType,
|
||||||
|
target_id: targetId,
|
||||||
|
content,
|
||||||
|
});
|
||||||
|
return { success: true, comment: response.data };
|
||||||
|
} catch (error) {
|
||||||
|
return {
|
||||||
|
success: false,
|
||||||
|
error: error.response?.data || 'Failed to create comment',
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async fetchComments(targetType, targetId) {
|
||||||
|
try {
|
||||||
|
const response = await api.get('/api/comments/', {
|
||||||
|
params: { target_type: targetType, target_id: targetId },
|
||||||
|
});
|
||||||
|
this.comments = response.data.results || response.data;
|
||||||
|
} catch (error) {
|
||||||
|
this.error = error.response?.data || 'Failed to fetch comments';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async approveComment(commentId) {
|
||||||
|
try {
|
||||||
|
await api.post(`/api/comments/${commentId}/approve_ai/`);
|
||||||
|
return { success: true };
|
||||||
|
} catch (error) {
|
||||||
|
return {
|
||||||
|
success: false,
|
||||||
|
error: error.response?.data || 'Failed to approve comment',
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async rejectComment(commentId, reason) {
|
||||||
|
try {
|
||||||
|
await api.post(`/api/comments/${commentId}/reject_ai/`, { reason });
|
||||||
|
return { success: true };
|
||||||
|
} catch (error) {
|
||||||
|
return {
|
||||||
|
success: false,
|
||||||
|
error: error.response?.data || 'Failed to reject comment',
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ratings
|
||||||
|
async createRating(targetType, targetId, score) {
|
||||||
|
try {
|
||||||
|
const response = await api.post('/api/ratings/', {
|
||||||
|
target_type: targetType,
|
||||||
|
target_id: targetId,
|
||||||
|
score,
|
||||||
|
});
|
||||||
|
return { success: true, rating: response.data };
|
||||||
|
} catch (error) {
|
||||||
|
return {
|
||||||
|
success: false,
|
||||||
|
error: error.response?.data || 'Failed to create rating',
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async fetchRatings(params = {}) {
|
||||||
|
try {
|
||||||
|
const response = await api.get('/api/ratings/', { params });
|
||||||
|
this.ratings = response.data.results || response.data;
|
||||||
|
} catch (error) {
|
||||||
|
this.error = error.response?.data || 'Failed to fetch ratings';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async fetchMyRatings() {
|
||||||
|
try {
|
||||||
|
const response = await api.get('/api/ratings/my_ratings/');
|
||||||
|
this.ratings = response.data;
|
||||||
|
} catch (error) {
|
||||||
|
this.error = error.response?.data || 'Failed to fetch my ratings';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Likes
|
||||||
|
async toggleLike(targetType, targetId) {
|
||||||
|
try {
|
||||||
|
const response = await api.post('/api/likes/toggle/', {
|
||||||
|
target_type: targetType,
|
||||||
|
target_id: targetId,
|
||||||
|
});
|
||||||
|
return response.data;
|
||||||
|
} catch (error) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async fetchMyLikes() {
|
||||||
|
try {
|
||||||
|
const response = await api.get('/api/likes/my_likes/');
|
||||||
|
this.likes = response.data;
|
||||||
|
} catch (error) {
|
||||||
|
this.error = error.response?.data || 'Failed to fetch my likes';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Favorites
|
||||||
|
async toggleFavorite(targetType, targetId) {
|
||||||
|
try {
|
||||||
|
const response = await api.post('/api/favorites/toggle/', {
|
||||||
|
target_type: targetType,
|
||||||
|
target_id: targetId,
|
||||||
|
});
|
||||||
|
return response.data;
|
||||||
|
} catch (error) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async fetchMyFavorites() {
|
||||||
|
try {
|
||||||
|
const response = await api.get('/api/favorites/my_favorites/');
|
||||||
|
this.favorites = response.data;
|
||||||
|
} catch (error) {
|
||||||
|
this.error = error.response?.data || 'Failed to fetch my favorites';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
clearComments() {
|
||||||
|
this.comments = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
clearRatings() {
|
||||||
|
this.ratings = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
clearLikes() {
|
||||||
|
this.likes = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
clearFavorites() {
|
||||||
|
this.favorites = [];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default InteractionStore;
|
||||||
139
frontend/src/stores/RegionStore.js
Normal file
139
frontend/src/stores/RegionStore.js
Normal file
@@ -0,0 +1,139 @@
|
|||||||
|
import { makeAutoObservable } from 'mobx';
|
||||||
|
import api from '../services/api';
|
||||||
|
|
||||||
|
class RegionStore {
|
||||||
|
regions = [];
|
||||||
|
currentRegion = null;
|
||||||
|
loading = false;
|
||||||
|
error = null;
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
makeAutoObservable(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
async fetchRegions() {
|
||||||
|
this.loading = true;
|
||||||
|
this.error = null;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const response = await api.get('/api/regions/');
|
||||||
|
this.regions = response.data;
|
||||||
|
} catch (error) {
|
||||||
|
this.error = error.response?.data || 'Failed to fetch regions';
|
||||||
|
} finally {
|
||||||
|
this.loading = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async fetchRegion(id) {
|
||||||
|
this.loading = true;
|
||||||
|
this.error = null;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const response = await api.get(`/api/regions/${id}/`);
|
||||||
|
this.currentRegion = response.data;
|
||||||
|
} catch (error) {
|
||||||
|
this.error = error.response?.data || 'Failed to fetch region';
|
||||||
|
} finally {
|
||||||
|
this.loading = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async fetchProvinces() {
|
||||||
|
this.loading = true;
|
||||||
|
this.error = null;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const response = await api.get('/api/regions/provinces/');
|
||||||
|
this.regions = response.data;
|
||||||
|
} catch (error) {
|
||||||
|
this.error = error.response?.data || 'Failed to fetch provinces';
|
||||||
|
} finally {
|
||||||
|
this.loading = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async fetchChildren(parentId) {
|
||||||
|
this.loading = true;
|
||||||
|
this.error = null;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const response = await api.get(`/api/regions/${parentId}/children/`);
|
||||||
|
return response.data;
|
||||||
|
} catch (error) {
|
||||||
|
this.error = error.response?.data || 'Failed to fetch children';
|
||||||
|
return [];
|
||||||
|
} finally {
|
||||||
|
this.loading = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async fetchRegionArticles(regionId) {
|
||||||
|
this.loading = true;
|
||||||
|
this.error = null;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const response = await api.get(`/api/regions/${regionId}/articles/`);
|
||||||
|
return response.data;
|
||||||
|
} catch (error) {
|
||||||
|
this.error = error.response?.data || 'Failed to fetch region articles';
|
||||||
|
return [];
|
||||||
|
} finally {
|
||||||
|
this.loading = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async fetchRegionServices(regionId) {
|
||||||
|
this.loading = true;
|
||||||
|
this.error = null;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const response = await api.get(`/api/regions/${regionId}/services/`);
|
||||||
|
return response.data;
|
||||||
|
} catch (error) {
|
||||||
|
this.error = error.response?.data || 'Failed to fetch region services';
|
||||||
|
return [];
|
||||||
|
} finally {
|
||||||
|
this.loading = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async rateRegion(regionId, score) {
|
||||||
|
try {
|
||||||
|
await api.post(`/api/regions/${regionId}/rate/`, { score });
|
||||||
|
return { success: true };
|
||||||
|
} catch (error) {
|
||||||
|
return {
|
||||||
|
success: false,
|
||||||
|
error: error.response?.data || 'Failed to rate region',
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async getRegionRating(regionId) {
|
||||||
|
try {
|
||||||
|
const response = await api.get(`/api/regions/${regionId}/my_rating/`);
|
||||||
|
return response.data.score;
|
||||||
|
} catch (error) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async favoriteRegion(regionId) {
|
||||||
|
try {
|
||||||
|
await api.post(`/api/regions/${regionId}/favorite/`);
|
||||||
|
return { success: true };
|
||||||
|
} catch (error) {
|
||||||
|
return {
|
||||||
|
success: false,
|
||||||
|
error: error.response?.data || 'Failed to favorite region',
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
clearCurrentRegion() {
|
||||||
|
this.currentRegion = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default RegionStore;
|
||||||
164
frontend/src/stores/ServiceStore.js
Normal file
164
frontend/src/stores/ServiceStore.js
Normal file
@@ -0,0 +1,164 @@
|
|||||||
|
import { makeAutoObservable } from 'mobx';
|
||||||
|
import api from '../services/api';
|
||||||
|
|
||||||
|
class ServiceStore {
|
||||||
|
services = [];
|
||||||
|
currentService = null;
|
||||||
|
loading = false;
|
||||||
|
error = null;
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
makeAutoObservable(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
async fetchServices(params = {}) {
|
||||||
|
this.loading = true;
|
||||||
|
this.error = null;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const response = await api.get('/api/services/', { params });
|
||||||
|
this.services = response.data.results || response.data;
|
||||||
|
} catch (error) {
|
||||||
|
this.error = error.response?.data || 'Failed to fetch services';
|
||||||
|
} finally {
|
||||||
|
this.loading = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async fetchService(id) {
|
||||||
|
this.loading = true;
|
||||||
|
this.error = null;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const response = await api.get(`/api/services/${id}/`);
|
||||||
|
this.currentService = response.data;
|
||||||
|
} catch (error) {
|
||||||
|
this.error = error.response?.data || 'Failed to fetch service';
|
||||||
|
} finally {
|
||||||
|
this.loading = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async createService(data) {
|
||||||
|
this.loading = true;
|
||||||
|
this.error = null;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const response = await api.post('/api/services/', data);
|
||||||
|
return { success: true, service: response.data };
|
||||||
|
} catch (error) {
|
||||||
|
this.error = error.response?.data || 'Failed to create service';
|
||||||
|
return { success: false, error: this.error };
|
||||||
|
} finally {
|
||||||
|
this.loading = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async updateService(id, data) {
|
||||||
|
this.loading = true;
|
||||||
|
this.error = null;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const response = await api.put(`/api/services/${id}/`, data);
|
||||||
|
return { success: true, service: response.data };
|
||||||
|
} catch (error) {
|
||||||
|
this.error = error.response?.data || 'Failed to update service';
|
||||||
|
return { success: false, error: this.error };
|
||||||
|
} finally {
|
||||||
|
this.loading = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async deleteService(id) {
|
||||||
|
try {
|
||||||
|
await api.delete(`/api/services/${id}/`);
|
||||||
|
return { success: true };
|
||||||
|
} catch (error) {
|
||||||
|
return {
|
||||||
|
success: false,
|
||||||
|
error: error.response?.data || 'Failed to delete service',
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async submitService(id) {
|
||||||
|
try {
|
||||||
|
await api.post(`/api/services/${id}/submit/`);
|
||||||
|
return { success: true };
|
||||||
|
} catch (error) {
|
||||||
|
return {
|
||||||
|
success: false,
|
||||||
|
error: error.response?.data || 'Failed to submit service',
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async approveService(id, reason = '') {
|
||||||
|
try {
|
||||||
|
await api.post(`/api/services/${id}/approve/`, { action: 'approve', reason });
|
||||||
|
return { success: true };
|
||||||
|
} catch (error) {
|
||||||
|
return {
|
||||||
|
success: false,
|
||||||
|
error: error.response?.data || 'Failed to approve service',
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async rejectService(id, reason) {
|
||||||
|
try {
|
||||||
|
await api.post(`/api/services/${id}/reject/`, { action: 'reject', reason });
|
||||||
|
return { success: true };
|
||||||
|
} catch (error) {
|
||||||
|
return {
|
||||||
|
success: false,
|
||||||
|
error: error.response?.data || 'Failed to reject service',
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async likeService(id) {
|
||||||
|
try {
|
||||||
|
const response = await api.post(`/api/services/${id}/like/`);
|
||||||
|
return response.data;
|
||||||
|
} catch (error) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async rateService(id, score) {
|
||||||
|
try {
|
||||||
|
await api.post(`/api/services/${id}/rate/`, { score });
|
||||||
|
return { success: true };
|
||||||
|
} catch (error) {
|
||||||
|
return {
|
||||||
|
success: false,
|
||||||
|
error: error.response?.data || 'Failed to rate service',
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async fetchServiceComments(id) {
|
||||||
|
try {
|
||||||
|
const response = await api.get(`/api/services/${id}/comments/`);
|
||||||
|
return response.data;
|
||||||
|
} catch (error) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async fetchServiceStats(id) {
|
||||||
|
try {
|
||||||
|
const response = await api.get(`/api/services/${id}/stats/`);
|
||||||
|
return response.data;
|
||||||
|
} catch (error) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
clearCurrentService() {
|
||||||
|
this.currentService = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default ServiceStore;
|
||||||
Reference in New Issue
Block a user