feat(chat): 添加私信功能和WebSocket实时通信
- 集成WebSocket管理器,支持心跳、自动重连、消息队列 - 实现私信相关API接口,包括会话列表、历史消息、已读标记等 - 添加聊天页面和会话列表页面,支持实时消息收发 - 配置地图权限和腾讯地图SDK用于酒局定位功能 - 修改应用名称为"喝酒了么"并更新应用描述 - 在App.vue中初始化WebSocket连接和私信功能 - 添加详细的私信模块接口文档和Mock数据 - 优化单图片动态高度计算和预加载逻辑
This commit is contained in:
@@ -45,13 +45,31 @@
|
||||
<!-- 地点 -->
|
||||
<view class="form-group">
|
||||
<text class="form-label">地点</text>
|
||||
<input
|
||||
class="form-input"
|
||||
v-model="form.location"
|
||||
placeholder="输入聚会地点"
|
||||
placeholder-class="form-placeholder"
|
||||
:maxlength="50"
|
||||
/>
|
||||
<!-- 已选地点:显示地图预览 -->
|
||||
<view v-if="form.latitude" class="location-preview">
|
||||
<map
|
||||
class="location-map"
|
||||
:latitude="form.latitude"
|
||||
:longitude="form.longitude"
|
||||
:markers="locationMarkers"
|
||||
:scale="15"
|
||||
:show-location="false"
|
||||
@click="chooseLocation"
|
||||
></map>
|
||||
<view class="location-info">
|
||||
<text class="location-name">{{ form.location }}</text>
|
||||
<text class="location-address">{{ form.address || '' }}</text>
|
||||
</view>
|
||||
<view class="location-change" @click="chooseLocation">
|
||||
<text class="location-change-text">重新选择</text>
|
||||
</view>
|
||||
</view>
|
||||
<!-- 未选地点:点击选择 -->
|
||||
<view v-else class="location-picker" @click="chooseLocation">
|
||||
<text class="location-picker-icon">📍</text>
|
||||
<text class="location-picker-text">点击选择地点</text>
|
||||
<text class="location-picker-arrow">›</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 人数 -->
|
||||
@@ -104,6 +122,9 @@ export default {
|
||||
date: '',
|
||||
time: '',
|
||||
location: '',
|
||||
address: '',
|
||||
latitude: null,
|
||||
longitude: null,
|
||||
maxPeople: 6,
|
||||
note: ''
|
||||
},
|
||||
@@ -113,6 +134,17 @@ export default {
|
||||
computed: {
|
||||
canSubmit() {
|
||||
return this.form.title.trim() && this.form.date && this.form.time && this.form.location.trim() && !this.submitting
|
||||
},
|
||||
locationMarkers() {
|
||||
if (!this.form.latitude) return []
|
||||
return [{
|
||||
id: 1,
|
||||
latitude: this.form.latitude,
|
||||
longitude: this.form.longitude,
|
||||
title: this.form.location,
|
||||
width: 28,
|
||||
height: 38
|
||||
}]
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
@@ -125,6 +157,19 @@ export default {
|
||||
onTimeChange(e) {
|
||||
this.form.time = e.detail.value
|
||||
},
|
||||
chooseLocation() {
|
||||
uni.chooseLocation({
|
||||
success: (res) => {
|
||||
this.form.location = res.name || res.address || ''
|
||||
this.form.address = res.address || ''
|
||||
this.form.latitude = res.latitude
|
||||
this.form.longitude = res.longitude
|
||||
},
|
||||
fail: () => {
|
||||
// 用户取消或无权限,不做处理
|
||||
}
|
||||
})
|
||||
},
|
||||
changePeople(delta) {
|
||||
const val = this.form.maxPeople + delta
|
||||
if (val >= 2 && val <= 50) {
|
||||
@@ -139,6 +184,9 @@ export default {
|
||||
title: this.form.title,
|
||||
time: `${this.form.date} ${this.form.time}`,
|
||||
location: this.form.location,
|
||||
address: this.form.address,
|
||||
latitude: this.form.latitude,
|
||||
longitude: this.form.longitude,
|
||||
maxPeople: this.form.maxPeople,
|
||||
note: this.form.note
|
||||
})
|
||||
@@ -279,6 +327,86 @@ export default {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
/* 地点选择器 */
|
||||
.location-picker {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: $sp-md;
|
||||
height: 96rpx;
|
||||
padding: 0 $sp-lg;
|
||||
background: $bg-card;
|
||||
border-radius: $radius-lg;
|
||||
border: 2rpx dashed var(--border-dashed, rgba(255,255,255,0.12));
|
||||
|
||||
&:active {
|
||||
background: $bg-card-alt;
|
||||
}
|
||||
}
|
||||
|
||||
.location-picker-icon {
|
||||
font-size: $fs-lg;
|
||||
}
|
||||
|
||||
.location-picker-text {
|
||||
flex: 1;
|
||||
font-size: $fs-base;
|
||||
color: $text-tertiary;
|
||||
}
|
||||
|
||||
.location-picker-arrow {
|
||||
font-size: $fs-xl;
|
||||
color: $text-tertiary;
|
||||
}
|
||||
|
||||
/* 地图预览 */
|
||||
.location-preview {
|
||||
border-radius: $radius-lg;
|
||||
overflow: hidden;
|
||||
border: 1rpx solid var(--border-faint, rgba(255,255,255,0.08));
|
||||
}
|
||||
|
||||
.location-map {
|
||||
width: 100%;
|
||||
height: 280rpx;
|
||||
}
|
||||
|
||||
.location-info {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 6rpx;
|
||||
padding: $sp-md $sp-lg;
|
||||
background: $bg-card;
|
||||
}
|
||||
|
||||
.location-name {
|
||||
font-size: $fs-base;
|
||||
font-weight: $fw-bold;
|
||||
color: $text-primary;
|
||||
}
|
||||
|
||||
.location-address {
|
||||
font-size: $fs-xs;
|
||||
color: $text-tertiary;
|
||||
}
|
||||
|
||||
.location-change {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: $sp-sm;
|
||||
background: $bg-card-alt;
|
||||
|
||||
&:active {
|
||||
background: $bg-elevated;
|
||||
}
|
||||
}
|
||||
|
||||
.location-change-text {
|
||||
font-size: $fs-sm;
|
||||
color: $amber;
|
||||
font-weight: $fw-medium;
|
||||
}
|
||||
|
||||
/* 人数步进器 */
|
||||
.form-stepper {
|
||||
display: flex;
|
||||
|
||||
Reference in New Issue
Block a user