| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287 |
- <template>
- <div class="profile-page">
- <!-- 返回按钮 -->
- <div class="header">
- <van-icon name="arrow-left" @click="goBack" />
- <span>{{ $t('user.personalInfo') }}</span>
- <span></span>
- </div>
- <!-- 个人信息列表 -->
- <div class="info-list">
- <!-- 头像 -->
- <div class="info-item" @click="handleAvatarClick">
- <span class="label">{{ $t('user.avatar') }}</span>
- <div class="value">
- <img :src="userInfo?.avatar || defaultAvatar" class="avatar" />
- <van-icon name="arrow" />
- </div>
- </div>
- <!-- 昵称 -->
- <div class="info-item" @click="goEdit('nickname')">
- <span class="label">{{ $t('user.nickname') }}</span>
- <div class="value">
- <span>{{ userInfo?.nickname || '-' }}</span>
- <van-icon name="arrow" />
- </div>
- </div>
- <!-- 绑定手机 -->
- <div class="info-item" @click="goEdit('phone')">
- <span class="label">{{ $t('user.bindPhone') }}</span>
- <div class="value">
- <span>{{ formatPhone(userInfo?.phone) }}</span>
- <van-icon name="arrow" />
- </div>
- </div>
- <!-- 绑定邮箱 -->
- <div class="info-item" @click="goEdit('email')">
- <span class="label">{{ $t('user.bindEmail') }}</span>
- <div class="value">
- <span>{{ userInfo?.email || $t('common.no') }}</span>
- <van-icon name="arrow" />
- </div>
- </div>
- <!-- 绑定 Telegram -->
- <div class="info-item" @click="goEdit('telegram')">
- <span class="label">Bind Telegram</span>
- <div class="value">
- <span>{{ telegramAccount || $t('common.no') }}</span>
- <van-icon name="arrow" />
- </div>
- </div>
- <!-- 地区 -->
- <div class="info-item" @click="goEdit('region')">
- <span class="label">{{ $t('user.region') }}</span>
- <div class="value">
- <span>{{ userInfo?.region || '-' }}</span>
- <van-icon name="arrow" />
- </div>
- </div>
- <!-- 年龄 -->
- <div class="info-item" @click="goEdit('age')">
- <span class="label">{{ $t('user.age') }}</span>
- <div class="value">
- <span>{{ userInfo?.age || '-' }}</span>
- <van-icon name="arrow" />
- </div>
- </div>
- <!-- 性别 -->
- <div class="info-item" @click="goEdit('gender')">
- <span class="label">{{ $t('user.gender') }}</span>
- <div class="value">
- <span>{{ getGenderText() }}</span>
- <van-icon name="arrow" />
- </div>
- </div>
- <!-- 实名认证 -->
- <div class="info-item" @click="goEdit('realName')">
- <span class="label">{{ $t('user.realName') }}</span>
- <div class="value">
- <span :class="{ verified: userInfo?.realNameStatus === 1 }">
- {{ getRealNameStatus() }}
- </span>
- <van-icon name="arrow" />
- </div>
- </div>
- <!-- 修改密码 -->
- <div class="info-item" @click="goPassword">
- <span class="label">{{ $t('user.changePassword') }}</span>
- <div class="value">
- <van-icon name="arrow" />
- </div>
- </div>
- <!-- 收款账户 -->
- <div class="info-item" @click="goPaymentAccount">
- <span class="label">{{ $t('user.paymentAccount') }}</span>
- <div class="value">
- <span>{{ userInfo?.paymentAccountCount || 0 }}</span>
- <van-icon name="arrow" />
- </div>
- </div>
- </div>
- <!-- 头像上传 -->
- <van-uploader
- ref="uploaderRef"
- v-show="false"
- :after-read="afterAvatarRead"
- accept="image/*"
- />
- </div>
- </template>
- <script setup lang="ts">
- import { ref, computed, onMounted } from "vue";
- import { useRouter } from "vue-router";
- import { useI18n } from "vue-i18n";
- import { showToast } from "vant";
- import { useUserStore } from "@/store/modules/userStore";
- import { requestUpdateUserInfo, requestGetSocialList } from "@/api/user";
- import { uploadFileToOss } from "@/api/upload";
- import defaultAvatar from "@/assets/images/common/icon_avatar.svg";
- const telegramAccount = ref('');
- const { t } = useI18n();
- const router = useRouter();
- const userStore = useUserStore();
- const uploaderRef = ref<any>(null);
- const userInfo = computed(() => userStore.userInfo);
- const formatPhone = (phone: string | undefined) => {
- if (!phone) return t('common.no');
- if (phone.length > 7) {
- return phone.slice(0, 3) + '****' + phone.slice(-4);
- }
- return phone;
- };
- const getGenderText = () => {
- const gender = userInfo.value?.gender;
- if (gender === 1) return t('user.male');
- if (gender === 2) return t('user.female');
- return '-';
- };
- const getRealNameStatus = () => {
- const status = userInfo.value?.realNameStatus;
- if (status === 1) return t('task.completed');
- if (status === 2) return t('taskStatus.pendingReview');
- return t('common.no');
- };
- const handleAvatarClick = () => {
- uploaderRef.value?.chooseFile();
- };
- const afterAvatarRead = async (file: any) => {
- try {
- // 先上传图片获取URL
- const url = await uploadFileToOss(file.file);
- if (!url) {
- showToast('Upload failed');
- return;
- }
- // 再用URL更新头像
- const res = await requestUpdateUserInfo({ avatar: url });
- if (res.code === 200) {
- showToast(t('common.save') + ' ' + t('task.completed'));
- userStore.fetchUserInfo();
- }
- } catch (e) {
- showToast('Upload failed');
- }
- };
- const goBack = () => {
- router.back();
- };
- const goEdit = (type: string) => {
- router.push(`/profile/edit?type=${type}`);
- };
- const goPassword = () => {
- router.push('/password');
- };
- const goPaymentAccount = () => {
- router.push('/payment-account');
- };
- const loadTelegramBind = async () => {
- 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) {
- telegramAccount.value = tg.account || '';
- }
- }
- } catch (e) {
- // ignore
- }
- };
- onMounted(() => {
- userStore.fetchUserInfo();
- loadTelegramBind();
- });
- </script>
- <style lang="scss" scoped>
- .profile-page {
- min-height: 100vh;
- background: var(--bg-primary, #121212);
- }
- .header {
- display: flex;
- align-items: center;
- justify-content: space-between;
- padding: 16px;
- color: var(--text-primary, #fff);
- font-size: 16px;
- font-weight: 600;
- .van-icon {
- font-size: 20px;
- }
- }
- .info-list {
- padding: 0 16px;
- .info-item {
- display: flex;
- align-items: center;
- justify-content: space-between;
- padding: 16px;
- background: var(--bg-card, rgba(255, 255, 255, 0.05));
- border-radius: 12px;
- margin-bottom: 12px;
- .label {
- font-size: 14px;
- color: var(--text-primary, rgba(255, 255, 255, 0.7));
- }
- .value {
- display: flex;
- align-items: center;
- gap: 8px;
- span {
- font-size: 14px;
- color: var(--text-primary, #fff);
- &.verified {
- color: #4caf50;
- }
- }
- .avatar {
- width: 40px;
- height: 40px;
- border-radius: 50%;
- object-fit: cover;
- }
- .van-icon {
- color: var(--text-tertiary, rgba(255, 255, 255, 0.3));
- }
- }
- }
- }
- </style>
|