|
|
|
@ -25,10 +25,14 @@ |
|
|
|
<view class="card" v-if="step === 2"> |
|
|
|
<view class="eyebrow">Light Profile</view> |
|
|
|
<view class="headline">设置一个轻社交资料</view> |
|
|
|
<view class="avatar-wrap" @tap="chooseAvatar"> |
|
|
|
<view class="avatar-wrap" :class="{ 'avatar-wrap--auditing': avatarAuditing }" @tap="chooseAvatar"> |
|
|
|
<image class="avatar-img" v-if="form.avatarUrl" :src="form.avatarUrl" mode="aspectFill"></image> |
|
|
|
<view class="avatar-text" v-else>{{ avatarPreview }}</view> |
|
|
|
<view class="avatar-tip">点一下换头像</view> |
|
|
|
<view class="avatar-audit-mask" v-if="avatarAuditing"> |
|
|
|
<view class="avatar-audit-spinner"></view> |
|
|
|
<view>头像审核中...</view> |
|
|
|
</view> |
|
|
|
<view class="avatar-tip">{{ avatarAuditing ? '头像审核中,请稍候' : '点一下换头像' }}</view> |
|
|
|
</view> |
|
|
|
<view class="random-name" @tap="randomName">随机一个昵称</view> |
|
|
|
<input class="input" v-model="form.anonymousName" maxlength="16" placeholder="昵称,例如:南门慢跑员" /> |
|
|
|
@ -55,6 +59,10 @@ |
|
|
|
<view class="eyebrow">Persona Cards</view> |
|
|
|
<view class="headline">上传你的人格卡片</view> |
|
|
|
<view class="card-desc">最多 5 张,像个人主页的形象展示。别人点击头像时可以看到。</view> |
|
|
|
<view class="persona-audit-tip" v-if="personaAuditing"> |
|
|
|
<view class="persona-audit-spinner"></view> |
|
|
|
<text>人格卡片审核中...</text> |
|
|
|
</view> |
|
|
|
<view class="persona-grid"> |
|
|
|
<view class="persona-item" v-for="(img, index) in form.personaImages" :key="img"> |
|
|
|
<image :src="img" mode="aspectFill" @tap="previewPersona(index)"></image> |
|
|
|
@ -113,6 +121,8 @@ |
|
|
|
step: 1, |
|
|
|
isEdit: false, |
|
|
|
submitting: false, |
|
|
|
avatarAuditing: false, |
|
|
|
personaAuditing: false, |
|
|
|
profileCompleted: 0, |
|
|
|
form: { |
|
|
|
currentMode: 'i', |
|
|
|
@ -158,7 +168,7 @@ |
|
|
|
|
|
|
|
}, |
|
|
|
fail() { |
|
|
|
this.tui.toast("您未授权,图片上传功能可能会出现错误") |
|
|
|
uni.showToast({ title: '您未授权,图片上传功能可能会出现错误', icon: 'none' }) |
|
|
|
} |
|
|
|
}) |
|
|
|
}, |
|
|
|
@ -194,6 +204,7 @@ |
|
|
|
this.form.anonymousName = this.nameSeeds[Math.floor(Math.random() * this.nameSeeds.length)] |
|
|
|
}, |
|
|
|
chooseAvatar() { |
|
|
|
if (this.avatarAuditing) return |
|
|
|
let that = this; |
|
|
|
uni.chooseMedia({ |
|
|
|
count: 1, |
|
|
|
@ -209,41 +220,58 @@ |
|
|
|
}) |
|
|
|
}, |
|
|
|
async upLoadFile(path) { |
|
|
|
let that = this; |
|
|
|
this.avatarAuditing = true |
|
|
|
uni.showLoading({ |
|
|
|
title: '加载中...', |
|
|
|
title: '头像审核中...', |
|
|
|
mask: true |
|
|
|
}) |
|
|
|
let hiver_token = uni.getStorageSync("hiver_token") |
|
|
|
await uni.uploadFile({ |
|
|
|
url: that.tui.interfaceUrl() + '/upload/file', |
|
|
|
filePath: path, |
|
|
|
name: 'file', |
|
|
|
header: { |
|
|
|
"content-type": "multipart/form-data", |
|
|
|
'accessToken': hiver_token |
|
|
|
}, |
|
|
|
formData: {}, |
|
|
|
success: (uploadFileRes) => { |
|
|
|
|
|
|
|
let path = JSON.parse(uploadFileRes.data) |
|
|
|
|
|
|
|
this.form.avatarUrl = path.result |
|
|
|
}, |
|
|
|
fail: (err) => { |
|
|
|
uni.hideLoading(); |
|
|
|
uni.showToast({ |
|
|
|
title: JSON.stringify(err), |
|
|
|
icon: 'none' |
|
|
|
}) |
|
|
|
} |
|
|
|
}); |
|
|
|
await setTimeout(res => { |
|
|
|
that.parentId = '' |
|
|
|
// uni.hideLoading(); |
|
|
|
}, 1000) |
|
|
|
return new Promise((resolve) => { |
|
|
|
uni.uploadFile({ |
|
|
|
url: tui.interfaceUrl() + '/upload/file', |
|
|
|
filePath: path, |
|
|
|
name: 'file', |
|
|
|
header: { |
|
|
|
"content-type": "multipart/form-data", |
|
|
|
'accessToken': hiver_token |
|
|
|
}, |
|
|
|
formData: {}, |
|
|
|
success: (uploadFileRes) => { |
|
|
|
try { |
|
|
|
let data = JSON.parse(uploadFileRes.data || '{}') |
|
|
|
if (!data.result) { |
|
|
|
this.avatarAuditing = false |
|
|
|
uni.hideLoading() |
|
|
|
uni.showToast({ title: '头像审核未通过,请更换图片', icon: 'none' }) |
|
|
|
resolve(false) |
|
|
|
return |
|
|
|
} |
|
|
|
this.form.avatarUrl = data.result |
|
|
|
this.avatarAuditing = false |
|
|
|
uni.hideLoading() |
|
|
|
uni.showToast({ title: '头像审核通过', icon: 'none', duration: 2200 }) |
|
|
|
resolve(true) |
|
|
|
} catch (e) { |
|
|
|
this.avatarAuditing = false |
|
|
|
uni.hideLoading() |
|
|
|
uni.showToast({ title: '头像上传失败,请重试', icon: 'none' }) |
|
|
|
resolve(false) |
|
|
|
} |
|
|
|
}, |
|
|
|
fail: () => { |
|
|
|
this.avatarAuditing = false |
|
|
|
uni.hideLoading() |
|
|
|
uni.showToast({ |
|
|
|
title: '头像上传失败,请检查网络后重试', |
|
|
|
icon: 'none' |
|
|
|
}) |
|
|
|
resolve(false) |
|
|
|
} |
|
|
|
}) |
|
|
|
}) |
|
|
|
}, |
|
|
|
choosePersonaImages() { |
|
|
|
if (this.personaAuditing) return |
|
|
|
const remain = 5 - this.form.personaImages.length |
|
|
|
if (remain <= 0) { |
|
|
|
uni.showToast({ title: '最多上传 5 张', icon: 'none' }) |
|
|
|
@ -256,10 +284,18 @@ |
|
|
|
camera: 'back', |
|
|
|
success: async (res) => { |
|
|
|
const files = res.tempFiles || [] |
|
|
|
for (const file of files) { |
|
|
|
if (this.form.personaImages.length >= 5) break |
|
|
|
const url = await this.uploadPersonaFile(file.tempFilePath) |
|
|
|
if (url) this.form.personaImages.push(url) |
|
|
|
if (!files.length) return |
|
|
|
this.personaAuditing = true |
|
|
|
uni.showLoading({ title: '人格卡片审核中...', mask: true }) |
|
|
|
try { |
|
|
|
for (const file of files) { |
|
|
|
if (this.form.personaImages.length >= 5) break |
|
|
|
const url = await this.uploadPersonaFile(file.tempFilePath) |
|
|
|
if (url) this.form.personaImages.push(url) |
|
|
|
} |
|
|
|
} finally { |
|
|
|
this.personaAuditing = false |
|
|
|
uni.hideLoading() |
|
|
|
} |
|
|
|
} |
|
|
|
}) |
|
|
|
@ -267,10 +303,9 @@ |
|
|
|
uploadPersonaFile(path) { |
|
|
|
if (!path) return Promise.resolve('') |
|
|
|
const hiverToken = uni.getStorageSync('hiver_token') |
|
|
|
uni.showLoading({ title: '上传中...', mask: true }) |
|
|
|
return new Promise((resolve) => { |
|
|
|
uni.uploadFile({ |
|
|
|
url: this.tui.interfaceUrl() + '/upload/file', |
|
|
|
url: tui.interfaceUrl() + '/upload/file', |
|
|
|
filePath: path, |
|
|
|
name: 'file', |
|
|
|
header: { |
|
|
|
@ -285,8 +320,7 @@ |
|
|
|
resolve('') |
|
|
|
} |
|
|
|
}, |
|
|
|
fail: () => resolve(''), |
|
|
|
complete: () => uni.hideLoading() |
|
|
|
fail: () => resolve('') |
|
|
|
}) |
|
|
|
}) |
|
|
|
}, |
|
|
|
@ -380,10 +414,13 @@ |
|
|
|
.gender-row { display: flex; flex-wrap: wrap; } |
|
|
|
.gender-chip { height: 58rpx; line-height: 58rpx; margin: 0 14rpx 14rpx 0; padding: 0 24rpx; border-radius: 999rpx; color: rgba(21,26,45,.58); background: rgba(238,244,255,.82); font-size: 23rpx; } |
|
|
|
.gender-chip.active { color: #11162a; background: #a9ffe7; font-weight: 800; } |
|
|
|
.avatar-wrap { width: 184rpx; margin: 0 auto 30rpx; text-align: center; } |
|
|
|
.avatar-wrap { position: relative; width: 184rpx; margin: 0 auto 30rpx; text-align: center; } |
|
|
|
.avatar-wrap--auditing { pointer-events: none; } |
|
|
|
.avatar-img, .avatar-text { width: 154rpx; height: 154rpx; margin: 0 auto; border-radius: 50%; } |
|
|
|
.avatar-img { display: block; } |
|
|
|
.avatar-text { text-align: center; line-height: 154rpx; color: #11162a; background: linear-gradient(145deg, #effffb, #a9ffe7); font-size: 58rpx; font-weight: 800; } |
|
|
|
.avatar-audit-mask { position: absolute; left: 15rpx; top: 0; width: 154rpx; height: 154rpx; display: flex; flex-direction: column; align-items: center; justify-content: center; border-radius: 50%; background: rgba(21,26,45,.62); color: #fff; font-size: 21rpx; font-weight: 800; line-height: 30rpx; } |
|
|
|
.avatar-audit-spinner { width: 34rpx; height: 34rpx; margin-bottom: 10rpx; border: 4rpx solid rgba(255,255,255,.36); border-top-color: #a9ffe7; border-radius: 50%; animation: avatarAuditSpin .8s linear infinite; box-sizing: border-box; } |
|
|
|
.avatar-tip { margin-top: 14rpx; color: rgba(21,26,45,.42); font-size: 22rpx; } |
|
|
|
.random-name { width: 220rpx; height: 58rpx; margin: 0 auto 22rpx; border-radius: 999rpx; text-align: center; line-height: 58rpx; color: #6c69d8; background: rgba(139,124,255,.1); font-size: 23rpx; font-weight: 800; } |
|
|
|
.input, .textarea { width: 100%; box-sizing: border-box; border-radius: 28rpx; background: rgba(238,244,255,.78); color: #151a2d; font-size: 27rpx; } |
|
|
|
@ -393,6 +430,8 @@ |
|
|
|
.tag { margin: 0 14rpx 18rpx 0; padding: 16rpx 24rpx; border-radius: 999rpx; color: rgba(21,26,45,.62); background: rgba(238,244,255,.82); font-size: 24rpx; } |
|
|
|
.tag.active { color: #11162a; background: #a9ffe7; font-weight: 800; } |
|
|
|
.persona-grid { display: flex; flex-wrap: wrap; gap: 18rpx; } |
|
|
|
.persona-audit-tip { height: 64rpx; margin: -6rpx 0 22rpx; padding: 0 22rpx; display: flex; align-items: center; border-radius: 999rpx; color: #151a2d; background: rgba(169,255,231,.48); font-size: 24rpx; font-weight: 800; box-sizing: border-box; } |
|
|
|
.persona-audit-spinner { width: 30rpx; height: 30rpx; margin-right: 12rpx; border: 4rpx solid rgba(108,105,216,.18); border-top-color: #6c69d8; border-radius: 50%; animation: avatarAuditSpin .8s linear infinite; box-sizing: border-box; } |
|
|
|
.persona-item, .persona-add { position: relative; width: 184rpx; height: 224rpx; border-radius: 30rpx; overflow: hidden; background: rgba(238,244,255,.82); } |
|
|
|
.persona-item image { width: 100%; height: 100%; display: block; } |
|
|
|
.persona-delete { position: absolute; right: 12rpx; top: 12rpx; width: 42rpx; height: 42rpx; border-radius: 50%; text-align: center; line-height: 38rpx; color: #fff; background: rgba(21,26,45,.56); font-size: 34rpx; } |
|
|
|
@ -419,5 +458,6 @@ |
|
|
|
@keyframes creatingPulse { 0%, 100% { transform: scale(.98); } 50% { transform: scale(1.04); } } |
|
|
|
@keyframes dotFloatA { 0%, 100% { transform: translate(0, 0); } 50% { transform: translate(-10rpx, 8rpx); } } |
|
|
|
@keyframes dotFloatB { 0%, 100% { transform: translate(0, 0); } 50% { transform: translate(12rpx, -8rpx); } } |
|
|
|
@keyframes avatarAuditSpin { to { transform: rotate(360deg); } } |
|
|
|
@keyframes loadingSlide { 0% { transform: translateX(-120%); } 100% { transform: translateX(230%); } } |
|
|
|
</style> |
|
|
|
|