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
This commit is contained in:
parent
79b92e7aae
commit
f30502bf7d
@ -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": "您的反馈已成功提交"
|
||||
}
|
||||
|
||||
@ -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 || '提交反馈失败'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -820,6 +820,85 @@
|
||||
<p class="account-status-dialog-text">{{ t('Do you want to continue?') }}</p>
|
||||
</div>
|
||||
</n-modal>
|
||||
|
||||
<!-- 反馈对话框 -->
|
||||
<n-modal
|
||||
v-model:show="showFeedbackDialog"
|
||||
preset="card"
|
||||
:title="t('Tell us why you are leaving')"
|
||||
:style="{ width: '600px' }"
|
||||
:mask-closable="false"
|
||||
:close-on-esc="false"
|
||||
>
|
||||
<n-space vertical :size="20">
|
||||
<p class="text-sm text-gray-800">
|
||||
{{ t('By sharing your thoughts, help us improve your experience.') }}
|
||||
</p>
|
||||
|
||||
<!-- 星级评分 -->
|
||||
<div>
|
||||
<span class="block text-sm leading-4 text-gray-600 mb-2">
|
||||
{{ t('Please rate your experience') }}
|
||||
</span>
|
||||
<div class="star-rating">
|
||||
<span
|
||||
v-for="rating in [1, 2, 3, 4, 5]"
|
||||
:key="rating"
|
||||
class="star-rating-star"
|
||||
@click="feedbackRating = rating"
|
||||
@mouseenter="hoveredRating = rating"
|
||||
@mouseleave="hoveredRating = 0"
|
||||
>
|
||||
<n-icon :size="20">
|
||||
<Icon
|
||||
:icon="(hoveredRating || feedbackRating) >= rating ? 'tabler:star-filled' : 'tabler:star'"
|
||||
:style="{ color: (hoveredRating || feedbackRating) >= rating ? '#ECAC4B' : '#C0C6CC' }"
|
||||
/>
|
||||
</n-icon>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 原因选择 -->
|
||||
<n-form-item :label="t('Select a reason')" required>
|
||||
<n-select
|
||||
v-model:value="feedbackReason"
|
||||
:options="feedbackReasons.map(r => ({ label: r, value: r }))"
|
||||
:placeholder="t('Select a reason')"
|
||||
/>
|
||||
</n-form-item>
|
||||
|
||||
<!-- 详细说明 -->
|
||||
<n-form-item :label="t('The reason I am leaving Jingrow is...')">
|
||||
<n-input
|
||||
v-model:value="feedbackNote"
|
||||
type="textarea"
|
||||
:rows="4"
|
||||
:placeholder="t('The reason I am leaving Jingrow is...')"
|
||||
/>
|
||||
</n-form-item>
|
||||
|
||||
<!-- 错误提示 -->
|
||||
<n-alert
|
||||
v-if="feedbackError"
|
||||
type="error"
|
||||
:title="feedbackError"
|
||||
/>
|
||||
</n-space>
|
||||
|
||||
<template #footer>
|
||||
<n-space justify="end">
|
||||
<n-button @click="closeFeedbackDialog">{{ t('Cancel') }}</n-button>
|
||||
<n-button
|
||||
type="primary"
|
||||
:loading="feedbackLoading"
|
||||
@click="handleSubmitFeedback"
|
||||
>
|
||||
{{ t('Submit') }}
|
||||
</n-button>
|
||||
</n-space>
|
||||
</template>
|
||||
</n-modal>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@ -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) {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user