tianyi 4 weeks ago
parent
commit
93306b2fba
  1. 574
      package1/ieBrowser/chat.vue
  2. 340
      package1/ieBrowser/chatList.vue
  3. 79
      package1/ieBrowser/companion.vue
  4. 72
      package1/ieBrowser/fate.vue
  5. 437
      package1/ieBrowser/friends.vue
  6. 2096
      package1/ieBrowser/index.vue
  7. 106
      package1/ieBrowser/match.vue
  8. 103
      package1/ieBrowser/matching.vue
  9. 75
      package1/ieBrowser/messages.vue
  10. 119
      package1/ieBrowser/mode.vue
  11. 66
      package1/ieBrowser/settings.vue
  12. 54
      package1/ieBrowser/splash.vue
  13. 87
      package1/ieBrowser/universe.vue
  14. 61
      pages/index/index.vue

574
package1/ieBrowser/chat.vue

@ -1,41 +1,74 @@
<template>
<view class="chat-page">
<view class="room-page">
<view class="glow glow-a"></view>
<view class="glow glow-b"></view>
<view class="nav" :style="{ paddingTop: menuButtonInfo.top + 'px' }">
<view class="back" @tap="back"></view>
<view class="user">
<view class="name">奶茶研究员</view>
<view class="meta">同校 · 90% 匹配 · 在线</view>
<view class="room-user">
<view class="room-name">{{ companion.name }}</view>
<view class="room-meta">{{ roomModeText }} · {{ countdownText }} 后自然结束</view>
</view>
<view class="more">···</view>
<view class="more" @tap="showSafety = true">···</view>
</view>
<view class="topic-card">
<view class="topic-label">今日破冰问题</view>
<view class="topic-text">如果校园里突然多了一个隐藏副本你希望它是什么</view>
<view class="radio-room">
<view class="radio-orbit"></view>
<view class="radio-core">FM</view>
<view class="radio-copy">
<view class="radio-title">深夜电台陪伴中</view>
<view class="radio-sub">你们已经安静陪伴了 {{ silentMinutes }} 分钟</view>
</view>
</view>
<view class="timer-card">
<view>
<view class="timer-label">沉默陪伴模式</view>
<view class="timer-title">{{ companion.prompt }}</view>
</view>
<view class="timer-pill">{{ countdownText }}</view>
</view>
<view class="silent-modes">
<view class="silent-chip" v-for="item in silentModes" :key="item" @tap="sendPresence(item)">
{{ item }}
</view>
</view>
<view class="messages">
<view class="system-line">你们被放进同一个频道不说话也算陪伴</view>
<view class="hesitate-line">对方删掉了一句话</view>
<view class="msg-row other">
<view class="avatar">E</view>
<view class="bubble">你好你也是重度米线爱好者吗</view>
<view class="avatar" :class="roomMode">{{ companion.avatar }}</view>
<view class="bubble">{{ companion.firstMessage }}</view>
</view>
<view class="msg-row mine">
<view class="bubble">对啊但我更想知道哪家汤底最稳</view>
<view class="bubble muted">我在刚好也想安静一会</view>
</view>
<view class="hesitate-line right">对方正在犹豫输入</view>
<view class="msg-row other">
<view class="avatar">E</view>
<view class="bubble">那我们可以开一个北门米线测评局</view>
<view class="avatar" :class="roomMode">{{ companion.avatar }}</view>
<view class="bubble">就不用急着聊先一起待 15 分钟</view>
</view>
<view class="msg-row mine">
<view class="bubble strong">今晚 6 我可以带拍照技能</view>
</view>
<view class="presence-row">
<view class="presence-chip" v-for="item in presenceActions" :key="item" @tap="sendPresence(item)">
{{ item }}
</view>
</view>
<view class="input-bar">
<view class="tool"></view>
<input class="input" placeholder="输入消息..." />
<view class="emoji"></view>
<view class="send">发送</view>
<input class="input" v-model="draft" placeholder="轻轻说一句,或保持安静" />
<view class="send" @tap="sendMessage">发送</view>
</view>
<view class="safety-mask" v-if="showSafety" @tap="showSafety = false">
<view class="safety-panel" @tap.stop>
<view class="safety-title">安全与退出</view>
<view class="safety-item" @tap="report">举报不适内容</view>
<view class="safety-item" @tap="block">拉黑这个对象</view>
<view class="safety-item quiet" @tap="finishRoom">提前结束陪伴</view>
</view>
</view>
</view>
</template>
@ -46,17 +79,117 @@
return {
menuButtonInfo: {
top: 24
},
roomMode: 'i',
secondsLeft: 15 * 60,
timer: null,
draft: '',
showSafety: false,
presenceActions: ['我在', '听着呢', '慢慢说', '抱一下空气'],
silentModes: ['一起听歌', '一起倒计时', '一起自习', '一起失眠'],
companions: {
i: {
name: '月台旁的影子',
avatar: '月',
prompt: '如果今晚可以把一个念头放在操场边,你想放什么?',
firstMessage: '我刚从图书馆出来,路上风有点凉。'
},
e: {
name: '便利店灯光',
avatar: '光',
prompt: '今晚聊一个不重要的小事,越轻越好。',
firstMessage: '我刚买了夜宵,突然很想知道大家今晚都在干嘛。'
}
}
}
},
onLoad() {
computed: {
companion() {
return this.companions[this.roomMode] || this.companions.i
},
roomModeText() {
return this.roomMode === 'i' ? '安静陪伴' : '轻轻热闹'
},
silentMinutes() {
return Math.max(1, 15 - Math.ceil(this.secondsLeft / 60))
},
countdownText() {
const minutes = String(Math.floor(this.secondsLeft / 60)).padStart(2, '0')
const seconds = String(this.secondsLeft % 60).padStart(2, '0')
return `${minutes}:${seconds}`
}
},
onLoad(options) {
if (uni.getMenuButtonBoundingClientRect) {
this.menuButtonInfo = uni.getMenuButtonBoundingClientRect()
}
if (options && options.mode) {
this.roomMode = options.mode
}
this.startTimer()
},
onUnload() {
this.clearTimer()
},
methods: {
startTimer() {
this.clearTimer()
this.timer = setInterval(() => {
if (this.secondsLeft <= 0) {
this.finishRoom()
return
}
this.secondsLeft -= 1
}, 1000)
},
clearTimer() {
if (this.timer) {
clearInterval(this.timer)
this.timer = null
}
},
sendPresence(text) {
uni.showToast({
title: `已发送:${text}`,
icon: 'none'
})
},
sendMessage() {
if (!this.draft.trim()) {
uni.showToast({
title: '也可以先不说话',
icon: 'none'
})
return
}
this.draft = ''
uni.showToast({
title: '已轻轻送出',
icon: 'none'
})
},
report() {
this.showSafety = false
uni.showToast({
title: '已收到举报',
icon: 'none'
})
},
block() {
this.showSafety = false
uni.showToast({
title: '已拉黑',
icon: 'none'
})
},
finishRoom() {
this.clearTimer()
uni.redirectTo({
url: '/package1/ieBrowser/chatList'
})
},
back() {
uni.navigateBack()
uni.redirectTo({ url: '/package1/ieBrowser/index' })
}
}
}
@ -64,79 +197,256 @@
<style lang="scss" scoped>
page {
background: #fbfcff;
background: #f7f9ff;
}
.chat-page {
.room-page {
min-height: 100vh;
padding: 0 28rpx 150rpx;
padding: 0 28rpx 176rpx;
box-sizing: border-box;
color: #161b2e;
background:
radial-gradient(circle at 12% 9%, rgba(131, 255, 216, 0.28), rgba(131, 255, 216, 0) 240rpx),
linear-gradient(180deg, #ffffff 0%, #f6f8ff 100%);
radial-gradient(circle at 14% 10%, rgba(139, 124, 255, 0.2), rgba(139, 124, 255, 0) 280rpx),
radial-gradient(circle at 82% 18%, rgba(169, 255, 231, .42), rgba(169, 255, 231, 0) 320rpx),
linear-gradient(180deg, #fbfdff 0%, #eef4ff 64%, #fff4e8 100%);
position: relative;
overflow: hidden;
}
.room-page::before {
content: '';
position: absolute;
inset: 0;
pointer-events: none;
opacity: .1;
background-image: radial-gradient(circle, rgba(22,27,46,.7) 0 1rpx, transparent 1rpx);
background-size: 44rpx 44rpx;
animation: noiseFloat 8s steps(5) infinite;
}
.glow {
position: absolute;
border-radius: 50%;
filter: blur(10rpx);
}
.glow-a {
right: -120rpx;
top: 210rpx;
width: 300rpx;
height: 300rpx;
background: rgba(169, 255, 231, 0.34);
}
.glow-b {
left: -150rpx;
bottom: 180rpx;
width: 360rpx;
height: 360rpx;
background: rgba(255, 184, 209, 0.22);
}
.nav {
position: relative;
z-index: 1;
height: 96rpx;
display: flex;
align-items: center;
}
.back {
width: 58rpx;
font-size: 56rpx;
.back,
.more {
width: 62rpx;
color: rgba(22, 27, 46, 0.62);
font-size: 54rpx;
line-height: 56rpx;
}
.user {
.more {
text-align: right;
font-size: 34rpx;
}
.room-user {
flex: 1;
text-align: center;
}
.name {
font-size: 32rpx;
font-weight: 900;
.room-name {
font-size: 31rpx;
font-weight: 800;
}
.meta {
margin-top: 6rpx;
color: #8c9995;
.room-meta {
margin-top: 8rpx;
color: rgba(22, 27, 46, 0.46);
font-size: 21rpx;
}
.more {
width: 58rpx;
text-align: right;
font-size: 34rpx;
font-weight: 900;
.timer-card,
.topic-card {
position: relative;
z-index: 1;
border: 1rpx solid rgba(255, 255, 255, 0.78);
background: rgba(255, 255, 255, 0.62);
backdrop-filter: blur(24rpx);
box-shadow: 0 20rpx 64rpx rgba(96, 112, 160, 0.12);
}
.topic-card {
margin-top: 12rpx;
padding: 24rpx;
border-radius: 28rpx;
background: linear-gradient(135deg, #111, #35413f);
color: #fff;
box-shadow: 0 18rpx 36rpx rgba(33, 45, 72, 0.12);
.timer-card {
display: flex;
align-items: center;
justify-content: space-between;
margin-top: 22rpx;
padding: 30rpx;
border-radius: 34rpx;
}
.radio-room {
position: relative;
z-index: 1;
display: flex;
align-items: center;
margin-top: 18rpx;
padding: 34rpx;
border-radius: 44rpx;
background: rgba(255,255,255,.58);
border: 1rpx solid rgba(255,255,255,.78);
backdrop-filter: blur(24rpx);
box-shadow: 0 24rpx 72rpx rgba(96,112,160,.13);
overflow: hidden;
}
.radio-orbit {
position: absolute;
right: -40rpx;
top: -60rpx;
width: 260rpx;
height: 260rpx;
border-radius: 50%;
border: 1rpx solid rgba(139,124,255,.16);
animation: radioSpin 16s linear infinite;
}
.radio-core {
width: 108rpx;
height: 108rpx;
margin-right: 24rpx;
border-radius: 50%;
text-align: center;
line-height: 108rpx;
color: #11162a;
background: linear-gradient(145deg, #ffffff, #a9ffe7);
font-size: 30rpx;
font-weight: 800;
box-shadow: 0 18rpx 48rpx rgba(169,255,231,.3);
animation: breathe 3s ease-in-out infinite;
}
.radio-copy {
position: relative;
z-index: 1;
}
.radio-title {
font-size: 32rpx;
font-weight: 800;
}
.radio-sub {
margin-top: 10rpx;
color: rgba(22,27,46,.52);
font-size: 24rpx;
}
.silent-modes {
position: relative;
z-index: 1;
display: flex;
overflow-x: auto;
white-space: nowrap;
margin-top: 22rpx;
}
.silent-chip {
flex-shrink: 0;
margin-right: 14rpx;
padding: 16rpx 24rpx;
border-radius: 999rpx;
color: rgba(22,27,46,.62);
background: rgba(255,255,255,.62);
border: 1rpx solid rgba(255,255,255,.72);
backdrop-filter: blur(18rpx);
font-size: 23rpx;
}
.timer-label,
.topic-label {
color: #bdfce9;
color: #6c69d8;
font-size: 22rpx;
font-weight: 900;
}
.timer-title {
margin-top: 12rpx;
font-size: 30rpx;
font-weight: 800;
}
.timer-pill {
width: 126rpx;
height: 70rpx;
border-radius: 999rpx;
text-align: center;
line-height: 70rpx;
color: #09101f;
background: #dffef4;
font-size: 28rpx;
font-weight: 800;
}
.topic-card {
margin-top: 24rpx;
padding: 26rpx;
border-radius: 30rpx;
}
.topic-text {
margin-top: 10rpx;
margin-top: 12rpx;
color: rgba(22, 27, 46, 0.72);
font-size: 27rpx;
font-weight: 800;
line-height: 42rpx;
}
.messages {
position: relative;
z-index: 1;
padding-top: 34rpx;
}
.system-line {
width: 560rpx;
margin: 0 auto 30rpx;
text-align: center;
color: rgba(22, 27, 46, 0.36);
font-size: 22rpx;
line-height: 34rpx;
}
.hesitate-line {
width: 260rpx;
margin: 0 auto 24rpx;
padding: 8rpx 18rpx;
border-radius: 999rpx;
color: rgba(22,27,46,.36);
background: rgba(255,255,255,.46);
font-size: 20rpx;
animation: fadeHint 2.8s ease-in-out infinite;
}
.hesitate-line.right {
margin-right: 18rpx;
}
.msg-row {
display: flex;
align-items: flex-start;
@ -152,75 +462,163 @@
height: 72rpx;
margin-right: 16rpx;
border-radius: 50%;
background: #ffe69a;
color: #a45c00;
text-align: center;
line-height: 72rpx;
font-size: 28rpx;
font-weight: 900;
font-size: 27rpx;
font-weight: 800;
}
.avatar.i {
color: #f7f4ff;
background: linear-gradient(145deg, #8b7cff, #dde7ff);
}
.avatar.e {
color: #07101e;
background: linear-gradient(145deg, #a9ffe7, #fff0b8);
}
.bubble {
max-width: 480rpx;
max-width: 500rpx;
padding: 22rpx 26rpx;
border-radius: 28rpx;
background: #fff;
box-shadow: 0 14rpx 30rpx rgba(33, 45, 72, 0.08);
color: #26322f;
border: 1rpx solid rgba(255, 255, 255, 0.78);
border-radius: 30rpx;
background: rgba(255, 255, 255, 0.62);
color: rgba(22, 27, 46, 0.72);
font-size: 27rpx;
line-height: 42rpx;
}
.mine .bubble {
background: #111;
color: #fff;
color: #09101f;
background: #dffef4;
}
.bubble.muted {
background: rgba(223, 254, 244, 0.88);
}
.presence-row {
position: fixed;
left: 28rpx;
right: 28rpx;
bottom: 132rpx;
z-index: 10;
display: flex;
overflow-x: auto;
white-space: nowrap;
}
.bubble.strong {
background: linear-gradient(135deg, #7f6cff, #3f2dcf);
.presence-chip {
flex-shrink: 0;
height: 58rpx;
line-height: 58rpx;
padding: 0 22rpx;
margin-right: 14rpx;
border-radius: 999rpx;
color: rgba(22, 27, 46, 0.58);
background: rgba(255, 255, 255, 0.62);
box-shadow: 0 12rpx 30rpx rgba(96, 112, 160, .1);
font-size: 23rpx;
}
.input-bar {
position: fixed;
left: 24rpx;
right: 24rpx;
bottom: 34rpx;
height: 94rpx;
padding: 12rpx;
bottom: 30rpx;
z-index: 10;
height: 88rpx;
padding: 10rpx;
box-sizing: border-box;
border: 1rpx solid rgba(255, 255, 255, 0.78);
border-radius: 999rpx;
background: rgba(255, 255, 255, 0.96);
box-shadow: 0 16rpx 42rpx rgba(33, 45, 72, 0.12);
background: rgba(255, 255, 255, 0.72);
backdrop-filter: blur(18rpx);
display: flex;
align-items: center;
}
.tool,
.emoji {
width: 58rpx;
text-align: center;
font-size: 34rpx;
color: #6c7a75;
}
.input {
flex: 1;
height: 70rpx;
padding: 0 20rpx;
height: 66rpx;
padding: 0 24rpx;
border-radius: 999rpx;
background: #f3f6f8;
font-size: 26rpx;
color: #161b2e;
background: rgba(238, 244, 255, 0.72);
font-size: 25rpx;
}
.send {
height: 64rpx;
line-height: 64rpx;
height: 66rpx;
line-height: 66rpx;
margin-left: 10rpx;
padding: 0 24rpx;
padding: 0 26rpx;
border-radius: 999rpx;
background: #111;
color: #fff;
color: #09101f;
background: #a9ffe7;
font-size: 24rpx;
font-weight: 900;
font-weight: 800;
}
.safety-mask {
position: fixed;
left: 0;
right: 0;
top: 0;
bottom: 0;
z-index: 20;
display: flex;
align-items: flex-end;
padding: 28rpx;
background: rgba(22, 27, 46, 0.18);
backdrop-filter: blur(18rpx);
box-sizing: border-box;
}
.safety-panel {
width: 100%;
padding: 30rpx;
border-radius: 38rpx;
background: rgba(255, 255, 255, 0.86);
box-sizing: border-box;
}
.safety-title {
margin-bottom: 18rpx;
font-size: 30rpx;
font-weight: 800;
}
.safety-item {
height: 86rpx;
line-height: 86rpx;
border-top: 1rpx solid rgba(22, 27, 46, 0.08);
color: rgba(22, 27, 46, 0.72);
font-size: 26rpx;
}
.safety-item.quiet {
color: #6c69d8;
}
@keyframes noiseFloat {
0%, 100% { transform: translate3d(0,0,0); }
50% { transform: translate3d(12rpx,-8rpx,0); }
}
@keyframes radioSpin {
from { transform: rotate(0); }
to { transform: rotate(360deg); }
}
@keyframes breathe {
0%, 100% { transform: scale(.98); }
50% { transform: scale(1.05); }
}
@keyframes fadeHint {
0%, 100% { opacity: .38; transform: translateY(0); }
50% { opacity: .82; transform: translateY(-4rpx); }
}
</style>

340
package1/ieBrowser/chatList.vue

@ -1,39 +1,47 @@
<template>
<view class="chat-list-page">
<view class="records-page">
<view class="glow glow-a"></view>
<view class="nav" :style="{ paddingTop: menuButtonInfo.top + 'px' }">
<view class="back" @tap="back"></view>
<view class="title">聊天记录</view>
<view class="filter">同校</view>
<view class="title">感受记录</view>
<view class="filter">仅自己可见</view>
</view>
<view class="summary-card">
<view>
<view class="summary-title">今天有 5 个新话题</view>
<view class="summary-sub">别让有趣的人掉进已读不回</view>
<view class="summary-label">Tonight Archive</view>
<view class="summary-title">今晚被轻轻接住了 2 </view>
<view class="summary-sub">这里不保存完整聊天只留下当时的情绪温度</view>
</view>
<view class="bubble"></view>
<view class="moon"></view>
</view>
<view class="tabs">
<view class="tab active">全部</view>
<view class="tab">找搭子</view>
<view class="tab">新朋友</view>
<view class="feeling-picker">
<view class="section-title">结束后你现在感觉</view>
<view class="feeling-row">
<view class="feeling-chip" v-for="item in feelings" :key="item"
:class="{ active: currentFeeling === item }" @tap="currentFeeling = item">
{{ item }}
</view>
</view>
</view>
<view class="chat-card" v-for="item in chats" :key="item.name" @tap="goChat">
<view class="avatar" :class="item.type">{{ item.type.toUpperCase() }}</view>
<view class="chat-main">
<view class="chat-line">
<text class="name">{{ item.name }}</text>
<text class="time">{{ item.time }}</text>
</view>
<view class="message">{{ item.message }}</view>
<view class="tags">
<text>{{ item.scene }}</text>
<text>{{ item.status }}</text>
<view class="record-card" v-for="item in records" :key="item.time">
<view class="record-top">
<view class="record-orb" :class="item.type">{{ item.type }}</view>
<view>
<view class="record-name">{{ item.name }}</view>
<view class="record-meta">{{ item.time }} · {{ item.duration }}</view>
</view>
</view>
<view class="unread" v-if="item.unread">{{ item.unread }}</view>
<view class="record-text">{{ item.feeling }}</view>
<view class="record-tags">
<text v-for="tag in item.tags" :key="tag">{{ tag }}</text>
</view>
</view>
<view class="empty-note">
不是消息列表也不是社交关系只是给夜晚留一点柔软的痕迹
</view>
</view>
</template>
@ -45,30 +53,29 @@
menuButtonInfo: {
top: 24
},
chats: [{
name: '橘子汽水',
type: 'e',
time: '刚刚',
message: '北门那家米线你去过吗?我想找个试吃搭子',
scene: '饭搭子',
status: '正在输入',
unread: 2
}, {
name: '凌晨两点半',
currentFeeling: '轻了一点',
feelings: ['轻了一点', '还是安静', '被听见了', '想睡了'],
records: [{
type: 'i',
time: '14:20',
message: '电影社今晚放映,可以一起坐后排安静看。',
scene: '电影搭子',
status: '同频 88%',
unread: 0
name: '月台旁的影子',
time: '23:18',
duration: '15 分钟',
feeling: '对方没有催我讲话,沉默变得没那么尴尬。',
tags: ['安静陪伴', '想安静', '半匿名']
}, {
type: 'e',
name: '便利店灯光',
time: '21:42',
duration: '12 分钟',
feeling: '聊了一个很小的夜宵话题,心情被拉亮了一点。',
tags: ['轻轻热闹', '想说话', '限时']
}, {
name: 'DChuo',
type: 'i',
name: '耳机里的风',
time: '昨天',
message: '明天图书馆三楼还有位置吗?',
scene: '自习搭子',
status: '已互关',
unread: 1
duration: '15 分钟',
feeling: '像有人坐在旁边,不需要解释为什么低落。',
tags: ['慢回复', '听着呢', '低压力']
}]
}
},
@ -79,12 +86,7 @@
},
methods: {
back() {
uni.navigateBack()
},
goChat() {
uni.navigateTo({
url: '/package1/ieBrowser/chat'
})
uni.redirectTo({ url: '/package1/ieBrowser/index' })
}
}
}
@ -92,26 +94,44 @@
<style lang="scss" scoped>
page {
background: #f6f8ff;
background: #f7f9ff;
}
.chat-list-page {
.records-page {
min-height: 100vh;
padding: 0 28rpx 48rpx;
background:
radial-gradient(circle at 14% 8%, rgba(131, 255, 216, 0.3), rgba(131, 255, 216, 0) 250rpx),
linear-gradient(180deg, #fcfdff 0%, #f3f6ff 100%);
padding: 0 28rpx 56rpx;
box-sizing: border-box;
color: #161b2e;
background:
radial-gradient(circle at 14% 8%, rgba(139, 124, 255, 0.2), rgba(139, 124, 255, 0) 280rpx),
radial-gradient(circle at 86% 18%, rgba(169, 255, 231, 0.38), rgba(169, 255, 231, 0) 320rpx),
linear-gradient(180deg, #fbfdff 0%, #eef4ff 62%, #fff4e8 100%);
position: relative;
overflow: hidden;
}
.glow {
position: absolute;
right: -120rpx;
top: 240rpx;
width: 320rpx;
height: 320rpx;
border-radius: 50%;
background: rgba(255, 184, 209, 0.26);
filter: blur(10rpx);
}
.nav {
height: 88rpx;
position: relative;
z-index: 1;
height: 92rpx;
display: flex;
align-items: center;
}
.back {
width: 58rpx;
color: rgba(22, 27, 46, 0.62);
font-size: 56rpx;
line-height: 56rpx;
}
@ -119,7 +139,7 @@
.title {
flex: 1;
font-size: 34rpx;
font-weight: 900;
font-weight: 800;
}
.filter {
@ -127,156 +147,170 @@
line-height: 54rpx;
padding: 0 22rpx;
border-radius: 999rpx;
background: #111;
color: #fff;
font-size: 24rpx;
font-weight: 900;
color: #09101f;
background: #a9ffe7;
font-size: 22rpx;
font-weight: 700;
}
.summary-card,
.feeling-picker,
.record-card {
position: relative;
z-index: 1;
border: 1rpx solid rgba(255, 255, 255, 0.78);
background: rgba(255, 255, 255, 0.62);
backdrop-filter: blur(24rpx);
box-shadow: 0 20rpx 64rpx rgba(96, 112, 160, 0.12);
}
.summary-card {
display: flex;
align-items: center;
justify-content: space-between;
padding: 34rpx;
border-radius: 38rpx;
background: linear-gradient(135deg, #111 0%, #35413f 100%);
color: #fff;
box-shadow: 0 22rpx 46rpx rgba(30, 43, 50, 0.14);
border-radius: 42rpx;
}
.summary-label {
color: #6c69d8;
font-size: 21rpx;
letter-spacing: 3rpx;
}
.summary-title {
font-size: 36rpx;
font-weight: 900;
margin-top: 14rpx;
font-size: 40rpx;
line-height: 52rpx;
font-weight: 800;
}
.summary-sub {
margin-top: 10rpx;
color: rgba(255, 255, 255, 0.72);
width: 460rpx;
margin-top: 12rpx;
color: rgba(22, 27, 46, 0.52);
font-size: 24rpx;
line-height: 38rpx;
}
.bubble {
width: 96rpx;
height: 96rpx;
border-radius: 32rpx;
background: linear-gradient(135deg, #bdfce9, #ffdf75);
color: #111;
.moon {
width: 104rpx;
height: 104rpx;
border-radius: 50%;
text-align: center;
line-height: 96rpx;
font-size: 40rpx;
font-weight: 900;
line-height: 104rpx;
color: #09101f;
background: linear-gradient(145deg, #effffb, #a9ffe7);
font-size: 34rpx;
font-weight: 800;
}
.feeling-picker {
margin-top: 28rpx;
padding: 28rpx;
border-radius: 34rpx;
}
.section-title {
margin-bottom: 20rpx;
font-size: 28rpx;
font-weight: 800;
}
.tabs {
.feeling-row {
display: flex;
margin: 28rpx 0;
padding: 8rpx;
border-radius: 999rpx;
background: rgba(255, 255, 255, 0.9);
box-shadow: 0 14rpx 30rpx rgba(33, 45, 72, 0.07);
flex-wrap: wrap;
}
.tab {
flex: 1;
.feeling-chip {
height: 58rpx;
line-height: 58rpx;
text-align: center;
padding: 0 22rpx;
margin: 0 14rpx 14rpx 0;
border-radius: 999rpx;
color: #71807b;
font-size: 24rpx;
font-weight: 900;
color: rgba(22, 27, 46, 0.55);
background: rgba(255, 255, 255, 0.58);
font-size: 23rpx;
}
.tab.active {
background: #111;
color: #fff;
.feeling-chip.active {
color: #09101f;
background: #a9ffe7;
}
.chat-card {
.record-card {
margin-top: 22rpx;
padding: 28rpx;
border-radius: 34rpx;
}
.record-top {
display: flex;
align-items: center;
margin-bottom: 18rpx;
padding: 24rpx;
border-radius: 34rpx;
background: rgba(255, 255, 255, 0.94);
box-shadow: 0 18rpx 38rpx rgba(33, 45, 72, 0.07);
}
.avatar {
width: 88rpx;
height: 88rpx;
.record-orb {
width: 78rpx;
height: 78rpx;
margin-right: 18rpx;
border-radius: 50%;
text-align: center;
line-height: 88rpx;
font-size: 34rpx;
font-weight: 900;
}
.avatar.i {
background: #c9fff0;
color: #08705c;
}
.avatar.e {
background: #ffe69a;
color: #a45c00;
line-height: 78rpx;
font-size: 30rpx;
font-weight: 800;
}
.chat-main {
flex: 1;
margin-left: 20rpx;
min-width: 0;
.record-orb.i {
color: #f7f4ff;
background: linear-gradient(145deg, #8b7cff, #dde7ff);
}
.chat-line {
display: flex;
align-items: center;
.record-orb.e {
color: #07101e;
background: linear-gradient(145deg, #a9ffe7, #fff0b8);
}
.name {
flex: 1;
font-size: 30rpx;
font-weight: 900;
.record-name {
font-size: 29rpx;
font-weight: 800;
}
.time {
color: #98a4a0;
.record-meta {
margin-top: 8rpx;
color: rgba(22, 27, 46, 0.44);
font-size: 22rpx;
}
.message {
margin-top: 8rpx;
color: #53615d;
font-size: 24rpx;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
.record-text {
margin-top: 22rpx;
color: rgba(22, 27, 46, 0.72);
font-size: 26rpx;
line-height: 42rpx;
}
.tags {
margin-top: 12rpx;
.record-tags {
margin-top: 20rpx;
}
.tags text {
margin-right: 8rpx;
padding: 4rpx 10rpx;
.record-tags text {
display: inline-block;
height: 42rpx;
line-height: 42rpx;
padding: 0 16rpx;
margin: 0 10rpx 10rpx 0;
border-radius: 999rpx;
background: rgba(127, 108, 255, 0.1);
color: #7f6cff;
color: #6c69d8;
background: rgba(139, 124, 255, 0.1);
font-size: 20rpx;
font-weight: 900;
}
.unread {
min-width: 34rpx;
height: 34rpx;
line-height: 34rpx;
padding: 0 8rpx;
border-radius: 999rpx;
background: #ff3b57;
color: #fff;
.empty-note {
position: relative;
z-index: 1;
width: 560rpx;
margin: 34rpx auto 0;
text-align: center;
font-size: 20rpx;
font-weight: 900;
color: rgba(22, 27, 46, 0.36);
font-size: 23rpx;
line-height: 38rpx;
}
</style>

79
package1/ieBrowser/companion.vue

@ -0,0 +1,79 @@
<template>
<view class="card-page">
<view class="top-safe" :style="{ height: menuButtonInfo.top + 'px' }"></view>
<view class="nav">
<view class="back" @tap="back"></view>
<view class="nav-title">人格卡</view>
<view class="ghost"></view>
</view>
<view class="label">半匿名陪伴对象</view>
<view class="companion-card">
<view class="orb" :class="mode">{{ companion.avatar }}</view>
<view class="name">{{ companion.name }}</view>
<view class="state">{{ companion.state }}</view>
<view class="quote">{{ companion.quote }}</view>
<view class="tags">
<text>{{ modeText }}</text>
<text>限时 15 分钟</text>
<text>不留完整记录</text>
</view>
</view>
<view class="actions">
<view class="ghost" @tap="skip">轻轻划过</view>
<view class="solid" @tap="enter">进入陪伴房间</view>
</view>
</view>
</template>
<script>
export default {
data() {
return {
mode: 'i',
menuButtonInfo: { top: 44 },
pool: {
i: { name: '月台旁的影子', avatar: '月', state: '在图书馆发呆', quote: '可以安静待 15 分钟,不用急着找话题。' },
e: { name: '便利店灯光', avatar: '光', state: '想聊点不重要的', quote: '要不要交换一句今天最荒唐的小事?' }
}
}
},
computed: {
companion() { return this.pool[this.mode] || this.pool.i },
modeText() { return this.mode === 'e' ? '轻轻热闹' : '安静陪伴' }
},
onLoad(options) {
if (uni.getMenuButtonBoundingClientRect) this.menuButtonInfo = uni.getMenuButtonBoundingClientRect()
this.mode = options.mode || 'i'
},
methods: {
enter() { uni.redirectTo({ url: '/package1/ieBrowser/chat?mode=' + this.mode }) },
skip() { uni.redirectTo({ url: '/package1/ieBrowser/index' }) },
back() { uni.redirectTo({ url: '/package1/ieBrowser/index' }) }
}
}
</script>
<style lang="scss" scoped>
page { background: #f7f9ff; }
.card-page { min-height: 100vh; padding: 0 32rpx 70rpx; box-sizing: border-box; color: #161b2e; background: radial-gradient(circle at 50% 30%, rgba(169,255,231,.45), transparent 360rpx), radial-gradient(circle at 85% 12%, rgba(255,184,209,.28), transparent 320rpx), linear-gradient(180deg, #fbfdff, #eef4ff 60%, #fff4e8); }
.nav { height: 90rpx; display: flex; align-items: center; }
.back, .ghost { width: 70rpx; font-size: 56rpx; color: rgba(22,27,46,.55); }
.nav-title { flex: 1; text-align: center; font-size: 30rpx; font-weight: 800; }
.label { margin-top: 20rpx; color: rgba(22,27,46,.42); font-size: 23rpx; letter-spacing: 4rpx; text-transform: uppercase; }
.companion-card { margin-top: 54rpx; padding: 48rpx 36rpx; border-radius: 56rpx; border: 1rpx solid rgba(255,255,255,.82); background: rgba(255,255,255,.64); backdrop-filter: blur(28rpx); box-shadow: 0 30rpx 90rpx rgba(96,112,160,.16); text-align: center; animation: cardIn .58s ease both; }
.orb { width: 168rpx; height: 168rpx; margin: 0 auto; border-radius: 50%; text-align: center; line-height: 168rpx; font-size: 58rpx; font-weight: 800; }
.orb.i { color: #f7f4ff; background: linear-gradient(145deg, #8b7cff, #dde7ff); box-shadow: 0 22rpx 68rpx rgba(139,124,255,.25); }
.orb.e { color: #11162a; background: linear-gradient(145deg, #a9ffe7, #fff0b8); }
.name { margin-top: 30rpx; font-size: 42rpx; font-weight: 800; }
.state { margin-top: 12rpx; color: rgba(22,27,46,.48); font-size: 24rpx; }
.quote { margin-top: 34rpx; padding: 30rpx; border-radius: 32rpx; background: rgba(255,255,255,.58); color: rgba(22,27,46,.72); font-size: 28rpx; line-height: 44rpx; text-align: left; }
.tags { display: flex; flex-wrap: wrap; justify-content: center; margin-top: 28rpx; }
.tags text { margin: 0 8rpx 12rpx; padding: 8rpx 16rpx; border-radius: 999rpx; color: #6c69d8; background: rgba(139,124,255,.1); font-size: 21rpx; }
.actions { position: fixed; left: 32rpx; right: 32rpx; bottom: 42rpx; display: flex; gap: 18rpx; }
.ghost, .solid { flex: 1; height: 94rpx; border-radius: 999rpx; text-align: center; line-height: 94rpx; font-size: 26rpx; font-weight: 800; }
.ghost { color: rgba(22,27,46,.56); background: rgba(255,255,255,.58); box-shadow: 0 18rpx 48rpx rgba(96,112,160,.1); }
.solid { color: #11162a; background: linear-gradient(135deg, #ffffff, #a9ffe7); box-shadow: 0 24rpx 58rpx rgba(169,255,231,.3); animation: breath 2.8s ease-in-out infinite; }
.ghost:active, .solid:active { transform: scale(.97); }
@keyframes cardIn { from { opacity: 0; transform: translateY(28rpx) scale(.98); } to { opacity: 1; transform: translateY(0) scale(1); } }
@keyframes breath { 0%, 100% { transform: scale(1); } 50% { transform: scale(1.018); } }
</style>

72
package1/ieBrowser/fate.vue

@ -0,0 +1,72 @@
<template>
<view class="fate-page">
<view class="top-safe" :style="{ height: menuButtonInfo.top + 'px' }"></view>
<view class="nav">
<view class="back" @tap="back"></view>
<view class="title">今日缘分</view>
<view class="ghost"></view>
</view>
<view class="hero">
<view class="hero-title">今天的 3 次轻连接</view>
<view class="hero-sub">它们不会变成关系压力只留下一点情绪轨迹</view>
</view>
<view class="timeline">
<view class="line"></view>
<view class="fate-card" v-for="item in fates" :key="item.time">
<view class="node" :class="item.type">{{ item.type }}</view>
<view class="card-main">
<view class="card-top">
<text class="name">{{ item.name }}</text>
<text class="time">{{ item.time }}</text>
</view>
<view class="feeling">{{ item.feeling }}</view>
<view class="remeet" v-if="item.remeet">24 小时内可再遇见一次</view>
</view>
</view>
</view>
</view>
</template>
<script>
export default {
data() {
return {
menuButtonInfo: { top: 44 },
fates: [
{ type: 'i', name: '月台旁的影子', time: '23:18', feeling: '沉默不尴尬,像有人坐在旁边。', remeet: true },
{ type: 'e', name: '便利店灯光', time: '21:42', feeling: '聊了一句夜宵废话,心情被拉亮一点。', remeet: false },
{ type: 'i', name: '耳机里的风', time: '昨天', feeling: '不用解释低落,也被轻轻听见。', remeet: false }
]
}
},
onLoad() {
if (uni.getMenuButtonBoundingClientRect) this.menuButtonInfo = uni.getMenuButtonBoundingClientRect()
},
methods: {
back() { uni.redirectTo({ url: '/package1/ieBrowser/index' }) }
}
}
</script>
<style lang="scss" scoped>
page { background: #f7f9ff; }
.fate-page { min-height: 100vh; padding: 0 30rpx 60rpx; box-sizing: border-box; color: #151a2d; background: radial-gradient(circle at 84% 12%, rgba(139,124,255,.22), transparent 300rpx), linear-gradient(180deg, #fbfdff, #eef4ff); }
.nav { height: 90rpx; display: flex; align-items: center; }
.back, .ghost { width: 70rpx; font-size: 56rpx; color: rgba(21,26,45,.64); }
.title { flex: 1; text-align: center; font-size: 31rpx; font-weight: 800; }
.hero { margin-top: 22rpx; padding: 36rpx; border-radius: 44rpx; background: rgba(255,255,255,.58); border: 1rpx solid rgba(255,255,255,.86); backdrop-filter: blur(24rpx); }
.hero-title { font-size: 44rpx; font-weight: 800; }
.hero-sub { margin-top: 14rpx; color: rgba(21,26,45,.52); font-size: 25rpx; line-height: 40rpx; }
.timeline { position: relative; margin-top: 36rpx; }
.line { position: absolute; left: 37rpx; top: 30rpx; bottom: 30rpx; width: 2rpx; background: rgba(139,124,255,.2); }
.fate-card { position: relative; display: flex; margin-bottom: 24rpx; }
.node { z-index: 1; width: 76rpx; height: 76rpx; border-radius: 50%; text-align: center; line-height: 76rpx; font-size: 30rpx; font-weight: 800; }
.node.i { color: #fff; background: #7771d8; }
.node.e { color: #11162a; background: #a9ffe7; }
.card-main { flex: 1; margin-left: 20rpx; padding: 28rpx; border-radius: 34rpx; background: rgba(255,255,255,.64); box-shadow: 0 22rpx 54rpx rgba(96,112,160,.12); }
.card-top { display: flex; }
.name { flex: 1; font-size: 28rpx; font-weight: 800; }
.time { color: rgba(21,26,45,.4); font-size: 22rpx; }
.feeling { margin-top: 14rpx; color: rgba(21,26,45,.62); font-size: 25rpx; line-height: 40rpx; }
.remeet { display: inline-block; margin-top: 18rpx; padding: 8rpx 18rpx; border-radius: 999rpx; color: #11162a; background: #dffef4; font-size: 21rpx; }
</style>

437
package1/ieBrowser/friends.vue

@ -1,43 +1,57 @@
<template>
<view class="friends-page">
<view class="archive-page">
<view class="glow glow-a"></view>
<view class="glow glow-b"></view>
<view class="nav" :style="{ paddingTop: menuButtonInfo.top + 'px' }">
<view class="back" @tap="back"></view>
<view class="title">好友列表</view>
<view class="add"></view>
<view class="title">我的夜间档案</view>
<view class="safe-dot">Safe</view>
</view>
<view class="profile-card">
<view class="profile-title">我的社交雷达</view>
<view class="profile-desc">已连接 28 位同校同学今天有 6 位正在找搭子</view>
<view class="radar">
<view class="radar-dot dot1"></view>
<view class="radar-dot dot2"></view>
<view class="radar-dot dot3"></view>
<view class="avatar-orb"></view>
<view class="profile-title">半匿名漂流者</view>
<view class="profile-desc">不经营人设不展示粉丝这里只记录你更喜欢怎样被陪伴</view>
<view class="profile-stats">
<view>
<text class="stat-num">3</text>
<text class="stat-label">今日机会</text>
</view>
<view>
<text class="stat-num">15m</text>
<text class="stat-label">默认限时</text>
</view>
<view>
<text class="stat-num">0</text>
<text class="stat-label">公开资料</text>
</view>
</view>
</view>
<view class="group-tabs">
<view class="group-tab active">全部好友</view>
<view class="group-tab">饭搭子</view>
<view class="group-tab">学习搭子</view>
<view class="section-card">
<view class="section-title">此刻偏好</view>
<view class="preference-grid">
<view class="preference-card" v-for="item in preferences" :key="item.title">
<view class="preference-title">{{ item.title }}</view>
<view class="preference-desc">{{ item.desc }}</view>
</view>
</view>
</view>
<view class="friend-card" v-for="friend in friends" :key="friend.name" @tap="goChat">
<view class="avatar" :class="friend.type">
{{ friend.type.toUpperCase() }}
<view class="online" v-if="friend.online"></view>
</view>
<view class="friend-main">
<view class="friend-line">
<text class="friend-name">{{ friend.name }}</text>
<text class="friend-type">{{ friend.type.toUpperCase() }}</text>
</view>
<view class="friend-status">{{ friend.status }}</view>
<view class="friend-tags">
<text v-for="tag in friend.tags" :key="tag">{{ tag }}</text>
<view class="section-card">
<view class="section-title">安全设置</view>
<view class="setting-row" v-for="item in settings" :key="item.title" @tap="handleSetting(item)">
<view>
<view class="setting-title">{{ item.title }}</view>
<view class="setting-desc">{{ item.desc }}</view>
</view>
<view class="setting-arrow"></view>
</view>
<view class="chat-btn"></view>
</view>
<view class="principle-card">
<view class="principle-title">产品原则</view>
<view class="principle-line" v-for="item in principles" :key="item">{{ item }}</view>
</view>
</view>
</template>
@ -49,31 +63,35 @@
menuButtonInfo: {
top: 24
},
friends: [{
name: '橘子汽水',
type: 'e',
online: true,
status: '正在寻找今晚饭搭子',
tags: ['北门', '新店', '话题王']
preferences: [{
title: '更常选择 i',
desc: '安静、慢回复、允许沉默。'
}, {
name: 'DChuo',
type: 'i',
online: true,
status: '图书馆三楼自习中',
tags: ['自习', '安静', '高匹配']
title: '夜间更活跃',
desc: '22:00 后更需要轻陪伴。'
}, {
name: '奶茶研究员',
type: 'e',
online: false,
status: '收藏了 12 家校园奶茶',
tags: ['探店', '拍照', '奶茶']
title: '记录不留全文',
desc: '只保留情绪,不保存完整聊天。'
}, {
name: '凌晨两点半',
type: 'i',
online: false,
status: '想找一个电影搭子',
tags: ['电影', '散步', '慢热']
}]
title: '不开放主页',
desc: '没有访客、关注、粉丝和点赞。'
}],
settings: [{
title: '举报记录',
desc: '查看你提交过的安全反馈。'
}, {
title: '黑名单',
desc: '被拉黑对象不会再随机出现。'
}, {
title: '隐私说明',
desc: '半匿名资料和聊天保留规则。'
}],
principles: [
'不做好友列表,做轻关系保护。',
'不做动态广场,做当下状态入口。',
'不做颜值筛选,做半匿名陪伴。',
'不做无限聊天,做限时共处。'
]
}
},
onLoad() {
@ -82,13 +100,14 @@
}
},
methods: {
back() {
uni.navigateBack()
},
goChat() {
uni.navigateTo({
url: '/package1/ieBrowser/chat'
handleSetting(item) {
uni.showToast({
title: item.title,
icon: 'none'
})
},
back() {
uni.redirectTo({ url: '/package1/ieBrowser/index' })
}
}
}
@ -96,26 +115,55 @@
<style lang="scss" scoped>
page {
background: #f6f8ff;
background: #f7f9ff;
}
.friends-page {
.archive-page {
min-height: 100vh;
padding: 0 28rpx 48rpx;
padding: 0 28rpx 56rpx;
box-sizing: border-box;
color: #161b2e;
background:
radial-gradient(circle at 85% 10%, rgba(255, 223, 117, 0.34), rgba(255, 223, 117, 0) 260rpx),
linear-gradient(180deg, #ffffff 0%, #f4f8ff 100%);
radial-gradient(circle at 82% 12%, rgba(169, 255, 231, 0.38), rgba(169, 255, 231, 0) 300rpx),
radial-gradient(circle at 18% 40%, rgba(255, 214, 165, 0.32), rgba(255, 214, 165, 0) 320rpx),
linear-gradient(180deg, #fbfdff 0%, #eef4ff 62%, #fff4e8 100%);
position: relative;
overflow: hidden;
}
.glow {
position: absolute;
border-radius: 50%;
filter: blur(10rpx);
}
.glow-a {
left: -130rpx;
top: 260rpx;
width: 340rpx;
height: 340rpx;
background: rgba(119, 99, 255, 0.22);
}
.glow-b {
right: -120rpx;
bottom: 180rpx;
width: 300rpx;
height: 300rpx;
background: rgba(255, 184, 209, 0.24);
}
.nav {
height: 88rpx;
position: relative;
z-index: 1;
height: 92rpx;
display: flex;
align-items: center;
}
.back {
width: 58rpx;
color: rgba(22, 27, 46, 0.62);
font-size: 56rpx;
line-height: 56rpx;
}
@ -123,208 +171,177 @@
.title {
flex: 1;
font-size: 34rpx;
font-weight: 900;
font-weight: 800;
}
.add {
width: 56rpx;
height: 56rpx;
border-radius: 50%;
background: #111;
color: #fff;
text-align: center;
line-height: 56rpx;
font-size: 34rpx;
.safe-dot {
height: 54rpx;
line-height: 54rpx;
padding: 0 22rpx;
border-radius: 999rpx;
color: #09101f;
background: #a9ffe7;
font-size: 22rpx;
font-weight: 800;
}
.profile-card {
padding: 36rpx;
border-radius: 42rpx;
background: linear-gradient(135deg, #7f6cff 0%, #111 100%);
color: #fff;
box-shadow: 0 24rpx 52rpx rgba(93, 70, 209, 0.18);
.profile-card,
.section-card,
.principle-card {
position: relative;
overflow: hidden;
z-index: 1;
border: 1rpx solid rgba(255, 255, 255, 0.78);
background: rgba(255, 255, 255, 0.62);
backdrop-filter: blur(24rpx);
box-shadow: 0 20rpx 64rpx rgba(96, 112, 160, 0.12);
}
.profile-title {
font-size: 42rpx;
font-weight: 900;
}
.profile-desc {
width: 430rpx;
margin-top: 12rpx;
color: rgba(255, 255, 255, 0.72);
font-size: 24rpx;
line-height: 38rpx;
.profile-card {
padding: 38rpx;
border-radius: 46rpx;
text-align: center;
}
.radar {
width: 160rpx;
height: 160rpx;
.avatar-orb {
width: 132rpx;
height: 132rpx;
margin: 0 auto;
border-radius: 50%;
border: 2rpx dashed rgba(255, 255, 255, 0.38);
position: absolute;
right: 28rpx;
top: 28rpx;
animation: radarRotate 8s linear infinite;
text-align: center;
line-height: 132rpx;
color: #09101f;
background: linear-gradient(145deg, #effffb, #a9ffe7);
font-size: 42rpx;
font-weight: 800;
}
.radar-dot {
width: 18rpx;
height: 18rpx;
border-radius: 50%;
background: #bdfce9;
position: absolute;
.profile-title {
margin-top: 24rpx;
font-size: 40rpx;
font-weight: 800;
}
.dot1 {
left: 28rpx;
top: 46rpx;
.profile-desc {
width: 520rpx;
margin: 14rpx auto 0;
color: rgba(22, 27, 46, 0.54);
font-size: 24rpx;
line-height: 38rpx;
}
.dot2 {
right: 36rpx;
top: 68rpx;
background: #ffdf75;
.profile-stats {
display: flex;
margin-top: 34rpx;
padding-top: 28rpx;
border-top: 1rpx solid rgba(22, 27, 46, 0.08);
}
.dot3 {
left: 74rpx;
bottom: 24rpx;
background: #ff91c8;
.profile-stats view {
flex: 1;
}
.group-tabs {
display: flex;
margin: 28rpx 0;
.stat-num,
.stat-label {
display: block;
}
.group-tab {
height: 58rpx;
line-height: 58rpx;
padding: 0 24rpx;
margin-right: 16rpx;
border-radius: 999rpx;
background: #fff;
color: #71807b;
font-size: 24rpx;
font-weight: 900;
box-shadow: 0 12rpx 24rpx rgba(33, 45, 72, 0.06);
.stat-num {
font-size: 34rpx;
font-weight: 800;
}
.group-tab.active {
background: #111;
color: #fff;
.stat-label {
margin-top: 8rpx;
color: rgba(22, 27, 46, 0.42);
font-size: 21rpx;
}
.friend-card {
display: flex;
align-items: center;
margin-bottom: 18rpx;
padding: 24rpx;
border-radius: 34rpx;
background: rgba(255, 255, 255, 0.94);
box-shadow: 0 18rpx 38rpx rgba(33, 45, 72, 0.07);
.section-card,
.principle-card {
margin-top: 26rpx;
padding: 30rpx;
border-radius: 36rpx;
}
.avatar {
width: 92rpx;
height: 92rpx;
border-radius: 50%;
text-align: center;
line-height: 92rpx;
font-size: 34rpx;
font-weight: 900;
position: relative;
.section-title,
.principle-title {
margin-bottom: 22rpx;
font-size: 30rpx;
font-weight: 800;
}
.avatar.i {
background: #c9fff0;
color: #08705c;
.preference-grid {
display: flex;
flex-wrap: wrap;
gap: 18rpx;
}
.avatar.e {
background: #ffe69a;
color: #a45c00;
.preference-card {
width: calc(50% - 9rpx);
padding: 24rpx;
border-radius: 28rpx;
background: rgba(255, 255, 255, 0.56);
box-sizing: border-box;
}
.online {
width: 20rpx;
height: 20rpx;
border: 4rpx solid #fff;
border-radius: 50%;
background: #19d887;
position: absolute;
right: 2rpx;
bottom: 6rpx;
.preference-title {
color: #6c69d8;
font-size: 25rpx;
font-weight: 800;
}
.friend-main {
flex: 1;
margin-left: 20rpx;
min-width: 0;
.preference-desc {
margin-top: 12rpx;
color: rgba(22, 27, 46, 0.52);
font-size: 22rpx;
line-height: 34rpx;
}
.friend-line {
.setting-row {
display: flex;
align-items: center;
justify-content: space-between;
padding: 24rpx 0;
border-top: 1rpx solid rgba(22, 27, 46, 0.08);
}
.friend-name {
font-size: 30rpx;
font-weight: 900;
.setting-row:first-of-type {
border-top: 0;
}
.friend-type {
margin-left: 12rpx;
padding: 4rpx 10rpx;
border-radius: 999rpx;
background: rgba(127, 108, 255, 0.1);
color: #7f6cff;
font-size: 20rpx;
font-weight: 900;
.setting-title {
font-size: 27rpx;
font-weight: 800;
}
.friend-status {
.setting-desc {
margin-top: 8rpx;
color: #53615d;
font-size: 24rpx;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
color: rgba(22, 27, 46, 0.48);
font-size: 22rpx;
}
.friend-tags {
margin-top: 10rpx;
}
.friend-tags text {
margin-right: 8rpx;
color: #87938f;
font-size: 21rpx;
.setting-arrow {
color: rgba(22, 27, 46, 0.42);
font-size: 42rpx;
}
.chat-btn {
width: 62rpx;
height: 62rpx;
border-radius: 50%;
background: #111;
color: #fff;
text-align: center;
line-height: 62rpx;
.principle-line {
position: relative;
padding-left: 24rpx;
margin-top: 18rpx;
color: rgba(22, 27, 46, 0.62);
font-size: 24rpx;
font-weight: 900;
line-height: 36rpx;
}
@keyframes radarRotate {
0% {
transform: rotate(0);
}
100% {
transform: rotate(360deg);
}
.principle-line::before {
content: '';
position: absolute;
left: 0;
top: 14rpx;
width: 8rpx;
height: 8rpx;
border-radius: 50%;
background: #a9ffe7;
}
</style>

2096
package1/ieBrowser/index.vue

File diff suppressed because it is too large

106
package1/ieBrowser/match.vue

@ -0,0 +1,106 @@
<template>
<view class="match-page">
<view class="top-safe" :style="{ height: menuButtonInfo.top + 'px' }"></view>
<view class="nav">
<view class="back" @tap="back"></view>
<view class="nav-title">随机匹配</view>
<view class="ghost"></view>
</view>
<view class="focus">
<view class="halo"></view>
<view class="dot">{{ mode }}</view>
</view>
<view class="copy">
<view class="title">使用一次今日陪伴机会</view>
<view class="desc">系统会根据你的此刻状态随机靠近一个也想被轻轻陪伴的人</view>
</view>
<view class="meta-card">
<view>
<text class="label">当前模式</text>
<text class="value">{{ modeText }}</text>
</view>
<view>
<text class="label">剩余机会</text>
<text class="value">3/3</text>
</view>
</view>
<view class="start" @tap="start">开始调频</view>
<view class="tips">不展示真实头像距离和学校连接只在限时房间里发生</view>
</view>
</template>
<script>
export default {
data() {
return {
mode: 'i',
mood: 'quiet',
menuButtonInfo: { top: 44 }
}
},
computed: {
modeText() {
return this.mode === 'e' ? '轻轻热闹' : '安静陪伴'
}
},
onLoad(options) {
if (uni.getMenuButtonBoundingClientRect) {
this.menuButtonInfo = uni.getMenuButtonBoundingClientRect()
}
this.mode = options.mode || 'i'
this.mood = options.mood || 'quiet'
},
methods: {
start() {
uni.navigateTo({ url: '/package1/ieBrowser/matching?mode=' + this.mode + '&mood=' + this.mood })
},
back() {
uni.redirectTo({ url: '/package1/ieBrowser/index' })
}
}
}
</script>
<style lang="scss" scoped>
page { background: #f7f9ff; }
.match-page {
min-height: 100vh;
padding: 0 32rpx 60rpx;
box-sizing: border-box;
color: #161b2e;
background:
radial-gradient(circle at 50% 34%, rgba(169, 255, 231, .48), transparent 360rpx),
radial-gradient(circle at 80% 8%, rgba(139, 124, 255, .24), transparent 320rpx),
radial-gradient(circle at 18% 76%, rgba(255, 214, 165, .34), transparent 340rpx),
linear-gradient(180deg, #fbfdff, #eef4ff 62%, #fff4e8);
}
.nav { height: 90rpx; display: flex; align-items: center; }
.back, .ghost { width: 70rpx; font-size: 56rpx; color: rgba(22,27,46,.55); }
.nav-title { flex: 1; text-align: center; font-size: 30rpx; font-weight: 800; }
.focus { position: relative; height: 430rpx; display: flex; align-items: center; justify-content: center; }
.halo { position: absolute; width: 300rpx; height: 300rpx; border-radius: 50%; border: 1rpx solid rgba(139,124,255,.22); background: rgba(255,255,255,.32); backdrop-filter: blur(18rpx); animation: pulse 2.8s ease-in-out infinite; }
.dot { width: 154rpx; height: 154rpx; border-radius: 50%; text-align: center; line-height: 154rpx; color: #11162a; background: linear-gradient(145deg, #ffffff, #a9ffe7); font-size: 70rpx; font-weight: 800; box-shadow: 0 24rpx 68rpx rgba(169,255,231,.36); }
.copy { text-align: center; }
.title { font-size: 44rpx; font-weight: 800; }
.desc { width: 560rpx; margin: 18rpx auto 0; color: rgba(22,27,46,.56); font-size: 25rpx; line-height: 42rpx; }
.meta-card { display: flex; margin-top: 46rpx; padding: 30rpx; border-radius: 36rpx; background: rgba(255,255,255,.62); border: 1rpx solid rgba(255,255,255,.8); backdrop-filter: blur(24rpx); box-shadow: 0 22rpx 64rpx rgba(96,112,160,.13); }
.meta-card view { flex: 1; }
.label, .value { display: block; text-align: center; }
.label { color: rgba(22,27,46,.42); font-size: 22rpx; }
.value { margin-top: 12rpx; font-size: 32rpx; font-weight: 800; }
.start { margin-top: 42rpx; height: 104rpx; border-radius: 999rpx; text-align: center; line-height: 104rpx; color: #11162a; background: linear-gradient(135deg, #ffffff, #a9ffe7 60%, #ffd6a5); font-size: 30rpx; font-weight: 800; box-shadow: 0 24rpx 58rpx rgba(169,255,231,.3); animation: pulseButton 2.8s ease-in-out infinite; }
.start:active { transform: scale(.97); }
.tips { width: 560rpx; margin: 26rpx auto 0; text-align: center; color: rgba(22,27,46,.38); font-size: 22rpx; line-height: 36rpx; }
@keyframes pulse {
0%, 100% { transform: scale(.86); opacity: .45; }
50% { transform: scale(1.12); opacity: 1; }
}
@keyframes pulseButton {
0%, 100% { transform: scale(1); }
50% { transform: scale(1.018); }
}
</style>

103
package1/ieBrowser/matching.vue

@ -0,0 +1,103 @@
<template>
<view class="matching-page">
<view class="back" @tap="back"></view>
<view class="space">
<view class="radio-ring ring-a"></view>
<view class="radio-ring ring-b"></view>
<view class="particle p1"></view>
<view class="particle p2"></view>
<view class="particle p3"></view>
<view class="tag tag-a">慢热</view>
<view class="tag tag-b">失眠</view>
<view class="tag tag-c">想散步</view>
<view class="flash-word word-a">靠近</view>
<view class="flash-word word-b">同频</view>
<view class="user-dot">{{ mode }}</view>
<view class="other-dot"></view>
</view>
<view class="title">校园电波正在接近</view>
<view class="desc">{{ copyList[currentCopy] }}</view>
<view class="skip" @tap="goCard">跳过动画</view>
</view>
</template>
<script>
export default {
data() {
return {
mode: 'i',
mood: 'quiet',
currentCopy: 0,
copyList: ['模糊人格标签正在漂浮', '两个光点正在靠近', '情绪文字短暂闪了一下']
}
},
onLoad(options) {
this.mode = options.mode || 'i'
this.mood = options.mood || 'quiet'
this.timer = setInterval(() => {
this.currentCopy = (this.currentCopy + 1) % this.copyList.length
}, 700)
setTimeout(() => {
this.goCard()
}, 1800)
},
onUnload() {
clearInterval(this.timer)
},
methods: {
back() {
clearInterval(this.timer)
uni.redirectTo({ url: '/package1/ieBrowser/index' })
},
goCard() {
clearInterval(this.timer)
uni.redirectTo({ url: '/package1/ieBrowser/companion?mode=' + this.mode + '&mood=' + this.mood })
}
}
}
</script>
<style lang="scss" scoped>
page { background: #0b1024; }
.matching-page {
min-height: 100vh;
padding: 0 32rpx;
box-sizing: border-box;
color: #f7f4ff;
text-align: center;
background:
radial-gradient(circle at 50% 42%, rgba(169, 255, 231, .2), transparent 380rpx),
radial-gradient(circle at 78% 16%, rgba(255, 184, 209, .18), transparent 320rpx),
radial-gradient(circle at 12% 20%, rgba(139, 124, 255, .28), transparent 360rpx),
linear-gradient(145deg, #0b1024, #151a31 56%, #101729);
overflow: hidden;
}
.back { position: fixed; left: 32rpx; top: 72rpx; z-index: 2; width: 70rpx; height: 70rpx; color: rgba(247,244,255,.62); font-size: 56rpx; line-height: 64rpx; text-align: left; }
.space { position: relative; height: 620rpx; }
.user-dot, .other-dot, .particle { position: absolute; border-radius: 50%; }
.user-dot { left: 150rpx; top: 320rpx; width: 116rpx; height: 116rpx; line-height: 116rpx; background: linear-gradient(145deg, #ffffff, #a9ffe7); color: #11162a; font-size: 52rpx; font-weight: 800; box-shadow: 0 22rpx 80rpx rgba(169,255,231,.32); animation: moveUser 1.8s ease-in-out forwards; }
.other-dot { right: 150rpx; top: 320rpx; width: 100rpx; height: 100rpx; background: linear-gradient(145deg, #8b7cff, #ffb8d1); box-shadow: 0 18rpx 70rpx rgba(139,124,255,.3); animation: moveOther 1.8s ease-in-out forwards; }
.particle { width: 14rpx; height: 14rpx; background: rgba(169,255,231,.58); animation: drift 3s ease-in-out infinite; }
.p1 { left: 90rpx; top: 210rpx; }
.p2 { right: 110rpx; top: 180rpx; animation-delay: .4s; }
.p3 { left: 360rpx; top: 460rpx; animation-delay: .8s; }
.title { font-size: 42rpx; font-weight: 800; }
.desc { margin-top: 18rpx; color: rgba(247,244,255,.48); font-size: 25rpx; }
.skip { position: fixed; left: 50%; bottom: 70rpx; transform: translateX(-50%); color: rgba(247,244,255,.4); font-size: 23rpx; }
.radio-ring { position: absolute; left: 50%; top: 360rpx; border-radius: 50%; border: 1rpx solid rgba(255,255,255,.1); transform: translate(-50%, -50%); }
.ring-a { width: 520rpx; height: 260rpx; animation: ringPulse 2.4s ease-in-out infinite; }
.ring-b { width: 360rpx; height: 360rpx; border-color: rgba(169,255,231,.15); animation: ringRotate 14s linear infinite; }
.tag, .flash-word { position: absolute; padding: 12rpx 20rpx; border-radius: 999rpx; background: rgba(255,255,255,.08); border: 1rpx solid rgba(255,255,255,.12); backdrop-filter: blur(18rpx); color: rgba(247,244,255,.66); font-size: 22rpx; }
.tag-a { left: 90rpx; top: 250rpx; animation: drift 3.6s ease-in-out infinite; }
.tag-b { right: 86rpx; top: 248rpx; animation: drift 3.4s ease-in-out infinite .6s; }
.tag-c { left: 260rpx; top: 470rpx; animation: drift 3.8s ease-in-out infinite 1s; }
.flash-word { color: rgba(169,255,231,.9); opacity: 0; }
.word-a { left: 170rpx; top: 170rpx; animation: flashWord 1.8s ease-in-out infinite .2s; }
.word-b { right: 170rpx; top: 430rpx; animation: flashWord 1.8s ease-in-out infinite .8s; }
@keyframes moveUser { to { left: 300rpx; transform: scale(1.12); } }
@keyframes moveOther { to { right: 300rpx; transform: scale(1.12); } }
@keyframes drift { 0%, 100% { transform: translateY(0); opacity: .3; } 50% { transform: translateY(-30rpx); opacity: 1; } }
@keyframes ringPulse { 0%, 100% { transform: translate(-50%, -50%) scale(.9) rotate(-10deg); opacity: .35; } 50% { transform: translate(-50%, -50%) scale(1.08) rotate(-4deg); opacity: .9; } }
@keyframes ringRotate { from { transform: translate(-50%, -50%) rotate(0); } to { transform: translate(-50%, -50%) rotate(360deg); } }
@keyframes flashWord { 0%, 100% { opacity: 0; transform: translateY(12rpx); } 45%, 60% { opacity: 1; transform: translateY(0); } }
</style>

75
package1/ieBrowser/messages.vue

@ -0,0 +1,75 @@
<template>
<view class="messages-page">
<view class="top-safe" :style="{ height: menuButtonInfo.top + 'px' }"></view>
<view class="nav">
<view class="back" @tap="back"></view>
<view class="nav-title">消息</view>
<view class="ghost"></view>
</view>
<view class="head">
<view class="title">消息</view>
<view class="sub">这里不是聊天列表只放未完成的陪伴</view>
</view>
<view class="room-card active" @tap="goChat">
<view class="pulse"></view>
<view class="main">
<view class="name">月台旁的影子</view>
<view class="desc">限时房间还剩 08:32可以继续回去待一会</view>
</view>
<view class="tag">进行中</view>
</view>
<view class="room-card" v-for="item in requests" :key="item.name">
<view class="avatar">{{ item.avatar }}</view>
<view class="main">
<view class="name">{{ item.name }}</view>
<view class="desc">{{ item.desc }}</view>
</view>
<view class="tag soft">再遇见</view>
</view>
<view class="empty">没有未完成的关系也是一种轻松</view>
</view>
</template>
<script>
export default {
data() {
return {
menuButtonInfo: { top: 44 },
requests: [
{ name: '便利店灯光', avatar: '光', desc: '对方也愿意在 24 小时内再聊一次。' },
{ name: '耳机里的风', avatar: '风', desc: '昨天的安静陪伴已自然结束。' }
]
}
},
onLoad() {
if (uni.getMenuButtonBoundingClientRect) this.menuButtonInfo = uni.getMenuButtonBoundingClientRect()
},
methods: {
back() { uni.redirectTo({ url: '/package1/ieBrowser/index' }) },
goChat() { uni.navigateTo({ url: '/package1/ieBrowser/chat?mode=i' }) }
}
}
</script>
<style lang="scss" scoped>
page { background: #f7f9ff; }
.messages-page { min-height: 100vh; padding: 0 30rpx 60rpx; box-sizing: border-box; color: #151a2d; background: radial-gradient(circle at 18% 8%, rgba(169,255,231,.42), transparent 280rpx), linear-gradient(180deg, #fbfdff, #eef4ff); }
.nav { height: 90rpx; display: flex; align-items: center; }
.back, .ghost { width: 70rpx; font-size: 56rpx; color: rgba(21,26,45,.55); }
.nav-title { flex: 1; text-align: center; font-size: 30rpx; font-weight: 800; }
.head { padding-top: 10rpx; }
.title { font-size: 52rpx; font-weight: 800; }
.sub { margin-top: 12rpx; color: rgba(21,26,45,.5); font-size: 25rpx; }
.room-card { display: flex; align-items: center; margin-top: 26rpx; padding: 28rpx; border-radius: 36rpx; background: rgba(255,255,255,.64); border: 1rpx solid rgba(255,255,255,.86); box-shadow: 0 22rpx 60rpx rgba(96,112,160,.12); }
.room-card.active { background: rgba(17,22,42,.92); color: #fff; }
.pulse, .avatar { width: 78rpx; height: 78rpx; margin-right: 20rpx; border-radius: 50%; text-align: center; line-height: 78rpx; background: #a9ffe7; color: #11162a; font-weight: 800; }
.pulse { animation: breath 2.4s ease-in-out infinite; }
.main { flex: 1; }
.name { font-size: 29rpx; font-weight: 800; }
.desc { margin-top: 8rpx; color: rgba(21,26,45,.52); font-size: 23rpx; line-height: 36rpx; }
.active .desc { color: rgba(255,255,255,.58); }
.tag { padding: 8rpx 16rpx; border-radius: 999rpx; color: #11162a; background: #a9ffe7; font-size: 20rpx; }
.tag.soft { color: #7771d8; background: rgba(119,113,216,.1); }
.empty { margin-top: 42rpx; text-align: center; color: rgba(21,26,45,.36); font-size: 23rpx; }
@keyframes breath { 0%, 100% { transform: scale(.9); opacity: .65; } 50% { transform: scale(1.04); opacity: 1; } }
</style>

119
package1/ieBrowser/mode.vue

@ -0,0 +1,119 @@
<template>
<view class="mode-page" :class="'theme-' + activeMode">
<view class="top-safe" :style="{ height: menuButtonInfo.top + 'px' }"></view>
<view class="nav">
<view class="back" @tap="back"></view>
<view class="nav-title">i/e 选择</view>
<view class="ghost"></view>
</view>
<view class="head">
<view class="eyebrow">Today Mode</view>
<view class="title">今天想以哪种方式被陪伴</view>
<view class="sub">这不是人格测试只是此刻的社交能量</view>
</view>
<view class="mode-card i" :class="{ active: activeMode === 'i' }" @tap="activeMode = 'i'">
<view class="mark">i</view>
<view class="copy">
<view class="name">安静陪伴</view>
<view class="desc">慢回复少说话允许沉默像两个人坐在操场边</view>
</view>
<view class="state">月光 / 耳机 / 图书馆</view>
</view>
<view class="mode-card e" :class="{ active: activeMode === 'e' }" @tap="activeMode = 'e'">
<view class="mark">e</view>
<view class="copy">
<view class="name">轻轻热闹</view>
<view class="desc">有人开场聊点废话把情绪拉亮一点</view>
</view>
<view class="state">便利店 / 夜跑 / 随机话题</view>
</view>
<view class="continue" @tap="goHome">进入此刻</view>
</view>
</template>
<script>
export default {
data() {
return {
activeMode: 'i',
menuButtonInfo: { top: 44 }
}
},
onLoad() {
if (uni.getMenuButtonBoundingClientRect) {
this.menuButtonInfo = uni.getMenuButtonBoundingClientRect()
}
},
methods: {
back() {
uni.redirectTo({ url: '/package1/ieBrowser/index' })
},
goHome() {
uni.redirectTo({ url: '/package1/ieBrowser/index?mode=' + this.activeMode })
}
}
}
</script>
<style lang="scss" scoped>
page { background: #f7f9ff; }
.mode-page {
min-height: 100vh;
padding: 0 32rpx 72rpx;
box-sizing: border-box;
color: #151a2d;
background:
radial-gradient(circle at 82% 8%, rgba(139, 124, 255, .24), transparent 290rpx),
linear-gradient(180deg, #fbfdff, #eef4ff);
transition: background .35s ease;
}
.theme-e {
background:
radial-gradient(circle at 82% 8%, rgba(255, 184, 209, .36), transparent 300rpx),
radial-gradient(circle at 18% 70%, rgba(255, 214, 165, .38), transparent 320rpx),
linear-gradient(180deg, #fffaf4, #f7f9ff);
}
.nav { height: 90rpx; display: flex; align-items: center; }
.back, .ghost { width: 70rpx; font-size: 56rpx; color: rgba(21, 26, 45, .55); }
.nav-title { flex: 1; text-align: center; font-size: 30rpx; font-weight: 800; }
.head { padding-top: 10rpx; }
.eyebrow { color: rgba(21, 26, 45, .42); font-size: 22rpx; letter-spacing: 5rpx; text-transform: uppercase; }
.title { width: 570rpx; margin-top: 18rpx; font-size: 52rpx; line-height: 66rpx; font-weight: 800; }
.sub { margin-top: 18rpx; color: rgba(21, 26, 45, .5); font-size: 25rpx; }
.mode-card {
position: relative;
margin-top: 34rpx;
padding: 34rpx;
border: 1rpx solid rgba(255, 255, 255, .74);
border-radius: 44rpx;
background: rgba(255, 255, 255, .56);
backdrop-filter: blur(24rpx);
box-shadow: 0 28rpx 80rpx rgba(96, 112, 160, .13);
transition: transform .22s ease, border-color .22s ease;
}
.mode-card.active { transform: scale(1.02); border-color: rgba(169, 255, 231, .95); }
.mark { width: 92rpx; height: 92rpx; border-radius: 32rpx; text-align: center; line-height: 92rpx; font-size: 52rpx; font-weight: 800; }
.i .mark { color: #f7f4ff; background: #7771d8; }
.e .mark { color: #11162a; background: #a9ffe7; }
.copy { margin-top: 26rpx; }
.name { font-size: 38rpx; font-weight: 800; }
.desc { margin-top: 12rpx; color: rgba(21, 26, 45, .58); font-size: 26rpx; line-height: 42rpx; }
.state { margin-top: 28rpx; color: rgba(21, 26, 45, .42); font-size: 22rpx; }
.continue {
position: fixed;
left: 32rpx;
right: 32rpx;
bottom: 40rpx;
height: 104rpx;
border-radius: 999rpx;
text-align: center;
line-height: 104rpx;
color: #11162a;
background: linear-gradient(135deg, #effffb, #a9ffe7);
font-size: 30rpx;
font-weight: 800;
}
</style>

66
package1/ieBrowser/settings.vue

@ -0,0 +1,66 @@
<template>
<view class="settings-page">
<view class="top-safe" :style="{ height: menuButtonInfo.top + 'px' }"></view>
<view class="nav">
<view class="back" @tap="back"></view>
<view class="title">设置</view>
<view class="ghost"></view>
</view>
<view class="panel" v-for="group in groups" :key="group.title">
<view class="panel-title">{{ group.title }}</view>
<view class="row" v-for="item in group.items" :key="item.name" @tap="tapItem(item)">
<view>
<view class="name">{{ item.name }}</view>
<view class="desc">{{ item.desc }}</view>
</view>
<view class="arrow"></view>
</view>
</view>
</view>
</template>
<script>
export default {
data() {
return {
menuButtonInfo: { top: 44 },
groups: [
{ title: '隐私', items: [
{ name: '半匿名资料', desc: '不展示真实头像、学校、距离。' },
{ name: '聊天保留规则', desc: '只保存情绪记录,不保存完整聊天。' }
] },
{ title: '安全', items: [
{ name: '黑名单', desc: '被拉黑对象不会再次出现。' },
{ name: '举报记录', desc: '查看已提交的安全反馈。' }
] },
{ title: '提醒', items: [
{ name: '深夜轻提醒', desc: '只在你允许的时间出现。' },
{ name: '今日次数', desc: '每天 3 次,不做无限刷。' }
] }
]
}
},
onLoad() {
if (uni.getMenuButtonBoundingClientRect) this.menuButtonInfo = uni.getMenuButtonBoundingClientRect()
},
methods: {
back() { uni.redirectTo({ url: '/package1/ieBrowser/index' }) },
tapItem(item) { uni.showToast({ title: item.name, icon: 'none' }) }
}
}
</script>
<style lang="scss" scoped>
page { background: #f7f9ff; }
.settings-page { min-height: 100vh; padding: 0 30rpx 60rpx; box-sizing: border-box; color: #151a2d; background: linear-gradient(180deg, #fbfdff, #eef4ff); }
.nav { height: 90rpx; display: flex; align-items: center; }
.back, .ghost { width: 70rpx; font-size: 56rpx; color: rgba(21,26,45,.64); }
.title { flex: 1; text-align: center; font-size: 31rpx; font-weight: 800; }
.panel { margin-top: 26rpx; padding: 30rpx; border-radius: 36rpx; background: rgba(255,255,255,.68); border: 1rpx solid rgba(255,255,255,.88); box-shadow: 0 22rpx 60rpx rgba(96,112,160,.1); }
.panel-title { margin-bottom: 12rpx; font-size: 30rpx; font-weight: 800; }
.row { display: flex; align-items: center; padding: 24rpx 0; border-top: 1rpx solid rgba(21,26,45,.06); }
.row:first-of-type { border-top: 0; }
.name { font-size: 27rpx; font-weight: 800; }
.desc { margin-top: 8rpx; color: rgba(21,26,45,.48); font-size: 22rpx; }
.arrow { flex: 1; text-align: right; color: rgba(21,26,45,.34); font-size: 42rpx; }
</style>

54
package1/ieBrowser/splash.vue

@ -0,0 +1,54 @@
<template>
<view class="splash-page" @tap="enter">
<view class="orb"></view>
<view class="brand">i/e Campus</view>
<view class="slogan">把此刻的频率轻轻调近一点</view>
<view class="hint">已登录 · 轻触进入</view>
</view>
</template>
<script>
export default {
onLoad() {
setTimeout(() => {
this.enter()
}, 1200)
},
methods: {
enter() {
uni.redirectTo({ url: '/package1/ieBrowser/mode' })
}
}
}
</script>
<style lang="scss" scoped>
page { background: #f7f9ff; }
.splash-page {
min-height: 100vh;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
color: #151a2d;
background:
radial-gradient(circle at 50% 38%, rgba(169, 255, 231, .65), rgba(169, 255, 231, 0) 220rpx),
radial-gradient(circle at 18% 12%, rgba(139, 124, 255, .24), rgba(139, 124, 255, 0) 300rpx),
linear-gradient(180deg, #fbfdff 0%, #eef4ff 100%);
}
.orb {
width: 178rpx;
height: 178rpx;
border-radius: 50%;
background: linear-gradient(145deg, #ffffff, #a9ffe7);
box-shadow: 0 0 80rpx rgba(139, 124, 255, .22);
animation: breath 2.8s ease-in-out infinite;
}
.brand { margin-top: 54rpx; font-size: 50rpx; font-weight: 800; letter-spacing: 2rpx; }
.slogan { width: 520rpx; margin-top: 22rpx; text-align: center; color: rgba(21, 26, 45, .58); font-size: 27rpx; line-height: 44rpx; }
.hint { position: fixed; bottom: 86rpx; color: rgba(21, 26, 45, .36); font-size: 23rpx; }
@keyframes breath {
0%, 100% { transform: scale(.96); opacity: .76; }
50% { transform: scale(1.06); opacity: 1; }
}
</style>

87
package1/ieBrowser/universe.vue

@ -0,0 +1,87 @@
<template>
<view class="universe-page">
<view class="top-safe" :style="{ height: menuButtonInfo.top + 'px' }"></view>
<view class="nav">
<view class="back" @tap="back"></view>
<view class="nav-title">我的宇宙</view>
<view class="ghost"></view>
</view>
<view class="profile">
<view class="orb"></view>
<view class="name">半匿名漂流者</view>
<view class="desc">不经营人设不展示粉丝这里只记录你更喜欢怎样被陪伴</view>
</view>
<view class="stats">
<view><text>3</text><text>今日机会</text></view>
<view><text>15m</text><text>默认限时</text></view>
<view><text>i</text><text>近期偏好</text></view>
</view>
<view class="panel">
<view class="panel-title">情绪轨道</view>
<view class="orbit-row" v-for="item in orbit" :key="item.day">
<view class="day">{{ item.day }}</view>
<view class="bar"><view :style="{ width: item.value + '%' }"></view></view>
<view class="mood">{{ item.mood }}</view>
</view>
</view>
<view class="panel">
<view class="setting" @tap="goSettings">
<view>
<view class="setting-title">隐私与安全</view>
<view class="setting-desc">黑名单举报记录半匿名规则</view>
</view>
<view class="arrow"></view>
</view>
</view>
</view>
</template>
<script>
export default {
data() {
return {
menuButtonInfo: { top: 44 },
orbit: [
{ day: '今天', value: 72, mood: '轻了一点' },
{ day: '昨天', value: 48, mood: '安静' },
{ day: '周六', value: 86, mood: '被听见' }
]
}
},
onLoad() {
if (uni.getMenuButtonBoundingClientRect) this.menuButtonInfo = uni.getMenuButtonBoundingClientRect()
},
methods: {
back() { uni.redirectTo({ url: '/package1/ieBrowser/index' }) },
goSettings() { uni.navigateTo({ url: '/package1/ieBrowser/settings' }) }
}
}
</script>
<style lang="scss" scoped>
page { background: #f7f9ff; }
.universe-page { min-height: 100vh; padding: 0 32rpx 60rpx; box-sizing: border-box; color: #161b2e; background: radial-gradient(circle at 50% 12%, rgba(169,255,231,.42), transparent 330rpx), radial-gradient(circle at 86% 28%, rgba(255,184,209,.24), transparent 320rpx), linear-gradient(180deg, #fbfdff, #eef4ff 62%, #fff4e8); }
.nav { height: 90rpx; display: flex; align-items: center; }
.back, .ghost { width: 70rpx; font-size: 56rpx; color: rgba(22,27,46,.55); }
.nav-title { flex: 1; text-align: center; font-size: 30rpx; font-weight: 800; }
.profile { padding-top: 18rpx; text-align: center; }
.orb { width: 148rpx; height: 148rpx; margin: 0 auto; border-radius: 50%; text-align: center; line-height: 148rpx; color: #11162a; background: linear-gradient(145deg, #effffb, #a9ffe7); font-size: 48rpx; font-weight: 800; box-shadow: 0 0 80rpx rgba(169,255,231,.18); }
.name { margin-top: 26rpx; font-size: 42rpx; font-weight: 800; }
.desc { width: 560rpx; margin: 14rpx auto 0; color: rgba(22,27,46,.52); font-size: 24rpx; line-height: 38rpx; }
.stats { display: flex; margin-top: 36rpx; padding: 28rpx; border-radius: 36rpx; background: rgba(255,255,255,.62); border: 1rpx solid rgba(255,255,255,.78); box-shadow: 0 20rpx 64rpx rgba(96,112,160,.12); }
.stats view { flex: 1; text-align: center; }
.stats text { display: block; }
.stats text:first-child { font-size: 34rpx; font-weight: 800; }
.stats text:last-child { margin-top: 8rpx; color: rgba(22,27,46,.42); font-size: 21rpx; }
.panel { margin-top: 26rpx; padding: 30rpx; border-radius: 36rpx; background: rgba(255,255,255,.62); border: 1rpx solid rgba(255,255,255,.78); backdrop-filter: blur(24rpx); box-shadow: 0 20rpx 64rpx rgba(96,112,160,.12); }
.panel-title { margin-bottom: 24rpx; font-size: 30rpx; font-weight: 800; }
.orbit-row { display: flex; align-items: center; margin-top: 22rpx; }
.day { width: 86rpx; color: rgba(22,27,46,.52); font-size: 22rpx; }
.bar { flex: 1; height: 12rpx; border-radius: 999rpx; background: rgba(22,27,46,.06); overflow: hidden; }
.bar view { height: 100%; border-radius: 999rpx; background: #a9ffe7; }
.mood { width: 120rpx; text-align: right; color: #6c69d8; font-size: 22rpx; }
.setting { display: flex; align-items: center; }
.setting-title { font-size: 28rpx; font-weight: 800; }
.setting-desc { margin-top: 8rpx; color: rgba(22,27,46,.48); font-size: 22rpx; }
.arrow { flex: 1; text-align: right; color: rgba(22,27,46,.4); font-size: 46rpx; }
</style>

61
pages/index/index.vue

@ -1928,37 +1928,54 @@
.menu-box {
width: 95%;
height: 200rpx;
height: 214rpx;
display: flex;
align-items: center;
align-items: flex-end;
margin: 30rpx auto 0;
padding: 12rpx 8rpx;
padding: 50rpx 8rpx 12rpx;
box-sizing: border-box;
border-radius: 38rpx;
border: 1px solid rgba(255, 255, 255, 0.9);
background:
radial-gradient(circle at 12% 0%, rgba(255, 255, 255, 0.94) 0, rgba(255, 255, 255, 0) 160rpx),
linear-gradient(135deg, rgba(255, 255, 255, 0.96) 0%, rgba(255, 250, 235, 0.9) 48%, rgba(239, 255, 248, 0.96) 100%);
radial-gradient(circle at 12% 0%, rgba(255, 255, 255, 0.94) 0, rgba(255, 255, 255, 0) 150rpx),
radial-gradient(circle at 92% 78%, rgba(88, 205, 122, 0.18) 0, rgba(88, 205, 122, 0) 170rpx),
linear-gradient(135deg, rgba(255, 255, 255, 0.96) 0%, rgba(244, 255, 241, 0.94) 50%, rgba(231, 255, 244, 0.96) 100%);
box-shadow: 0 20rpx 46rpx rgba(0, 35, 28, 0.075), inset 0 1rpx 0 rgba(255, 255, 255, 0.9);
position: relative;
z-index: 99;
overflow: hidden;
}
.menu-box::before {
content: '校园生活 · 一站搞定';
position: absolute;
left: 26rpx;
top: 17rpx;
color: #2c8b6f;
font-size: 22rpx;
font-weight: 900;
letter-spacing: 1rpx;
}
.menu-box::after {
content: '';
width: 280rpx;
height: 160rpx;
border-radius: 50%;
background: linear-gradient(135deg, rgba(166, 255, 234, 0.18) 0%, rgba(166, 255, 234, 0) 74%);
content: '本周精选活动 >';
position: absolute;
right: -150rpx;
top: -92rpx;
right: 24rpx;
top: 16rpx;
height: 42rpx;
padding: 0 18rpx;
border-radius: 999rpx;
background: rgba(255, 255, 255, 0.76);
color: #1e6a58;
font-size: 22rpx;
font-weight: 900;
line-height: 42rpx;
box-shadow: 0 8rpx 18rpx rgba(0, 35, 28, 0.06);
}
.menu-list {
flex: 1;
height: 100%;
height: 142rpx;
display: flex;
flex-direction: column;
align-items: center;
@ -1977,8 +1994,8 @@
}
.menu-list img {
width: 82rpx;
height: 82rpx;
width: 76rpx;
height: 76rpx;
display: block;
margin: 0 auto;
position: relative;
@ -2003,9 +2020,9 @@
.menu-name {
text-align: center;
font-size: 22rpx;
font-size: 21rpx;
font-weight: 900;
margin-top: 8rpx;
margin-top: 6rpx;
color: #183f36;
line-height: 28rpx;
position: relative;
@ -2015,7 +2032,7 @@
}
.menu-desc {
margin-top: 2rpx;
margin-top: 0;
color: rgba(18, 73, 63, 0.58);
font-size: 17rpx;
font-weight: 800;
@ -2026,12 +2043,12 @@
}
.world-light {
width: 104rpx;
height: 104rpx;
width: 96rpx;
height: 96rpx;
position: absolute;
left: 50%;
top: 18rpx;
margin-left: -52rpx;
top: 10rpx;
margin-left: -48rpx;
border-radius: 50%;
background: radial-gradient(circle, rgba(166, 255, 234, 0.62) 0%, rgba(166, 255, 234, 0) 68%);
box-shadow: 0 0 24rpx rgba(166, 255, 234, 0.32);

Loading…
Cancel
Save