Browse Source

client:iOS 打开会员充值入口,资料保存不再被默认昵称整单拒绝。

iOS 的会员卡片、额度不足弹窗和支付方式走 Apple 内购;昵称未改时不再连同头像、性别一起提交。

Co-authored-by: Cursor <cursoragent@cursor.com>
along
Rodger-Wang 23 hours ago
parent
commit
ef31a9ffcc
  1. 3
      apps/client/lib/core/translations/language/ar_sa.dart
  2. 3
      apps/client/lib/core/translations/language/bg_bg.dart
  3. 3
      apps/client/lib/core/translations/language/cs_cz.dart
  4. 3
      apps/client/lib/core/translations/language/da_dk.dart
  5. 3
      apps/client/lib/core/translations/language/de_de.dart
  6. 3
      apps/client/lib/core/translations/language/el_gr.dart
  7. 3
      apps/client/lib/core/translations/language/en_us.dart
  8. 3
      apps/client/lib/core/translations/language/es_es.dart
  9. 3
      apps/client/lib/core/translations/language/et_ee.dart
  10. 3
      apps/client/lib/core/translations/language/fa_ir.dart
  11. 3
      apps/client/lib/core/translations/language/fi_fi.dart
  12. 3
      apps/client/lib/core/translations/language/fr_fr.dart
  13. 3
      apps/client/lib/core/translations/language/hi_in.dart
  14. 3
      apps/client/lib/core/translations/language/hr_hr.dart
  15. 3
      apps/client/lib/core/translations/language/hu_hu.dart
  16. 3
      apps/client/lib/core/translations/language/id_id.dart
  17. 3
      apps/client/lib/core/translations/language/is_is.dart
  18. 3
      apps/client/lib/core/translations/language/it_it.dart
  19. 3
      apps/client/lib/core/translations/language/ja_jp.dart
  20. 3
      apps/client/lib/core/translations/language/ko_kr.dart
  21. 3
      apps/client/lib/core/translations/language/lt_lt.dart
  22. 3
      apps/client/lib/core/translations/language/lv_lv.dart
  23. 3
      apps/client/lib/core/translations/language/ms_my.dart
  24. 3
      apps/client/lib/core/translations/language/nb_no.dart
  25. 3
      apps/client/lib/core/translations/language/nl_nl.dart
  26. 3
      apps/client/lib/core/translations/language/pl_pl.dart
  27. 3
      apps/client/lib/core/translations/language/pt_pt.dart
  28. 3
      apps/client/lib/core/translations/language/ro_ro.dart
  29. 3
      apps/client/lib/core/translations/language/ru_ru.dart
  30. 3
      apps/client/lib/core/translations/language/sk_sk.dart
  31. 3
      apps/client/lib/core/translations/language/sl_si.dart
  32. 3
      apps/client/lib/core/translations/language/sr_rs.dart
  33. 3
      apps/client/lib/core/translations/language/sv_se.dart
  34. 3
      apps/client/lib/core/translations/language/th_th.dart
  35. 3
      apps/client/lib/core/translations/language/tl_ph.dart
  36. 3
      apps/client/lib/core/translations/language/tr_tr.dart
  37. 3
      apps/client/lib/core/translations/language/uk_ua.dart
  38. 3
      apps/client/lib/core/translations/language/vi_vn.dart
  39. 3
      apps/client/lib/core/translations/language/zh_cn.dart
  40. 3
      apps/client/lib/core/translations/language/zh_hk.dart
  41. 3
      apps/client/lib/core/translations/language/zh_tw.dart
  42. 4
      apps/client/lib/core/utils/app_features.dart
  43. 7
      apps/client/lib/modules/common/widgets/recharge_dialog.dart
  44. 12
      apps/client/lib/modules/goods/controllers/goods_base_controller.dart
  45. 7
      apps/client/lib/modules/goods/controllers/goodsvip_controller.dart
  46. 94
      apps/client/lib/modules/goods/views/goodsvip_view.dart
  47. 52
      apps/client/lib/modules/profile/controllers/profile_controller.dart
  48. 111
      apps/client/lib/modules/settings/views/settings_view.dart

3
apps/client/lib/core/translations/language/ar_sa.dart

@ -800,6 +800,9 @@ const Map<String, String> arSA = {
// 设置页
"systemSettings": "إعدادات النظام",
"vipRecharge": "شحن العضوية",
"vipMonth": "Monthly VIP",
"vipQuarter": "Quarterly VIP",
"vipLifetime": "Lifetime VIP",
"aiRecharge": "شحن AI",
"translationRecharge": "شحن الترجمة",
"meetingAssistantRecharge": "شحن الاجتماع",

3
apps/client/lib/core/translations/language/bg_bg.dart

@ -820,6 +820,9 @@ const Map<String, String> bgBG = {
// 设置页
"systemSettings": "Системни настройки",
"vipRecharge": "Преплащане за VIP член",
"vipMonth": "Monthly VIP",
"vipQuarter": "Quarterly VIP",
"vipLifetime": "Lifetime VIP",
"aiRecharge": "Премиум член",
"translationRecharge": "Преплащане за превод",
"meetingAssistantRecharge": "Преплащане за Сообщението",

3
apps/client/lib/core/translations/language/cs_cz.dart

@ -809,6 +809,9 @@ const Map<String, String> csCZ = {
// 设置页
"systemSettings": "Systémová nastavení",
"vipRecharge": "Přepayka VIP členství",
"vipMonth": "Monthly VIP",
"vipQuarter": "Quarterly VIP",
"vipLifetime": "Lifetime VIP",
"aiRecharge": "Prémiový člen",
"translationRecharge": "Přepayka překladu",
"meetingAssistantRecharge": "Přepayka asistenta schůzky",

3
apps/client/lib/core/translations/language/da_dk.dart

@ -812,6 +812,9 @@ const Map<String, String> daDK = {
// 设置页
"systemSettings": "Systemindstillinger",
"vipRecharge": "Opladning af VIP medlem",
"vipMonth": "Monthly VIP",
"vipQuarter": "Quarterly VIP",
"vipLifetime": "Lifetime VIP",
"aiRecharge": "Premium medlem",
"translationRecharge": "Opladning af oversetning",
"meetingAssistantRecharge": "Opladning af mødeassistent",

3
apps/client/lib/core/translations/language/de_de.dart

@ -827,6 +827,9 @@ const Map<String, String> deDE = {
// 设置页
"systemSettings": "Systemeinstellungen",
"vipRecharge": "VIP-Mitgliedschaft-Recharge",
"vipMonth": "Monthly VIP",
"vipQuarter": "Quarterly VIP",
"vipLifetime": "Lifetime VIP",
"aiRecharge": "Premium-Mitgliedschaft",
"translationRecharge": "Übersetzungs-Recharge",
"meetingAssistantRecharge": "Meeting-Assistent-Recharge",

3
apps/client/lib/core/translations/language/el_gr.dart

@ -830,6 +830,9 @@ const Map<String, String> elGR = {
// 设置页
"systemSettings": "Ρυθμίσεις συστήματος",
"vipRecharge": "Περιορέωση VIP μέλους",
"vipMonth": "Monthly VIP",
"vipQuarter": "Quarterly VIP",
"vipLifetime": "Lifetime VIP",
"aiRecharge": "Premium μέλος",
"translationRecharge": "Περιορέωση μετάφρασης",
"meetingAssistantRecharge": "Περιορέωση βοηθού συνάντησης",

3
apps/client/lib/core/translations/language/en_us.dart

@ -833,6 +833,9 @@ const Map<String, String> enUS = {
// 设置页
"systemSettings": "System Settings", //系统设置
"vipRecharge": "VIP Recharge", //会员充值
"vipMonth": "Monthly VIP",
"vipQuarter": "Quarterly VIP",
"vipLifetime": "Lifetime VIP",
"aiRecharge": "AI Recharge", //AI充值
"translationRecharge": "Translation Recharge", //翻译充值
"meetingAssistantRecharge": "Meeting Recharge", //会议充值

3
apps/client/lib/core/translations/language/es_es.dart

@ -825,6 +825,9 @@ const Map<String, String> esES = {
// 设置页
"systemSettings": "Configuración del sistema",
"vipRecharge": "Recarga de VIP",
"vipMonth": "Monthly VIP",
"vipQuarter": "Quarterly VIP",
"vipLifetime": "Lifetime VIP",
"aiRecharge": "Miembro premium",
"translationRecharge": "Recarga de traducción",
"meetingAssistantRecharge": "Recarga de asistente de reunión",

3
apps/client/lib/core/translations/language/et_ee.dart

@ -816,6 +816,9 @@ const Map<String, String> etEE = {
// 设置页
"systemSettings": "Süsteemi seaded",
"vipRecharge": "VIP liige varundus",
"vipMonth": "Monthly VIP",
"vipQuarter": "Quarterly VIP",
"vipLifetime": "Lifetime VIP",
"aiRecharge": "Premium liige",
"translationRecharge": "Tõlke varundus",
"meetingAssistantRecharge": "Koosoleku assistendi varundus",

3
apps/client/lib/core/translations/language/fa_ir.dart

@ -804,6 +804,9 @@ const Map<String, String> faIR = {
// 设置页
"systemSettings": "تنظیمات سیستم",
"vipRecharge": "شارژ عضویت ویژه",
"vipMonth": "Monthly VIP",
"vipQuarter": "Quarterly VIP",
"vipLifetime": "Lifetime VIP",
"aiRecharge": "عضویت ویژه",
"translationRecharge": "شارژ ترجمه",
"meetingAssistantRecharge": "شارژ کمک‌کننده جلسه",

3
apps/client/lib/core/translations/language/fi_fi.dart

@ -814,6 +814,9 @@ const Map<String, String> fiFI = {
// 设置页
"systemSettings": "Järjestelmäasetukset",
"vipRecharge": "Premium-jäsenvaraus",
"vipMonth": "Monthly VIP",
"vipQuarter": "Quarterly VIP",
"vipLifetime": "Lifetime VIP",
"aiRecharge": "Premium-jäsen",
"translationRecharge": "Käännösvaraus",
"meetingAssistantRecharge": "Kokousavustajan varaus",

3
apps/client/lib/core/translations/language/fr_fr.dart

@ -835,6 +835,9 @@ const Map<String, String> frFR = {
// 设置页
"systemSettings": "Paramètres système",
"vipRecharge": "Recharge de VIP",
"vipMonth": "Monthly VIP",
"vipQuarter": "Quarterly VIP",
"vipLifetime": "Lifetime VIP",
"aiRecharge": "Membre premium",
"translationRecharge": "Recharge de traduction",
"meetingAssistantRecharge": "Recharge de l'assistant de réunion",

3
apps/client/lib/core/translations/language/hi_in.dart

@ -811,6 +811,9 @@ const Map<String, String> hiIN = {
// 设置页
"systemSettings": "सिस्टम सेटिंग्स",
"vipRecharge": "प्रीमियम सदस्य रिचार्ज",
"vipMonth": "Monthly VIP",
"vipQuarter": "Quarterly VIP",
"vipLifetime": "Lifetime VIP",
"aiRecharge": "प्रीमियम सदस्य",
"translationRecharge": "अनुवाद रिचार्ज",
"meetingAssistantRecharge": "बैठक असिस्टेंट रिचार्ज",

3
apps/client/lib/core/translations/language/hr_hr.dart

@ -822,6 +822,9 @@ const Map<String, String> hrHR = {
// 设置页
"systemSettings": "Postavke sustava",
"vipRecharge": "Ponuda premium članstva",
"vipMonth": "Monthly VIP",
"vipQuarter": "Quarterly VIP",
"vipLifetime": "Lifetime VIP",
"aiRecharge": "Premium član",
"translationRecharge": "Prijevod ponuda",
"meetingAssistantRecharge": "Asistent sastanka ponuda",

3
apps/client/lib/core/translations/language/hu_hu.dart

@ -824,6 +824,9 @@ const Map<String, String> huHU = {
// 设置页
"systemSettings": "Rendszerbeállítások",
"vipRecharge": "Prémium tag ponuda",
"vipMonth": "Monthly VIP",
"vipQuarter": "Quarterly VIP",
"vipLifetime": "Lifetime VIP",
"aiRecharge": "Prémium tag",
"translationRecharge": "Fordítás ponuda",
"meetingAssistantRecharge": "Megbeszélés asszisztens ponuda",

3
apps/client/lib/core/translations/language/id_id.dart

@ -814,6 +814,9 @@ const Map<String, String> idID = {
// 设置页
"systemSettings": "Pengaturan Sistem",
"vipRecharge": "Pembayaran Premium",
"vipMonth": "Monthly VIP",
"vipQuarter": "Quarterly VIP",
"vipLifetime": "Lifetime VIP",
"aiRecharge": "Anggota Premium",
"translationRecharge": "Pembayaran Terjemahan",
"meetingAssistantRecharge": "Pembayaran Asisten Rapat",

3
apps/client/lib/core/translations/language/is_is.dart

@ -814,6 +814,9 @@ const Map<String, String> isIS = {
// 设置页
"systemSettings": "Kerfisstillingar",
"vipRecharge": "Premium meðlimurinnsla",
"vipMonth": "Monthly VIP",
"vipQuarter": "Quarterly VIP",
"vipLifetime": "Lifetime VIP",
"aiRecharge": "Premium meðlimur",
"translationRecharge": "Þýðingsponsoring",
"meetingAssistantRecharge": "Fundarasistentsponsoring",

3
apps/client/lib/core/translations/language/it_it.dart

@ -828,6 +828,9 @@ const Map<String, String> itIT = {
// 设置页
"systemSettings": "Impostazioni di sistema",
"vipRecharge": "Ricarica membro Premium",
"vipMonth": "Monthly VIP",
"vipQuarter": "Quarterly VIP",
"vipLifetime": "Lifetime VIP",
"aiRecharge": "Membro Premium",
"translationRecharge": "Ricarica traduzione",
"meetingAssistantRecharge": "Ricarica assistente riunione",

3
apps/client/lib/core/translations/language/ja_jp.dart

@ -761,6 +761,9 @@ const Map<String, String> jaJP = {
// 设置页
"systemSettings": "システム設定",
"vipRecharge": "プレミアムメンバー料金",
"vipMonth": "Monthly VIP",
"vipQuarter": "Quarterly VIP",
"vipLifetime": "Lifetime VIP",
"aiRecharge": "プレミアムメンバー",
"translationRecharge": "翻訳料金",
"meetingAssistantRecharge": "会議アシスタント料金",

3
apps/client/lib/core/translations/language/ko_kr.dart

@ -759,6 +759,9 @@ const Map<String, String> koKR = {
// 设置页
"systemSettings": "시스템 설정",
"vipRecharge": "프리미엄 회원료",
"vipMonth": "Monthly VIP",
"vipQuarter": "Quarterly VIP",
"vipLifetime": "Lifetime VIP",
"aiRecharge": "프리미엄 회원",
"translationRecharge": "번역료",
"meetingAssistantRecharge": "회의 어시스턴트료",

3
apps/client/lib/core/translations/language/lt_lt.dart

@ -819,6 +819,9 @@ const Map<String, String> ltLT = {
// 设置页
"systemSettings": "Sistemos nustatymai",
"vipRecharge": "Premium naryso užsipirkimas",
"vipMonth": "Monthly VIP",
"vipQuarter": "Quarterly VIP",
"vipLifetime": "Lifetime VIP",
"aiRecharge": "Premium narys",
"translationRecharge": "Vertimo užsipirkimas",
"meetingAssistantRecharge": "Susitikimų asistento užsipirkimas",

3
apps/client/lib/core/translations/language/lv_lv.dart

@ -822,6 +822,9 @@ const Map<String, String> lvLV = {
// 设置页
"systemSettings": "Sistēmas iestatījumi",
"vipRecharge": "Premium biedra pārrakstīšana",
"vipMonth": "Monthly VIP",
"vipQuarter": "Quarterly VIP",
"vipLifetime": "Lifetime VIP",
"aiRecharge": "Premium biedrs",
"translationRecharge": "Tulkošanas pārrakstīšana",
"meetingAssistantRecharge": "Sapulces palīgs pārrakstīšana",

3
apps/client/lib/core/translations/language/ms_my.dart

@ -818,6 +818,9 @@ const Map<String, String> msMY = {
// 设置页
"systemSettings": "Tetapan Sistem",
"vipRecharge": "Pembayaran Ahli Premium",
"vipMonth": "Monthly VIP",
"vipQuarter": "Quarterly VIP",
"vipLifetime": "Lifetime VIP",
"aiRecharge": "Ahli Premium",
"translationRecharge": "Pembayaran Penterjemahan",
"meetingAssistantRecharge": "Pembayaran Pembantu Mesyuarat",

3
apps/client/lib/core/translations/language/nb_no.dart

@ -816,6 +816,9 @@ const Map<String, String> nbNO = {
// 设置页
"systemSettings": "Systeminnstillinger",
"vipRecharge": "Premium-medlemsinnskudd",
"vipMonth": "Monthly VIP",
"vipQuarter": "Quarterly VIP",
"vipLifetime": "Lifetime VIP",
"aiRecharge": "Premium-medlem",
"translationRecharge": "Oversettelsespenger",
"meetingAssistantRecharge": "Møteassistentpenger",

3
apps/client/lib/core/translations/language/nl_nl.dart

@ -700,6 +700,9 @@ const Map<String, String> nlNL = {
// 设置页
"systemSettings": "Systeeminstellingen",
"vipRecharge": "Premium lidspayering",
"vipMonth": "Monthly VIP",
"vipQuarter": "Quarterly VIP",
"vipLifetime": "Lifetime VIP",
"aiRecharge": "Premium lid",
"translationRecharge": "Vertalingspayering",
"meetingAssistantRecharge": "Vergaderassistentpayering",

3
apps/client/lib/core/translations/language/pl_pl.dart

@ -823,6 +823,9 @@ const Map<String, String> plPL = {
// 设置页
"systemSettings": "Ustawienia systemowe",
"vipRecharge": "Płatność Premium",
"vipMonth": "Monthly VIP",
"vipQuarter": "Quarterly VIP",
"vipLifetime": "Lifetime VIP",
"aiRecharge": "Członek Premium",
"translationRecharge": "Płatność tłumaczenia",
"meetingAssistantRecharge": "Płatność asystenta spotkań",

3
apps/client/lib/core/translations/language/pt_pt.dart

@ -831,6 +831,9 @@ const Map<String, String> ptPT = {
// 设置页
"systemSettings": "Definições do Sistema",
"vipRecharge": "Recarga Premium",
"vipMonth": "Monthly VIP",
"vipQuarter": "Quarterly VIP",
"vipLifetime": "Lifetime VIP",
"aiRecharge": "Membro Premium",
"translationRecharge": "Recarga de Tradução",
"meetingAssistantRecharge": "Recarga do Assistente de Reunião",

3
apps/client/lib/core/translations/language/ro_ro.dart

@ -823,6 +823,9 @@ const Map<String, String> roRO = {
// 设置页
"systemSettings": "Setări de sistem",
"vipRecharge": "Recarga Premium",
"vipMonth": "Monthly VIP",
"vipQuarter": "Quarterly VIP",
"vipLifetime": "Lifetime VIP",
"aiRecharge": "Membru Premium",
"translationRecharge": "Recarga de traducere",
"meetingAssistantRecharge": "Recarga de asistent ședință",

3
apps/client/lib/core/translations/language/ru_ru.dart

@ -820,6 +820,9 @@ const Map<String, String> ruRU = {
// 设置页
"systemSettings": "Системные настройки",
"vipRecharge": "Пополнение премиум-члена",
"vipMonth": "Monthly VIP",
"vipQuarter": "Quarterly VIP",
"vipLifetime": "Lifetime VIP",
"aiRecharge": "Премиум-участник",
"translationRecharge": "Пополнение перевода",
"meetingAssistantRecharge": "Пополнение помощника встречи",

3
apps/client/lib/core/translations/language/sk_sk.dart

@ -817,6 +817,9 @@ const Map<String, String> skSK = {
// 设置页
"systemSettings": "Systémové nastavenia",
"vipRecharge": "Nákup prémium členstva",
"vipMonth": "Monthly VIP",
"vipQuarter": "Quarterly VIP",
"vipLifetime": "Lifetime VIP",
"aiRecharge": "Prémium člen",
"translationRecharge": "Nákup prekladov",
"meetingAssistantRecharge": "Nákup asistentu stretnutia",

3
apps/client/lib/core/translations/language/sl_si.dart

@ -818,6 +818,9 @@ const Map<String, String> slSI = {
// 设置页
"systemSettings": "Sistemske nastavitve",
"vipRecharge": "Nákup premium člana",
"vipMonth": "Monthly VIP",
"vipQuarter": "Quarterly VIP",
"vipLifetime": "Lifetime VIP",
"aiRecharge": "Premium član",
"translationRecharge": "Nákup prevajanja",
"meetingAssistantRecharge": "Nákup asistenta sestanka",

3
apps/client/lib/core/translations/language/sr_rs.dart

@ -816,6 +816,9 @@ const Map<String, String> srRS = {
// 设置页
"systemSettings": "Sistemska podešavanja",
"vipRecharge": "Kupovina premium članstva",
"vipMonth": "Monthly VIP",
"vipQuarter": "Quarterly VIP",
"vipLifetime": "Lifetime VIP",
"aiRecharge": "Premium član",
"translationRecharge": "Kupovina prevođenja",
"meetingAssistantRecharge": "Kupovina asistenta sastanka",

3
apps/client/lib/core/translations/language/sv_se.dart

@ -818,6 +818,9 @@ const Map<String, String> svSE = {
// 设置页
"systemSettings": "Systeminställningar",
"vipRecharge": "Premium-låntagning",
"vipMonth": "Monthly VIP",
"vipQuarter": "Quarterly VIP",
"vipLifetime": "Lifetime VIP",
"aiRecharge": "Premium-medlem",
"translationRecharge": "Översättningslåntagning",
"meetingAssistantRecharge": "Mötesassistentlåntagning",

3
apps/client/lib/core/translations/language/th_th.dart

@ -794,6 +794,9 @@ const Map<String, String> thTH = {
// 设置页
"systemSettings": "การตั้งค่าระบบ",
"vipRecharge": "การเติมเงินสมาชิกระดับพรีเมียม",
"vipMonth": "Monthly VIP",
"vipQuarter": "Quarterly VIP",
"vipLifetime": "Lifetime VIP",
"aiRecharge": "สมาชิกระดับพรีเมียม",
"translationRecharge": "การเติมเงินการแปล",
"meetingAssistantRecharge": "การเติมเงินผู้ช่วยการประชุม",

3
apps/client/lib/core/translations/language/tl_ph.dart

@ -833,6 +833,9 @@ const Map<String, String> tlPH = {
// 设置页
"systemSettings": "Mga Setting ng System",
"vipRecharge": "Pagsasalin ng Recharge ng Premium na Miyembro",
"vipMonth": "Monthly VIP",
"vipQuarter": "Quarterly VIP",
"vipLifetime": "Lifetime VIP",
"aiRecharge": "Premium na Miyembro",
"translationRecharge": "Pagsasalin ng Recharge",
"meetingAssistantRecharge": "Pagsasalin ng Recharge ng Pulong",

3
apps/client/lib/core/translations/language/tr_tr.dart

@ -814,6 +814,9 @@ const Map<String, String> trTR = {
// 设置页
"systemSettings": "Sistem Ayarları",
"vipRecharge": "VIP Üyelik Yükleme",
"vipMonth": "Monthly VIP",
"vipQuarter": "Quarterly VIP",
"vipLifetime": "Lifetime VIP",
"aiRecharge": "AI Yükleme",
"translationRecharge": "Çeviri Yükleme",
"meetingAssistantRecharge": "Toplantı Yükleme",

3
apps/client/lib/core/translations/language/uk_ua.dart

@ -821,6 +821,9 @@ const Map<String, String> ukUA = {
// 设置页
"systemSettings": "Системні налаштування",
"vipRecharge": "Підписатися на премиум-членство",
"vipMonth": "Monthly VIP",
"vipQuarter": "Quarterly VIP",
"vipLifetime": "Lifetime VIP",
"aiRecharge": "Преміум-учасник",
"translationRecharge": "Підписатися на переклад",
"meetingAssistantRecharge": "Підписатися на допомогу з зустрічю",

3
apps/client/lib/core/translations/language/vi_vn.dart

@ -807,6 +807,9 @@ const Map<String, String> viVN = {
// 设置页
"systemSettings": "Cài đặt hệ thống",
"vipRecharge": "Nạp lại dịch vụ Premium",
"vipMonth": "Monthly VIP",
"vipQuarter": "Quarterly VIP",
"vipLifetime": "Lifetime VIP",
"aiRecharge": "Thành viên Premium",
"translationRecharge": "Nạp lại dịch vụ dịch",
"meetingAssistantRecharge": "Nạp lại dịch vụ hỗ trợ họp",

3
apps/client/lib/core/translations/language/zh_cn.dart

@ -766,6 +766,9 @@ const Map<String, String> zhCN = {
// 设置页
"systemSettings": "系统设置",
"vipRecharge": "会员充值",
"vipMonth": "月度VIP",
"vipQuarter": "季度VIP",
"vipLifetime": "终生VIP",
"aiRecharge": "AI充值",
"translationRecharge": "翻译充值",
"meetingAssistantRecharge": "会议充值",

3
apps/client/lib/core/translations/language/zh_hk.dart

@ -761,6 +761,9 @@ const Map<String, String> zhHK = {
// 设置页
"systemSettings": "系統設定",
"vipRecharge": "高級會員充值",
"vipMonth": "Monthly VIP",
"vipQuarter": "Quarterly VIP",
"vipLifetime": "Lifetime VIP",
"aiRecharge": "AI充值",
"translationRecharge": "翻譯充值",
"meetingAssistantRecharge": "會議充值",

3
apps/client/lib/core/translations/language/zh_tw.dart

@ -761,6 +761,9 @@ const Map<String, String> zhTW = {
// 设置页
"systemSettings": "系統設定",
"vipRecharge": "高級會員充值",
"vipMonth": "Monthly VIP",
"vipQuarter": "Quarterly VIP",
"vipLifetime": "Lifetime VIP",
"aiRecharge": "AI充值",
"translationRecharge": "翻譯充值",
"meetingAssistantRecharge": "會議充值",

4
apps/client/lib/core/utils/app_features.dart

@ -10,10 +10,12 @@ class AppFeatures {
/// 2026-08-28 起暂时关闭:新用户注册就送 30 天 VIP + 翻译/会议各 100 分钟
/// + 智能体 100 次,这期间不引导充值。
///
/// 置回 true 即可恢复,影响两处:
/// 置回 true 即可在安卓也恢复,影响两处:
/// 1. 「设置」页的会员充值卡片(settings_view.dart)
/// 2. 额度不足/会员过期时的充值弹窗里的「去充值」按钮(recharge_dialog.dart)
///
/// iOS 不受这个开关控制,入口始终打开,购买走 Apple IAP。
///
/// 注意:关闭的只是**入口**,goodsvip/goodstrans/goodsmeet 这几个页面本身还在,
/// 路由也没删——万一还有别的地方能跳进去,页面不会崩。
static const bool rechargeEnabled = false;

7
apps/client/lib/modules/common/widgets/recharge_dialog.dart

@ -1,3 +1,4 @@
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import '../../../routes/app_routes.dart';
@ -34,9 +35,9 @@ void showRechargeDialog(String type) {
.tr, // 会员过期描述 / 余额不足描述
textAlign: TextAlign.center,
),
// 充值入口关闭期间只保留提示,不给「去充值」按钮——
// 留着按钮会跳到一个已经从设置页隐藏掉的页面,前后矛盾。
if (AppFeatures.rechargeEnabled) ...[
// 安卓在充值入口关闭期间只保留提示。iOS 走 Apple IAP,按钮始终保留。
if (AppFeatures.rechargeEnabled ||
defaultTargetPlatform == TargetPlatform.iOS) ...[
const SizedBox(height: 20),
SizedBox(
width: double.infinity,

12
apps/client/lib/modules/goods/controllers/goods_base_controller.dart

@ -154,8 +154,11 @@ abstract class GoodsBaseController extends GetxController {
///
/// ⚠️ Google Play 卖数字商品必须走 Play 结算,摆出微信/支付宝/PayPal 是最典型的
/// 下架理由。所以 Google 渠道**一律只留 google**:既不信后端下发的渠道列表,
/// 配置缺失时也不回退成「展示所有」。其它渠道行为保持不变。
/// 配置缺失时也不回退成「展示所有」。
/// 苹果包同样:数字商品只能走 Apple 内购,不展示微信/支付宝/PayPal。
List<_PayMethod> _getEnabledPayMethods() {
final bool isIOS = GetPlatform.isIOS && !kIsWeb;
if (isIOS) return <_PayMethod>[_PayMethod.apple];
if (_isGooglePlayBuild) {
final bool isAndroid = GetPlatform.isAndroid && !kIsWeb;
return isAndroid ? <_PayMethod>[_PayMethod.google] : <_PayMethod>[];
@ -756,8 +759,11 @@ abstract class GoodsBaseController extends GetxController {
final context = Get.context;
final isDark =
context != null && Theme.of(context).brightness == Brightness.dark;
final titleText =
success ? 'paymentSuccess'.tr : 'paymentFailed'.tr; // 支付成功/支付失败
final cancelled =
message == '已取消支付' || message == 'paymentCancelled'.tr;
final titleText = success
? 'paymentSuccess'.tr
: (cancelled ? 'paymentCancelled'.tr : 'paymentFailed'.tr);
Get.dialog(
Dialog(
insetPadding: const EdgeInsets.symmetric(horizontal: 24, vertical: 24),

7
apps/client/lib/modules/goods/controllers/goodsvip_controller.dart

@ -8,8 +8,15 @@ class GoodsvipController extends GoodsBaseController {
/// 服务端已把自购与设备赋予的 VIP 合并好、算力也拆好了来源,这里**不做任何换算**。
final compute = Rxn<Map<String, dynamic>>();
/// 从「我的」点进来的档位。进页时记一次。
/// 不能在 build 里读 Get.arguments:取消支付会盖一层结果窗,当前路由参数变成空,
/// 页面一重绘就会把月度/季度/终生退回整页「AI充值」。
late final String? vipTier;
@override
void onInit() {
final args = Get.arguments;
vipTier = args is Map && args['tier'] is String ? args['tier'] as String : null;
super.onInit();
refreshCompute();
}

94
apps/client/lib/modules/goods/views/goodsvip_view.dart

@ -29,7 +29,7 @@ class GoodsvipView extends GetView<GoodsvipController> {
onPressed: () => Get.back(),
),
title: Text(
'aiRecharge'.tr,
_pageTitle,
style: TextStyle(
fontSize: 18.sp,
fontWeight: FontWeight.w600,
@ -48,29 +48,34 @@ class GoodsvipView extends GetView<GoodsvipController> {
} else if (controller.error.isNotEmpty) {
content = Center(child: Text(controller.error.value));
} else {
final focused = _tier != null;
final source = focused
? controller.items.where(_matchesTier).toList()
: controller.items.toList();
final Map<UsageType, List<DBGoods>> grouped = {};
for (final g in controller.items) {
for (final g in source) {
grouped.putIfAbsent(g.usagetype, () => []).add(g);
}
// VIP 时长在前、算力包在后;两者都没有商品时页面只剩权益说明
final order = [UsageType.Vip, UsageType.Compute];
// 从「我的」点某一档进来时只留会员服务和这一档;其它入口仍是完整充值页。
final order =
focused ? [UsageType.Vip] : [UsageType.Vip, UsageType.Compute];
final children = <Widget>[];
// 到期 / 算力不足提示条:阈值由后台配(0 = 关掉该提示),判定在 controller 里
if (controller.vipExpiringSoon) {
children.add(_buildWarnBanner(
isDarkMode,
'vipExpiringSoon'.trParams({'days': '${controller.vipDaysLeft}'}),
));
children.add(SizedBox(height: 12.h));
}
if (controller.computeLow) {
children.add(_buildWarnBanner(isDarkMode, 'computeLow'.tr));
children.add(SizedBox(height: 12.h));
if (!focused) {
if (controller.vipExpiringSoon) {
children.add(_buildWarnBanner(
isDarkMode,
'vipExpiringSoon'
.trParams({'days': '${controller.vipDaysLeft}'}),
));
children.add(SizedBox(height: 12.h));
}
if (controller.computeLow) {
children.add(_buildWarnBanner(isDarkMode, 'computeLow'.tr));
children.add(SizedBox(height: 12.h));
}
children.add(_buildFeaturesSection(isDarkMode));
children.add(SizedBox(height: 16.h));
}
children.add(_buildFeaturesSection(isDarkMode));
children.add(SizedBox(height: 16.h));
// children.add(_buildScenesSection(isDarkMode));
// children.add(SizedBox(height: 16.h));
for (int i = 0; i < order.length; i++) {
final t = order[i];
final list = grouped[t];
@ -84,7 +89,9 @@ class GoodsvipView extends GetView<GoodsvipController> {
}
}
children.add(GoodsFooterSection(isDarkMode: isDarkMode));
if (!focused) {
children.add(GoodsFooterSection(isDarkMode: isDarkMode));
}
content = ListView(
key: ValueKey(userTick),
padding: EdgeInsets.all(16.w),
@ -113,6 +120,49 @@ class GoodsvipView extends GetView<GoodsvipController> {
);
}
/// 进页时记下的档位。不要改回读 Get.arguments。
String? get _tier => controller.vipTier;
String get _pageTitle {
switch (_tier) {
case 'month':
return 'vipMonth'.tr;
case 'quarter':
return 'vipQuarter'.tr;
case 'lifetime':
return 'vipLifetime'.tr;
default:
return 'aiRecharge'.tr;
}
}
/// 月度约 30 天、季度约 90 天、终生按一年以上。天数对不上时再看商品名。
bool _matchesTier(DBGoods g) {
if (g.usagetype != UsageType.Vip) return false;
final tier = _tier;
if (g.viptime > 0) {
switch (tier) {
case 'month':
return g.viptime >= 28 && g.viptime <= 31;
case 'quarter':
return g.viptime >= 80 && g.viptime <= 100;
case 'lifetime':
return g.viptime >= 365;
}
}
final blob = '${g.id} ${g.name} ${g.localname}'.toLowerCase();
switch (tier) {
case 'month':
return blob.contains('month') || blob.contains('月度');
case 'quarter':
return blob.contains('quarter') || blob.contains('季');
case 'lifetime':
return blob.contains('life') || blob.contains('终');
default:
return false;
}
}
/// 到期 / 算力不足的提示条。刻意做成温和的黄色而不是红色错误样式——
/// 这是「该续费了」的提醒,不是故障;下面就是购买入口,不需要再额外引导。
Widget _buildWarnBanner(bool isDarkMode, String text) {
@ -486,10 +536,10 @@ class GoodsvipView extends GetView<GoodsvipController> {
shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(),
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
crossAxisCount: _tier != null ? 1 : 2,
mainAxisSpacing: 8.h,
crossAxisSpacing: 12.w,
childAspectRatio: 1.3,
childAspectRatio: _tier != null ? 2.8 : 1.3,
),
itemCount: list.length,
itemBuilder: (_, i) => _buildGridItemCard(list[i], type, isDarkMode),

52
apps/client/lib/modules/profile/controllers/profile_controller.dart

@ -35,6 +35,9 @@ class ProfileController extends GetxController {
final _userportraitManager = Get.find<UserportraitManager>();
// 用于乐观更新的原始状态备份
String _originalName = '';
// 服务端已落库的昵称。默认名 User_xxxx 含敏感词,未改昵称时不要再提交,
// 否则头像和性别会跟着被整单拒绝。
String _serverName = '';
String _originalAvatar = '';
String _originalLocalAvatar = '';
@ -220,9 +223,13 @@ class ProfileController extends GetxController {
// 创建FormData对象用于上传
dio.FormData formData = dio.FormData();
// 添加基本用户信息
// 添加基本用户信息。昵称没变就不传:服务端对非空名字做敏感词校验,
// 自动生成的 User_xxxx 一定含 "se",会把同一次的头像、性别一起拒绝。
formData.fields.add(MapEntry('language', currentLanguage.value));
formData.fields.add(MapEntry('name', userInfo.value.name));
if (userInfo.value.name.isNotEmpty &&
userInfo.value.name != _serverName) {
formData.fields.add(MapEntry('name', userInfo.value.name));
}
formData.fields.add(MapEntry('gender', userInfo.value.gender.toString()));
// 如果有头像,添加到FormData
@ -272,8 +279,15 @@ class ProfileController extends GetxController {
// 更新用户信息为服务器返回的最新数据
userInfo.update((u) {
if (u != null) {
u.name = response['name'] ?? u.name;
u.avatar = response['avatar'] ?? u.avatar;
// 没改昵称时请求不带 name,服务端会把该字段回成空串,不能覆盖本地名字。
final returnedName = response['name'];
if (returnedName is String && returnedName.isNotEmpty) {
u.name = returnedName;
}
final returnedAvatar = response['avatar'];
if (returnedAvatar is String && returnedAvatar.isNotEmpty) {
u.avatar = returnedAvatar;
}
if (response['gender'] != null) {
u.gender = response['gender'] as int? ?? u.gender;
}
@ -292,8 +306,9 @@ class ProfileController extends GetxController {
Logger().d('更新后的用户信息: ${userInfo.value.toJson()}');
} else {
Logger().e('服务器响应为空或格式错误: $response');
throw Exception('服务器响应异常');
// code != 0 时拦截器已经把服务端 msg 弹出来了,这里只回滚,不再叠一条「请重试」。
Logger().e('服务器拒绝保存: $response');
throw const ProfileSaveRejected();
}
} catch (e) {
Logger().e('同步到后端失败: $e');
@ -318,6 +333,7 @@ class ProfileController extends GetxController {
final userJson = _storage.read(userKey);
if (userJson != null) {
userInfo.value = User.instance;
_serverName = userInfo.value.name;
Logger().d('从本地加载用户信息: $userJson');
// 重置头像准备状态
@ -628,22 +644,34 @@ class ProfileController extends GetxController {
// 更新用户名和头像(保存操作)
Future<void> updateUserNameAndAvatar(String name) async {
if (name.trim().isEmpty) {
final trimmed = name.trim();
if (trimmed.isEmpty) {
Logger().e('无效名称: $name');
Get.snackbar('error'.tr, 'usernameCannotBeEmpty'.tr); //用户名不能为空
return;
}
// 保存按钮拿到的是输入框文本。内联编辑没失焦时 userInfo 里还是旧昵称,
// 必须以输入框为准,否则改名请求仍会带上过不了校验的默认名。
if (trimmed != userInfo.value.name) {
userInfo.update((user) {
if (user != null) {
user.name = trimmed;
}
});
hasEdits.value = true;
}
// 显示加载状态
isUpdating.value = true;
try {
Logger().d('开始保存用户信息 - 名称: ${name.trim()}, 本地头像: ${localAvatar.value}');
Logger().d('开始保存用户信息 - 名称: $trimmed, 本地头像: ${localAvatar.value}');
// 同步到后端
await _syncWithBackend();
// 同步成功后更新原始状态和本地存储
_serverName = userInfo.value.name;
_saveOriginalState();
await _syncLocalStorage();
@ -691,6 +719,9 @@ class ProfileController extends GetxController {
);
}
});
} on ProfileSaveRejected {
Logger().e('保存被服务端拒绝');
await _rollbackToOriginalState();
} catch (e) {
Logger().e('更新用户名和头像错误: $e');
@ -795,3 +826,8 @@ class ProfileController extends GetxController {
}
}
}
/// 服务端以业务码拒绝了保存。拦截器已经弹出 msg,调用方只回滚、不再提示。
class ProfileSaveRejected implements Exception {
const ProfileSaveRejected();
}

111
apps/client/lib/modules/settings/views/settings_view.dart

@ -1,4 +1,5 @@
import 'dart:ui';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
@ -234,10 +235,14 @@ class SettingsView extends GetView<SettingsController> {
}
// 构建Vip购买卡片
/// 会员充值:单行紧凑卡片(图标 + 文字 + 箭头同一行),紧跟用户信息卡下方
/// 会员充值,紧跟用户信息卡下方。
///
/// AppFeatures.rechargeEnabled=false 时整卡不渲染(当前的送额度期间不引导充值)。
/// 安卓仍由 [AppFeatures.rechargeEnabled] 控制。iOS 始终展示,
/// 月 / 季 / 终身都进现有的会员商品页,支付走 Apple IAP。
Widget _buildVipPurchaseCard(bool isDarkMode) {
if (defaultTargetPlatform == TargetPlatform.iOS) {
return _buildIosVipRechargeCard(isDarkMode);
}
if (!AppFeatures.rechargeEnabled) return const SizedBox.shrink();
return GestureDetector(
behavior: HitTestBehavior.opaque,
@ -305,6 +310,108 @@ class SettingsView extends GetView<SettingsController> {
);
}
/// iOS 会员充值:月 / 季 / 终身,都打开现有会员商品页。
Widget _buildIosVipRechargeCard(bool isDarkMode) {
return Container(
padding: EdgeInsets.fromLTRB(16.w, 14.h, 16.w, 12.h),
decoration: BoxDecoration(
gradient: LinearGradient(
colors: isDarkMode
? [
const Color(0xFF0D47A1).withValues(alpha: 0.5),
const Color(0xFF1976D2).withValues(alpha: 0.5),
]
: [const Color(0xFFE3F2FD), const Color(0xFFBBDEFB)],
begin: Alignment.centerLeft,
end: Alignment.centerRight,
),
borderRadius: BorderRadius.circular(14.r),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'vipRecharge'.tr,
style: TextStyle(
fontSize: 15.sp,
fontWeight: FontWeight.w700,
color: isDarkMode ? Colors.white : Colors.black87,
),
),
SizedBox(height: 12.h),
Row(
children: [
_iosVipItem(
icon: Icons.workspace_premium,
label: 'vipMonth'.tr,
isDarkMode: isDarkMode,
arguments: const {'tier': 'month'},
),
_iosVipItem(
icon: Icons.calendar_view_month,
label: 'vipQuarter'.tr,
isDarkMode: isDarkMode,
arguments: const {'tier': 'quarter'},
),
_iosVipItem(
icon: Icons.event_available,
label: 'vipLifetime'.tr,
isDarkMode: isDarkMode,
arguments: const {'tier': 'lifetime'},
),
],
),
],
),
);
}
Widget _iosVipItem({
required IconData icon,
required String label,
required bool isDarkMode,
Object? arguments,
}) {
return Expanded(
child: InkWell(
onTap: () => Get.toNamed(Routes.goodsvip, arguments: arguments),
borderRadius: BorderRadius.circular(12.r),
child: Column(
children: [
Container(
width: 42.w,
height: 42.w,
decoration: BoxDecoration(
color: isDarkMode
? Colors.amber[900]!.withValues(alpha: 0.3)
: Colors.white,
shape: BoxShape.circle,
),
child: Icon(
icon,
size: 20.sp,
color: isDarkMode ? Colors.amber[300]! : Colors.amber[700]!,
),
),
SizedBox(height: 6.h),
Text(
label,
textAlign: TextAlign.center,
maxLines: 2,
overflow: TextOverflow.ellipsis,
style: TextStyle(
fontSize: 12.sp,
fontWeight: FontWeight.w500,
color: isDarkMode ? Colors.white : const Color(0xFF111827),
height: 1.2,
),
),
],
),
),
);
}
Widget _buildSystemSettingsSection(bool isDarkMode) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,

Loading…
Cancel
Save