|
@@ -77,6 +77,31 @@
|
|
|
</div>
|
|
</div>
|
|
|
</div>
|
|
</div>
|
|
|
|
|
|
|
|
|
|
+ <!-- Telegram 绑定 -->
|
|
|
|
|
+ <div class="edit-section" v-if="type === 'telegram'">
|
|
|
|
|
+ <div class="telegram-header">
|
|
|
|
|
+ <svg viewBox="0 0 24 24" width="48" height="48" style="margin: 0 auto 12px; display: block;">
|
|
|
|
|
+ <circle cx="12" cy="12" r="12" fill="#0088cc"/>
|
|
|
|
|
+ <path fill="#fff" d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm5.46 7.12l-1.67 6.14c-.13.46-.47.58-.95.36l-2.62-1.93-1.26 1.22c-.14.14-.26.26-.53.26l.19-2.67 4.84-4.37c.21-.19-.05-.29-.32-.12l-5.99 3.78-2.58-.81c-.56-.17-.57-.56.12-.83l10.1-3.9c.46-.17.87.11.67.87z"/>
|
|
|
|
|
+ </svg>
|
|
|
|
|
+ <p class="telegram-tip">Enter your Telegram username to bind your account</p>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <van-field
|
|
|
|
|
+ v-model="telegramUsername"
|
|
|
|
|
+ placeholder="@username"
|
|
|
|
|
+ maxlength="50"
|
|
|
|
|
+ class="edit-input"
|
|
|
|
|
+ >
|
|
|
|
|
+ <template #left-icon>
|
|
|
|
|
+ <span style="color: var(--text-secondary, rgba(255,255,255,0.5)); font-size: 16px;">@</span>
|
|
|
|
|
+ </template>
|
|
|
|
|
+ </van-field>
|
|
|
|
|
+ <div class="tips">
|
|
|
|
|
+ <p>* Open Telegram → Settings → Username to find your username</p>
|
|
|
|
|
+ <p>* Binding Telegram enables you to participate in red packet events</p>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+
|
|
|
<!-- 地区编辑 -->
|
|
<!-- 地区编辑 -->
|
|
|
<div class="edit-section" v-if="type === 'region'">
|
|
<div class="edit-section" v-if="type === 'region'">
|
|
|
<van-field
|
|
<van-field
|
|
@@ -146,7 +171,7 @@ import { useRouter, useRoute } from "vue-router";
|
|
|
import { useI18n } from "vue-i18n";
|
|
import { useI18n } from "vue-i18n";
|
|
|
import { showToast } from "vant";
|
|
import { showToast } from "vant";
|
|
|
import { useUserStore } from "@/store/modules/userStore";
|
|
import { useUserStore } from "@/store/modules/userStore";
|
|
|
-import { requestUpdateUserInfo, requestBindPhone, requestBindEmail, requestVerifyRealName } from "@/api/user";
|
|
|
|
|
|
|
+import { requestUpdateUserInfo, requestBindPhone, requestBindEmail, requestVerifyRealName, requestBindSocial, requestGetSocialList } from "@/api/user";
|
|
|
import { requestSendCode } from "@/api/auth";
|
|
import { requestSendCode } from "@/api/auth";
|
|
|
|
|
|
|
|
const { t } = useI18n();
|
|
const { t } = useI18n();
|
|
@@ -166,6 +191,7 @@ const age = ref(userInfo.value?.age ? String(userInfo.value.age) : '');
|
|
|
const gender = ref(userInfo.value?.gender || 0);
|
|
const gender = ref(userInfo.value?.gender || 0);
|
|
|
const realName = ref('');
|
|
const realName = ref('');
|
|
|
const idCard = ref('');
|
|
const idCard = ref('');
|
|
|
|
|
+const telegramUsername = ref('');
|
|
|
const countdown = ref(0);
|
|
const countdown = ref(0);
|
|
|
let timer: NodeJS.Timer | null = null;
|
|
let timer: NodeJS.Timer | null = null;
|
|
|
|
|
|
|
@@ -174,6 +200,7 @@ const getTitle = () => {
|
|
|
nickname: t('user.nickname'),
|
|
nickname: t('user.nickname'),
|
|
|
phone: t('user.bindPhone'),
|
|
phone: t('user.bindPhone'),
|
|
|
email: t('user.bindEmail'),
|
|
email: t('user.bindEmail'),
|
|
|
|
|
+ telegram: 'Bind Telegram',
|
|
|
region: t('user.region'),
|
|
region: t('user.region'),
|
|
|
age: t('user.age'),
|
|
age: t('user.age'),
|
|
|
gender: t('user.gender'),
|
|
gender: t('user.gender'),
|
|
@@ -245,6 +272,15 @@ const handleSave = async () => {
|
|
|
res = await requestBindEmail({ email: email.value, code: code.value });
|
|
res = await requestBindEmail({ email: email.value, code: code.value });
|
|
|
break;
|
|
break;
|
|
|
|
|
|
|
|
|
|
+ case 'telegram':
|
|
|
|
|
+ const tgAccount = telegramUsername.value.trim().replace(/^@/, '');
|
|
|
|
|
+ if (!tgAccount) {
|
|
|
|
|
+ showToast('Please enter your Telegram username');
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+ res = await requestBindSocial({ platform: 'telegram', account: tgAccount });
|
|
|
|
|
+ break;
|
|
|
|
|
+
|
|
|
case 'region':
|
|
case 'region':
|
|
|
if (!region.value.trim()) {
|
|
if (!region.value.trim()) {
|
|
|
showToast(t('user.region'));
|
|
showToast(t('user.region'));
|
|
@@ -295,13 +331,28 @@ const goBack = () => {
|
|
|
router.back();
|
|
router.back();
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
-onMounted(() => {
|
|
|
|
|
|
|
+onMounted(async () => {
|
|
|
if (userInfo.value) {
|
|
if (userInfo.value) {
|
|
|
nickname.value = userInfo.value.nickname || '';
|
|
nickname.value = userInfo.value.nickname || '';
|
|
|
region.value = userInfo.value.region || '';
|
|
region.value = userInfo.value.region || '';
|
|
|
age.value = userInfo.value.age ? String(userInfo.value.age) : '';
|
|
age.value = userInfo.value.age ? String(userInfo.value.age) : '';
|
|
|
gender.value = userInfo.value.gender || 0;
|
|
gender.value = userInfo.value.gender || 0;
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
|
|
+ // 加载已绑定的 Telegram 用户名
|
|
|
|
|
+ if (type.value === 'telegram') {
|
|
|
|
|
+ try {
|
|
|
|
|
+ const res = await requestGetSocialList();
|
|
|
|
|
+ if (res.code === 200 && res.data) {
|
|
|
|
|
+ const tg = (res.data as any[]).find((item: any) => item.platform === 'telegram');
|
|
|
|
|
+ if (tg && tg.account) {
|
|
|
|
|
+ telegramUsername.value = tg.account;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ } catch (e) {
|
|
|
|
|
+ // ignore
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
});
|
|
});
|
|
|
</script>
|
|
</script>
|
|
|
|
|
|
|
@@ -398,6 +449,17 @@ onMounted(() => {
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ .telegram-header {
|
|
|
|
|
+ text-align: center;
|
|
|
|
|
+ margin-bottom: 20px;
|
|
|
|
|
+
|
|
|
|
|
+ .telegram-tip {
|
|
|
|
|
+ font-size: 13px;
|
|
|
|
|
+ color: var(--text-secondary, rgba(255, 255, 255, 0.6));
|
|
|
|
|
+ line-height: 1.5;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
.tips {
|
|
.tips {
|
|
|
margin-top: 16px;
|
|
margin-top: 16px;
|
|
|
padding: 12px;
|
|
padding: 12px;
|