feat(feedback): implement user feedback collection system with email reporting

Backend:
- Add user_feedback table with RLS policy
- Create feedback submission API (multipart/form-data)
- Implement xlsx report generation with embedded images
- Add scheduled email delivery via Feishu SMTP
- Create HTML email templates (daily_report, no_feedback)

Frontend:
- Add feedback screen with type selection and image picker
- Support anonymous submission via skipAuth flag
- Collect device info and app version

Protocol:
- Document feedback API contract and error codes
- Update http-error-codes.md with FEEDBACK_* codes
This commit is contained in:
qzl
2026-04-20 12:49:54 +08:00
parent 913ed26f8d
commit 6a2a9d2c87
46 changed files with 4768 additions and 9 deletions
+58
View File
@@ -1224,4 +1224,62 @@ class AppLocalizationsEn extends AppLocalizations {
@override
String get settingsDoNotSellDisabled => 'On';
@override
String get settingsFeedbackTitle => 'Feedback';
@override
String get feedbackTitle => 'Feedback';
@override
String get feedbackTypeLabel => 'Feedback Type';
@override
String get feedbackTypeBug => 'Bug';
@override
String get feedbackTypeSuggestion => 'Suggestion';
@override
String get feedbackTypeOther => 'Other';
@override
String get feedbackContentLabel => 'Content';
@override
String get feedbackContentHint =>
'Please describe your issue or suggestion in detail...';
@override
String get feedbackImagesLabel => 'Add Screenshots (max 3)';
@override
String get feedbackAnonymousLabel => 'Do not upload my personal information';
@override
String get feedbackAnonymousHint =>
'If checked, your user ID will not be collected. Device info will still be collected for troubleshooting.';
@override
String get feedbackSubmit => 'Submit Feedback';
@override
String get feedbackSubmitting => 'Submitting...';
@override
String get feedbackSuccess =>
'Thank you for your feedback. We will process it soon.';
@override
String get feedbackContentRequired => 'Please enter feedback content';
@override
String get feedbackContentTooLong =>
'Feedback content cannot exceed 500 characters';
@override
String get feedbackTooManyImages => 'Maximum 3 images allowed';
@override
String get feedbackImageTooLarge => 'Image size cannot exceed 5MB';
}