feat: 完善对象存储上传与真实条码二维码引擎,彻底剥离保底Mock数据
这个提交包含在:
@@ -0,0 +1,111 @@
|
||||
import { OrderStatus } from '../order/order-state-machine';
|
||||
|
||||
export interface OrderReviewInput {
|
||||
orderId: string;
|
||||
orderStatus: OrderStatus;
|
||||
expertId: number;
|
||||
userId: number;
|
||||
userNickname: string;
|
||||
rating: number;
|
||||
tags?: string[];
|
||||
content?: string;
|
||||
}
|
||||
|
||||
export interface ReviewRecord {
|
||||
id: string;
|
||||
orderId: string;
|
||||
expertId: number;
|
||||
userId: number;
|
||||
userNickname: string;
|
||||
rating: number;
|
||||
tags: string[];
|
||||
content: string;
|
||||
createdAt: string;
|
||||
}
|
||||
|
||||
export interface PostCommentInput {
|
||||
postId: string;
|
||||
userId: number;
|
||||
author: string;
|
||||
content: string;
|
||||
}
|
||||
|
||||
export interface CommentRecord {
|
||||
id: string;
|
||||
postId: string;
|
||||
userId: number;
|
||||
author: string;
|
||||
content: string;
|
||||
createdAt: string;
|
||||
}
|
||||
|
||||
export class ReviewAndCommentService {
|
||||
private reviews: ReviewRecord[] = [];
|
||||
private comments: CommentRecord[] = [];
|
||||
|
||||
submitOrderReview(input: OrderReviewInput): ReviewRecord {
|
||||
if (input.orderStatus !== OrderStatus.COMPLETED) {
|
||||
throw new Error('只有已完成(COMPLETED)状态的订单才允许提交服务评价');
|
||||
}
|
||||
|
||||
if (!input.rating || input.rating < 1 || input.rating > 5) {
|
||||
throw new Error('评分必须在 1 至 5 星之间');
|
||||
}
|
||||
|
||||
const exists = this.reviews.some(r => r.orderId === input.orderId);
|
||||
if (exists) {
|
||||
throw new Error('该订单已评价,不可重复提交评价');
|
||||
}
|
||||
|
||||
const review: ReviewRecord = {
|
||||
id: `rev_${Date.now()}_${Math.floor(100 + Math.random() * 900)}`,
|
||||
orderId: input.orderId,
|
||||
expertId: input.expertId,
|
||||
userId: input.userId,
|
||||
userNickname: input.userNickname || '买家用户',
|
||||
rating: Math.floor(input.rating),
|
||||
tags: input.tags || [],
|
||||
content: input.content || '好评!',
|
||||
createdAt: new Date().toISOString()
|
||||
};
|
||||
|
||||
this.reviews.push(review);
|
||||
return review;
|
||||
}
|
||||
|
||||
getReviewsByExpert(expertId: number): ReviewRecord[] {
|
||||
return this.reviews.filter(r => r.expertId === expertId);
|
||||
}
|
||||
|
||||
calculateExpertAverageRating(expertId: number, baseRating: number = 5.0): number {
|
||||
const list = this.getReviewsByExpert(expertId);
|
||||
if (list.length === 0) return baseRating;
|
||||
const total = list.reduce((sum, item) => sum + item.rating, 0);
|
||||
return Number((total / list.length).toFixed(2));
|
||||
}
|
||||
|
||||
submitPostComment(input: PostCommentInput): CommentRecord {
|
||||
if (!input.content || !input.content.trim()) {
|
||||
throw new Error('评论内容不能为空');
|
||||
}
|
||||
if (input.content.trim().length > 500) {
|
||||
throw new Error('评论内容不能超过 500 个字符');
|
||||
}
|
||||
|
||||
const comment: CommentRecord = {
|
||||
id: `cmt_${Date.now()}_${Math.floor(100 + Math.random() * 900)}`,
|
||||
postId: input.postId,
|
||||
userId: input.userId,
|
||||
author: input.author || '热心搭子',
|
||||
content: input.content.trim(),
|
||||
createdAt: new Date().toISOString()
|
||||
};
|
||||
|
||||
this.comments.push(comment);
|
||||
return comment;
|
||||
}
|
||||
|
||||
getCommentsByPost(postId: string): CommentRecord[] {
|
||||
return this.comments.filter(c => c.postId === postId);
|
||||
}
|
||||
}
|
||||
在新工单中引用
屏蔽一个用户