fix: 首页我的计划点击跳转错页 + feat: 新增留言反馈功能
fix: - 首页'我的计划'卡片误绑 onExercise(跳动作详情),改为 onPlanTap 正确跳训练计划详情页 - 修复后点击计划可正常打开 plan-detail feat(留言反馈): - 后端新增 feedback 模块:POST /api/feedback(AuthGuard,content 必填/contact 选填),JsonStore 持久化 - 前端新增 pages/feedback 页面(留言内容 textarea + 联系方式选填 + 提交),profile 菜单新增'意见反馈'入口 - icon-svg 新增 message-circle 图标(反馈页用)
This commit is contained in:
@@ -7,6 +7,7 @@ import { AuthModule } from './auth/auth.module';
|
||||
import { UsersModule } from './users/users.module';
|
||||
import { FavoritesModule } from './favorites/favorites.module';
|
||||
import { PlansModule } from './plans/plans.module';
|
||||
import { FeedbackModule } from './feedback/feedback.module';
|
||||
|
||||
// 若 backend/media 目录存在(放有 images/ 与 videos/),则通过 /media 暴露静态资源
|
||||
const mediaDir = path.join(__dirname, '..', 'media');
|
||||
@@ -21,6 +22,7 @@ const staticImports = fs.existsSync(mediaDir)
|
||||
UsersModule,
|
||||
FavoritesModule,
|
||||
PlansModule,
|
||||
FeedbackModule,
|
||||
...staticImports,
|
||||
],
|
||||
})
|
||||
|
||||
31
backend/src/feedback/feedback.controller.ts
Normal file
31
backend/src/feedback/feedback.controller.ts
Normal file
@@ -0,0 +1,31 @@
|
||||
import { Body, Controller, Post, UseGuards } from '@nestjs/common';
|
||||
import { FeedbackService } from './feedback.service';
|
||||
import { AuthGuard } from '../common/auth.guard';
|
||||
import { CurrentUser } from '../common/current-user.decorator';
|
||||
import { IsOptional, IsString, MaxLength, MinLength } from 'class-validator';
|
||||
|
||||
class FeedbackBody {
|
||||
@IsString()
|
||||
@MinLength(1, { message: '留言内容不能为空' })
|
||||
@MaxLength(1000, { message: '留言内容不能超过 1000 字' })
|
||||
content: string;
|
||||
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
@MaxLength(100, { message: '联系方式不能超过 100 字' })
|
||||
contact?: string;
|
||||
}
|
||||
|
||||
@Controller('api/feedback')
|
||||
@UseGuards(AuthGuard)
|
||||
export class FeedbackController {
|
||||
constructor(private readonly svc: FeedbackService) {}
|
||||
|
||||
@Post()
|
||||
submit(
|
||||
@CurrentUser() u: { openid: string },
|
||||
@Body() body: FeedbackBody,
|
||||
) {
|
||||
return this.svc.submit(u.openid, body.content, body.contact);
|
||||
}
|
||||
}
|
||||
9
backend/src/feedback/feedback.module.ts
Normal file
9
backend/src/feedback/feedback.module.ts
Normal file
@@ -0,0 +1,9 @@
|
||||
import { Module } from '@nestjs/common';
|
||||
import { FeedbackService } from './feedback.service';
|
||||
import { FeedbackController } from './feedback.controller';
|
||||
|
||||
@Module({
|
||||
controllers: [FeedbackController],
|
||||
providers: [FeedbackService],
|
||||
})
|
||||
export class FeedbackModule {}
|
||||
33
backend/src/feedback/feedback.service.ts
Normal file
33
backend/src/feedback/feedback.service.ts
Normal file
@@ -0,0 +1,33 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { randomUUID } from 'crypto';
|
||||
import { getStore } from '../common/store';
|
||||
|
||||
export interface Feedback {
|
||||
id: string;
|
||||
openid: string;
|
||||
content: string;
|
||||
contact?: string;
|
||||
createdAt: string;
|
||||
}
|
||||
|
||||
@Injectable()
|
||||
export class FeedbackService {
|
||||
private store = getStore<Feedback>('feedback');
|
||||
|
||||
submit(openid: string, content: string, contact?: string): Feedback {
|
||||
return this.store.insert({
|
||||
id: randomUUID(),
|
||||
openid,
|
||||
content,
|
||||
contact: contact || undefined,
|
||||
createdAt: new Date().toISOString(),
|
||||
});
|
||||
}
|
||||
|
||||
// 管理员视角:按时间倒序返回全部留言
|
||||
list(): Feedback[] {
|
||||
return this.store
|
||||
.all()
|
||||
.sort((a, b) => (a.createdAt < b.createdAt ? 1 : -1));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user