From f30502bf7d24eceee9b27adfd54024cf9d6f9348 Mon Sep 17 00:00:00 2001 From: jingrow Date: Sun, 4 Jan 2026 21:23:29 +0800 Subject: [PATCH] fix(settings): fix disable account API and add feedback dialog - Fix disable account API parameter format (pass null instead of empty object) - Add feedback dialog after account disable (aligned with jcloud dashboard) - Implement star rating, reason selection, and feedback submission - Add submitFeedback API function - Add missing Chinese translations for account status messages - Add feedback dialog translations and validation logic --- src/locales/zh-CN.json | 25 ++++- src/shared/api/account.ts | 29 ++++- src/views/settings/Settings.vue | 188 +++++++++++++++++++++++++++++++- 3 files changed, 239 insertions(+), 3 deletions(-) diff --git a/src/locales/zh-CN.json b/src/locales/zh-CN.json index 1ee86f6..aa8600f 100644 --- a/src/locales/zh-CN.json +++ b/src/locales/zh-CN.json @@ -1296,6 +1296,10 @@ "Change your account login password": "更改您的账户登录密码", "Disable Account": "禁用账户", "Enable Account": "启用账户", + "Your account has been disabled successfully": "您的账户已成功禁用", + "Failed to disable account": "禁用账户失败", + "Your account has been enabled successfully": "您的账户已成功启用", + "Failed to enable account": "启用账户失败", "Disable your account and stop billing": "禁用您的账户并停止计费", "Enable your account and resume billing": "启用您的账户并恢复计费", "After confirming this action:": "确认此操作后:", @@ -1329,6 +1333,7 @@ "Tip: Password should contain symbols, numbers and uppercase letters": "提示:密码应包含符号、数字和大写字母", "Password updated successfully": "密码更新成功", "Your password has been updated": "您的密码已更新", + "Profile updated successfully": "个人资料更新成功", "Current password is incorrect": "当前密码不正确", "Setting you as a developer...": "正在将您设置为开发者...", "You can now publish apps to our marketplace": "您现在可以在我们的应用市场发布应用了", @@ -1357,5 +1362,23 @@ "Failed to disable two-factor authentication": "禁用双因素认证失败", "Failed to load QR code": "加载二维码失败", "Enabling two-factor authentication...": "正在启用双因素认证...", - "Disabling two-factor authentication...": "正在禁用双因素认证..." + "Disabling two-factor authentication...": "正在禁用双因素认证...", + "Tell us why you are leaving": "告诉我们您离开的原因", + "By sharing your thoughts, help us improve your experience.": "通过分享您的想法,帮助我们改善您的体验。", + "Please rate your experience": "请评价您的体验", + "Select a reason": "选择一个原因", + "The reason I am leaving Jingrow is...": "我离开 Jingrow 的原因是...", + "我要迁移到其他产品": "我要迁移到其他产品", + "我只是在探索这个产品": "我只是在探索这个产品", + "我更喜欢自己托管实例": "我更喜欢自己托管实例", + "已将站点迁移到另一个Jingrow账户": "已将站点迁移到另一个Jingrow账户", + "我不喜欢Jingrow的体验": "我不喜欢Jingrow的体验", + "Jingrow对我来说太贵了": "Jingrow对我来说太贵了", + "支付问题": "支付问题", + "缺少功能": "缺少功能", + "我的原因不在此列表中": "我的原因不在此列表中", + "请选择一个原因": "请选择一个原因", + "请评价您的体验": "请评价您的体验", + "请简要说明原因": "请简要说明原因", + "Your feedback has been submitted successfully": "您的反馈已成功提交" } diff --git a/src/shared/api/account.ts b/src/shared/api/account.ts index d9ddc92..3c24053 100644 --- a/src/shared/api/account.ts +++ b/src/shared/api/account.ts @@ -291,7 +291,7 @@ export const disableAccount = async (totpCode?: string): Promise<{ success: bool try { const response = await axios.post( `/api/action/jcloud.api.account.disable_account`, - totpCode ? { totp_code: totpCode } : {}, + { totp_code: totpCode || null }, { headers: get_session_api_headers(), withCredentials: true @@ -552,3 +552,30 @@ export const disable2FA = async (totpCode: string): Promise<{ success: boolean; } } } + +// 提交反馈 +export const submitFeedback = async (team: string, message: string, note: string, rating: number, route?: string): Promise<{ success: boolean; message?: string }> => { + try { + const response = await axios.post( + `/api/action/jcloud.api.account.feedback`, + { + team, + message, + note, + rating, + route: route || null + }, + { + headers: get_session_api_headers(), + withCredentials: true + } + ) + + return { success: true, message: response.data?.message || '反馈已提交' } + } catch (error: any) { + return { + success: false, + message: error.response?.data?.detail || error.response?.data?.message || error.message || '提交反馈失败' + } + } +} diff --git a/src/views/settings/Settings.vue b/src/views/settings/Settings.vue index 357315e..a8a3317 100644 --- a/src/views/settings/Settings.vue +++ b/src/views/settings/Settings.vue @@ -820,6 +820,85 @@

{{ t('Do you want to continue?') }}

+ + + + +

+ {{ t('By sharing your thoughts, help us improve your experience.') }} +

+ + +
+ + {{ t('Please rate your experience') }} + +
+ + + + + +
+
+ + + + + + + + + + + + + +
+ + +
@@ -880,7 +959,8 @@ import { getPartnerName, get2FAQRCodeUrl, enable2FA, - disable2FA + disable2FA, + submitFeedback } from '../../shared/api/account' import ClickToCopyField from '../../shared/components/ClickToCopyField.vue' @@ -1000,6 +1080,15 @@ const showEnableAccountDialog = ref(false) const disableAccountLoading = ref(false) const enableAccountLoading = ref(false) +// 反馈对话框 +const showFeedbackDialog = ref(false) +const feedbackRating = ref(0) +const feedbackReason = ref('') +const feedbackNote = ref('') +const feedbackLoading = ref(false) +const feedbackError = ref('') +const hoveredRating = ref(0) + // API Secret 相关 const showCreateSecretDialog = ref(false) const createSecretData = ref<{ api_key: string; api_secret: string } | null>(null) @@ -1678,6 +1767,8 @@ const handleDisableAccountConfirm = async () => { message.success(t('Your account has been disabled successfully')) showDisableAccountDialog.value = false await loadUserAccountInfo() + // 显示反馈对话框 + showFeedbackDialog.value = true } else { message.error(result.message || t('Failed to disable account')) } @@ -1686,6 +1777,84 @@ const handleDisableAccountConfirm = async () => { } } +// 反馈原因选项 +const feedbackReasons = [ + t('我要迁移到其他产品'), + t('我只是在探索这个产品'), + t('我更喜欢自己托管实例'), + t('已将站点迁移到另一个Jingrow账户'), + t('我不喜欢Jingrow的体验'), + t('Jingrow对我来说太贵了'), + t('支付问题'), + t('缺少功能'), + t('我的原因不在此列表中') +] + +// 提交反馈 +const handleSubmitFeedback = async () => { + // 验证 + if (!feedbackReason.value) { + feedbackError.value = t('请选择一个原因') + return + } + + if (feedbackRating.value === 0) { + feedbackError.value = t('请评价您的体验') + return + } + + const requiresNote = [ + t('支付问题'), + t('缺少功能'), + t('我的原因不在此列表中') + ].includes(feedbackReason.value) + + if (requiresNote && !feedbackNote.value) { + feedbackError.value = t('请简要说明原因') + return + } + + feedbackLoading.value = true + feedbackError.value = '' + + try { + const result = await submitFeedback( + teamInfo.value?.name || '', + feedbackReason.value, + feedbackNote.value, + feedbackRating.value + ) + + if (result.success) { + message.success(t('Your feedback has been submitted successfully')) + showFeedbackDialog.value = false + // 重置表单 + feedbackRating.value = 0 + feedbackReason.value = '' + feedbackNote.value = '' + // 延迟跳转 + setTimeout(() => { + window.location.href = '/dashboard' + }, 1000) + } else { + feedbackError.value = result.message || t('提交反馈失败') + } + } catch (error: any) { + feedbackError.value = error.message || t('提交反馈失败') + } finally { + feedbackLoading.value = false + } +} + +// 关闭反馈对话框 +const closeFeedbackDialog = () => { + showFeedbackDialog.value = false + feedbackRating.value = 0 + feedbackReason.value = '' + feedbackNote.value = '' + feedbackError.value = '' +} + // 确认启用账户 const handleEnableAccountConfirm = async () => { enableAccountLoading.value = true @@ -2168,6 +2337,23 @@ onMounted(async () => { margin-top: 0; } +/* 星级评分样式 */ +.star-rating { + display: flex; + gap: 4px; + align-items: center; +} + +.star-rating-star { + display: inline-block; + cursor: pointer; + transition: transform 0.1s; +} + +.star-rating-star:hover { + transform: scale(1.1); +} + /* 响应式设计 */ @media (max-width: 1200px) { .settings-page :deep(.n-grid) {