|
|
|
|
@ -100,13 +100,14 @@
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
<script setup>
|
|
|
|
|
import { ref, computed, onMounted, onUnmounted } from 'vue'
|
|
|
|
|
import { ref, computed, onMounted, onUnmounted, watch } from 'vue'
|
|
|
|
|
import { User, Avatar, Phone } from '@element-plus/icons-vue'
|
|
|
|
|
import PhoneWidget from './PhoneWidget.vue'
|
|
|
|
|
import UserCenterDialog from './UserCenterDialog.vue'
|
|
|
|
|
import OCListDialog from './OCListDialog.vue'
|
|
|
|
|
import OCInfoDialog from './OCInfoDialog.vue'
|
|
|
|
|
import { ocList } from '../stores/ocStore.js'
|
|
|
|
|
import { ocList, loadOCFromStorage } from '../stores/ocStore.js'
|
|
|
|
|
import { currentUser } from '../stores/userStore.js'
|
|
|
|
|
|
|
|
|
|
// 默认头像
|
|
|
|
|
const defaultAvatar = 'data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTAwIiBoZWlnaHQ9IjEwMCIgdmlld0JveD0iMCAwIDEwMCAxMDAiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxyZWN0IHdpZHRoPSIxMDAiIGhlaWdodD0iMTAwIiBmaWxsPSIjZGRlMGU2Ii8+CjxjaXJjbGUgY3g9IjUwIiBjeT0iMzUiIHI9IjIwIiBmaWxsPSIjYThiOWNlIi8+CjxwYXRoIGQ9Ik0wIDg1QzAgNzAuNjQgMTEuNjQgNTkgMjYgNTlINzRDODguMzYgNTkgMTAwIDcwLjY0IDEwMCA4NVYxMDBIMFY4NVoiIGZpbGw9IiNhOGI5Y2UiLz4KPC9zdmc+'
|
|
|
|
|
@ -130,6 +131,8 @@ const locationCoords = {
|
|
|
|
|
const ocPositions = ref([])
|
|
|
|
|
// 每个地点的实时状态(位置、在场人数、对应 oc 列表)
|
|
|
|
|
const locationStatuses = ref([])
|
|
|
|
|
// 是否已经按当前用户加载了专属 ocList
|
|
|
|
|
const ocLoadedForUser = ref(false)
|
|
|
|
|
|
|
|
|
|
// 辅助函数
|
|
|
|
|
const handleImageError = (event) => {
|
|
|
|
|
@ -283,6 +286,19 @@ const computePositions = () => {
|
|
|
|
|
|
|
|
|
|
let posTimer = null
|
|
|
|
|
onMounted(() => {
|
|
|
|
|
// 尝试按当前用户加载其专属 OC 列表(如果用户已登录)
|
|
|
|
|
if (currentUser.value && currentUser.value.username) {
|
|
|
|
|
try {
|
|
|
|
|
loadOCFromStorage(currentUser.value.username)
|
|
|
|
|
ocLoadedForUser.value = true
|
|
|
|
|
} catch (e) {
|
|
|
|
|
console.error('Failed to load user-specific OC list:', e)
|
|
|
|
|
ocLoadedForUser.value = false
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
ocLoadedForUser.value = false
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
computePositions()
|
|
|
|
|
posTimer = setInterval(computePositions, 60 * 1000)
|
|
|
|
|
document.addEventListener('click', closePopoverOnClickOutside)
|
|
|
|
|
@ -292,6 +308,24 @@ onUnmounted(() => {
|
|
|
|
|
document.removeEventListener('click', closePopoverOnClickOutside)
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
// 当登录用户变更时,尝试加载该用户的 OC 列表并刷新位置(确保地图只显示自己的 OC)
|
|
|
|
|
watch(currentUser, (val) => {
|
|
|
|
|
if (val && val.username) {
|
|
|
|
|
try {
|
|
|
|
|
loadOCFromStorage(val.username)
|
|
|
|
|
ocLoadedForUser.value = true
|
|
|
|
|
} catch (e) {
|
|
|
|
|
console.error('Failed to load OC list for user on change:', e)
|
|
|
|
|
ocLoadedForUser.value = false
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
ocLoadedForUser.value = false
|
|
|
|
|
// 恢复为全局加载(不展示其他账号的 OC)
|
|
|
|
|
loadOCFromStorage()
|
|
|
|
|
}
|
|
|
|
|
computePositions()
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
// OC 信息弹窗与控制弹窗显示/隐藏
|
|
|
|
|
const showOCInfo = ref(false)
|
|
|
|
|
const selectedOC = ref(null)
|
|
|
|
|
@ -349,7 +383,7 @@ const closePopoverOnClickOutside = (event) => {
|
|
|
|
|
.community-container {
|
|
|
|
|
display: flex;
|
|
|
|
|
height: 100vh;
|
|
|
|
|
background: linear-gradient(135deg, #ffc6c6 0%, #7486c0 100%);
|
|
|
|
|
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
|
|
|
|
position: relative;
|
|
|
|
|
overflow: hidden;
|
|
|
|
|
}
|
|
|
|
|
|