Quellcode durchsuchen

Add account cancellation feature and update localization

- Implemented the account cancellation API in the user API, allowing users to destroy their accounts.
- Enhanced the cancellation page to integrate the account cancellation functionality, providing feedback on success or failure.
- Updated localization files for English, Indonesian, and Chinese to include success and failure messages for account cancellation, improving user experience.
0es vor 3 Monaten
Ursprung
Commit
b5ad086ddd
5 geänderte Dateien mit 46 neuen und 8 gelöschten Zeilen
  1. 14 0
      app/api/user.ts
  2. 23 5
      app/pages/mine/cancellation.vue
  3. 3 1
      i18n/locales/en.json
  4. 3 1
      i18n/locales/id.json
  5. 3 1
      i18n/locales/zh.json

+ 14 - 0
app/api/user.ts

@@ -68,6 +68,20 @@ export const userApi = {
     return http.post<object>('/user/logout')
   },
 
+  /**
+   * Account cancellation / destroy
+   * 对应后端接口:POST /user/destroy
+   * 按后端要求使用 application/x-www-form-urlencoded
+   * 注意:暂不传递额外的 body 参数(仅前端展示)
+   */
+  destroy() {
+    return http.post<object>('/user/destroy', undefined, {
+      headers: {
+        'Content-Type': 'application/x-www-form-urlencoded',
+      },
+    })
+  },
+
   /**
    * Renew token - refresh authentication token
    * @returns Token renewal response

+ 23 - 5
app/pages/mine/cancellation.vue

@@ -2,6 +2,7 @@
 import { computed, ref } from 'vue'
 import { showToast } from 'vant'
 import ConfirmDialog from '~/components/common/ConfirmDialog.vue'
+import { userApi } from '~/api/user'
 
 definePageMeta({
   auth: true,
@@ -12,11 +13,13 @@ type CancellationReason = 'noNeed' | 'privacy' | 'experience' | 'other'
 const router = useRouter()
 const route = useRoute()
 const { t } = useI18n()
+const { logout } = useAuth()
 
 const reason = ref<CancellationReason>('noNeed')
 const otherReason = ref('')
 const acknowledged = ref(false)
 const confirmVisible = ref(false)
+const destroying = ref(false)
 
 const isOther = computed(() => reason.value === 'other')
 const canSubmit = computed(() => {
@@ -43,11 +46,26 @@ const handleClickSubmit = () => {
 }
 
 const handleConfirm = async () => {
-  // TODO: Integrate account cancellation API later.
-  showToast(t('mine.cancellation.toast.placeholderSuccess'))
-  setTimeout(() => {
-    router.back()
-  }, 500)
+  if (destroying.value)
+    return
+
+  try {
+    destroying.value = true
+
+    // NOTE: Do NOT send extra params for now (only frontend display).
+    await userApi.destroy()
+
+    showToast(t('mine.cancellation.toast.success'))
+    logout()
+    router.replace('/')
+  }
+  catch (error) {
+    console.error('Failed to destroy account:', error)
+    showToast(t('mine.cancellation.toast.failed'))
+  }
+  finally {
+    destroying.value = false
+  }
 }
 </script>
 

+ 3 - 1
i18n/locales/en.json

@@ -219,7 +219,9 @@
       },
       "toast": {
         "needAcknowledge": "Please check the confirmation box first",
-        "placeholderSuccess": "Cancellation submitted (API integration pending)"
+        "placeholderSuccess": "Cancellation submitted (API integration pending)",
+        "success": "Cancellation successful",
+        "failed": "Cancellation failed, please try again later"
       }
     }
   },

+ 3 - 1
i18n/locales/id.json

@@ -220,7 +220,9 @@
       },
       "toast": {
         "needAcknowledge": "Silakan centang kotak konfirmasi terlebih dahulu",
-        "placeholderSuccess": "Pembatalan terkirim (integrasi API belum tersedia)"
+        "placeholderSuccess": "Pembatalan terkirim (integrasi API belum tersedia)",
+        "success": "Pembatalan berhasil",
+        "failed": "Pembatalan gagal, silakan coba lagi nanti"
       }
     }
   },

+ 3 - 1
i18n/locales/zh.json

@@ -220,7 +220,9 @@
       },
       "toast": {
         "needAcknowledge": "请先勾选确认事项",
-        "placeholderSuccess": "已提交注销申请(接口待接入)"
+        "placeholderSuccess": "已提交注销申请(接口待接入)",
+        "success": "注销成功",
+        "failed": "注销失败,请稍后重试"
       }
     }
   },