|
|
|
@ -4,10 +4,10 @@ |
|
|
|
<view class="nav"> |
|
|
|
<view class="back" @tap="back">‹</view> |
|
|
|
<view class="title">{{ isEdit ? '编辑 i/e 资料' : '先认识一下你' }}</view> |
|
|
|
<view class="step">{{ step }}/5</view> |
|
|
|
<view class="step">{{ step }}/4</view> |
|
|
|
</view> |
|
|
|
|
|
|
|
<view class="progress"><view :style="{ width: step * 20 + '%' }"></view></view> |
|
|
|
<view class="progress"><view :style="{ width: step * 25 + '%' }"></view></view> |
|
|
|
|
|
|
|
<view class="card" v-if="step === 1"> |
|
|
|
<view class="eyebrow">Your Energy</view> |
|
|
|
@ -52,22 +52,6 @@ |
|
|
|
</view> |
|
|
|
|
|
|
|
<view class="card" v-if="step === 4"> |
|
|
|
<view class="eyebrow">Persona Cards</view> |
|
|
|
<view class="headline">上传你的人格卡片</view> |
|
|
|
<view class="card-desc">像 QQ 个人主页的形象展示。最多 5 张,别人点头像时可以看到。</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> |
|
|
|
<view class="persona-delete" @tap.stop="removePersonaImage(index)">×</view> |
|
|
|
</view> |
|
|
|
<view class="persona-add" v-if="form.personaImages.length < 5" @tap="choosePersonaImages"> |
|
|
|
<view class="plus">+</view> |
|
|
|
<view>添加图片</view> |
|
|
|
</view> |
|
|
|
</view> |
|
|
|
</view> |
|
|
|
|
|
|
|
<view class="card" v-if="step === 5"> |
|
|
|
<view class="eyebrow">Match Target</view> |
|
|
|
<view class="headline">你现在想遇见哪类人?</view> |
|
|
|
<view class="target-card" v-for="item in targetOptions" :key="item.key" :class="{ active: form.targetModePreference === item.key }" @tap="form.targetModePreference = item.key"> |
|
|
|
@ -84,7 +68,7 @@ |
|
|
|
|
|
|
|
<view class="actions"> |
|
|
|
<view class="ghost" @tap="prev" v-if="step > 1">上一步</view> |
|
|
|
<view class="solid" @tap="next">{{ step === 5 ? '进入 i/e 此刻' : '继续' }}</view> |
|
|
|
<view class="solid" @tap="next">{{ step === 4 ? '进入 i/e 此刻' : '继续' }}</view> |
|
|
|
</view> |
|
|
|
</view> |
|
|
|
</template> |
|
|
|
@ -110,8 +94,7 @@ |
|
|
|
avatarUrl: '', |
|
|
|
gender: 'unknown', |
|
|
|
intro: '', |
|
|
|
interestTags: [], |
|
|
|
personaImages: [] |
|
|
|
interestTags: [] |
|
|
|
}, |
|
|
|
tagOptions: ['慢热', '爱听歌', '夜跑', '自习', '想聊天', '想安静', '情绪低电量', '散步', '电影', '游戏', '摄影', '干饭'], |
|
|
|
targetOptions: [ |
|
|
|
@ -159,7 +142,6 @@ |
|
|
|
this.form.gender = profile.gender || 'unknown' |
|
|
|
this.form.intro = profile.intro || '' |
|
|
|
this.form.interestTags = profile.interestTags || [] |
|
|
|
this.form.personaImages = profile.personaImages || [] |
|
|
|
}, |
|
|
|
toggleTag(tag) { |
|
|
|
const index = this.form.interestTags.indexOf(tag) |
|
|
|
@ -177,45 +159,54 @@ |
|
|
|
this.form.anonymousName = this.nameSeeds[Math.floor(Math.random() * this.nameSeeds.length)] |
|
|
|
}, |
|
|
|
chooseAvatar() { |
|
|
|
uni.chooseImage({ |
|
|
|
let that = this; |
|
|
|
uni.chooseMedia({ |
|
|
|
count: 1, |
|
|
|
sizeType: ['compressed'], |
|
|
|
sourceType: ['album', 'camera'], |
|
|
|
success: async (res) => { |
|
|
|
const filePath = res.tempFilePaths && res.tempFilePaths[0] |
|
|
|
if (!filePath) return |
|
|
|
const result = await tui.uploadFile('/upload/file', filePath) |
|
|
|
const url = typeof result === 'string' ? result : (result.url || result.fileUrl || result.path || result.fullPath || result) |
|
|
|
if (url && typeof url === 'string') this.form.avatarUrl = url |
|
|
|
mediaType: ['image'], |
|
|
|
sourceType: ['camera', 'album'], |
|
|
|
camera: 'back', |
|
|
|
success(res) { |
|
|
|
that.upLoadFile(res.tempFiles[0].tempFilePath) |
|
|
|
}, |
|
|
|
fail() { |
|
|
|
uni.hideLoading(); |
|
|
|
} |
|
|
|
}) |
|
|
|
}, |
|
|
|
choosePersonaImages() { |
|
|
|
const remain = 5 - this.form.personaImages.length |
|
|
|
if (remain <= 0) { |
|
|
|
uni.showToast({ title: '最多上传 5 张', icon: 'none' }) |
|
|
|
return |
|
|
|
} |
|
|
|
uni.chooseImage({ |
|
|
|
count: remain, |
|
|
|
sizeType: ['compressed'], |
|
|
|
sourceType: ['album', 'camera'], |
|
|
|
success: async (res) => { |
|
|
|
const files = res.tempFilePaths || [] |
|
|
|
for (const filePath of files) { |
|
|
|
if (this.form.personaImages.length >= 5) break |
|
|
|
const result = await tui.uploadFile('/upload/file', filePath) |
|
|
|
const url = typeof result === 'string' ? result : (result.url || result.fileUrl || result.path || result.fullPath || result) |
|
|
|
if (url && typeof url === 'string') this.form.personaImages.push(url) |
|
|
|
} |
|
|
|
} |
|
|
|
async upLoadFile(path) { |
|
|
|
let that = this; |
|
|
|
uni.showLoading({ |
|
|
|
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 |
|
|
|
}, |
|
|
|
removePersonaImage(index) { |
|
|
|
this.form.personaImages.splice(index, 1) |
|
|
|
formData: {}, |
|
|
|
success: (uploadFileRes) => { |
|
|
|
|
|
|
|
let path = JSON.parse(uploadFileRes.data) |
|
|
|
|
|
|
|
this.form.avatarUrl = path.result |
|
|
|
}, |
|
|
|
previewPersona(index) { |
|
|
|
uni.previewImage({ urls: this.form.personaImages, current: this.form.personaImages[index] }) |
|
|
|
fail: (err) => { |
|
|
|
uni.hideLoading(); |
|
|
|
uni.showToast({ |
|
|
|
title: JSON.stringify(err), |
|
|
|
icon: 'none' |
|
|
|
}) |
|
|
|
} |
|
|
|
}); |
|
|
|
await setTimeout(res => { |
|
|
|
that.parentId = '' |
|
|
|
// uni.hideLoading(); |
|
|
|
}, 1000) |
|
|
|
}, |
|
|
|
validateStep() { |
|
|
|
if (this.step === 2 && !this.form.anonymousName.trim()) { |
|
|
|
@ -232,7 +223,7 @@ |
|
|
|
async next() { |
|
|
|
if (this.submitting) return |
|
|
|
if (!this.validateStep()) return |
|
|
|
if (this.step < 5) { |
|
|
|
if (this.step < 4) { |
|
|
|
this.step += 1 |
|
|
|
return |
|
|
|
} |
|
|
|
@ -273,7 +264,6 @@ |
|
|
|
.card { margin-top: 36rpx; padding: 38rpx 32rpx; border-radius: 46rpx; border: 1rpx solid rgba(255,255,255,.82); background: rgba(255,255,255,.64); box-shadow: 0 26rpx 80rpx rgba(96,112,160,.14); backdrop-filter: blur(26rpx); } |
|
|
|
.eyebrow { color: rgba(21,26,45,.42); font-size: 22rpx; letter-spacing: 5rpx; text-transform: uppercase; } |
|
|
|
.headline { margin-top: 16rpx; margin-bottom: 28rpx; font-size: 46rpx; line-height: 60rpx; font-weight: 800; } |
|
|
|
.card-desc { margin: -10rpx 0 24rpx; color: rgba(21,26,45,.52); font-size: 24rpx; line-height: 38rpx; } |
|
|
|
.mode-card, .target-card { display: flex; align-items: center; margin-top: 22rpx; padding: 28rpx; border-radius: 34rpx; background: rgba(238,244,255,.68); border: 2rpx solid transparent; } |
|
|
|
.mode-card.active, .target-card.active { border-color: #a9ffe7; background: rgba(223,254,244,.7); transform: scale(1.01); } |
|
|
|
.mark { width: 82rpx; height: 82rpx; margin-right: 22rpx; border-radius: 28rpx; text-align: center; line-height: 82rpx; font-size: 46rpx; font-weight: 800; } |
|
|
|
@ -298,12 +288,6 @@ |
|
|
|
.tag-grid { display: flex; flex-wrap: wrap; } |
|
|
|
.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-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; } |
|
|
|
.persona-add { display: flex; flex-direction: column; align-items: center; justify-content: center; color: rgba(21,26,45,.46); border: 2rpx dashed rgba(108,105,216,.22); box-sizing: border-box; font-size: 23rpx; } |
|
|
|
.persona-add .plus { margin-bottom: 10rpx; color: #6c69d8; font-size: 44rpx; font-weight: 800; } |
|
|
|
.actions { position: fixed; left: 32rpx; right: 32rpx; bottom: 42rpx; display: flex; gap: 18rpx; } |
|
|
|
.ghost, .solid { flex: 1; height: 96rpx; border-radius: 999rpx; text-align: center; line-height: 96rpx; font-size: 28rpx; font-weight: 800; } |
|
|
|
.ghost { color: rgba(21,26,45,.58); background: rgba(255,255,255,.68); } |
|
|
|
|