mirror of
https://github.com/ialley-workshop-open/uni-halo.git
synced 2026-07-27 04:20:43 +08:00
feat: 新增点赞、游客评论、分享等核心功能,重构页面逻辑
1. 新增全局点赞状态管理,使用metadata.name做key并持久化存储 2. 新增游客信息存储与评论面板,支持游客评论互动 3. 新增全局分享hook,为多个页面配置分享功能 4. 重构登录页面,支持登录/注册切换与游客访问模式 5. 合并注册页到登录页,简化路由结构 6. 优化剪贴板工具函数,支持自定义提示文本 7. 重构个人中心页面,支持游客信息管理 8. 修复相册页面标题与样式问题 9. 移除无用的备份文件与测试代码
This commit is contained in:
+176
-87
@@ -2,38 +2,92 @@
|
||||
import { storeToRefs } from 'pinia'
|
||||
import { LOGIN_PAGE } from '@/router/config'
|
||||
import { useUserStore } from '@/store'
|
||||
import { useGuestStore } from '@/store/guest'
|
||||
import { useTokenStore } from '@/store/token'
|
||||
import i18n, { t } from '@/locale/index'
|
||||
import { setTabbarItem } from '@/tabbar/i18n'
|
||||
import GuestInfoPanel from '@/components/post-detail/uh-guest-info-panel.vue'
|
||||
|
||||
defineOptions({
|
||||
name: 'Mine',
|
||||
})
|
||||
defineOptions({ name: 'Mine' })
|
||||
|
||||
definePage({
|
||||
style: {
|
||||
navigationBarTitleText: '我的',
|
||||
navigationBarBackgroundColor: '#ffffff',
|
||||
enablePullDownRefresh: true,
|
||||
},
|
||||
})
|
||||
|
||||
const userStore = useUserStore()
|
||||
const tokenStore = useTokenStore()
|
||||
// 使用storeToRefs解构userInfo
|
||||
const guestStore = useGuestStore()
|
||||
|
||||
const { userInfo } = storeToRefs(userStore)
|
||||
|
||||
// 微信小程序下登录
|
||||
async function handleLogin() {
|
||||
// #ifdef MP-WEIXIN
|
||||
// 微信登录
|
||||
await tokenStore.wxLogin()
|
||||
/** 是否已登录 */
|
||||
const hasLogin = computed(() => tokenStore.hasLogin)
|
||||
/** 是否已填写游客信息 */
|
||||
const hasGuestInfo = computed(() => guestStore.isComplete)
|
||||
|
||||
/** 显示的头像 */
|
||||
const displayAvatar = computed(() => {
|
||||
if (hasLogin.value && userInfo.value.avatar) {
|
||||
return userInfo.value.avatar
|
||||
}
|
||||
return '/static/images/default-avatar.png'
|
||||
})
|
||||
|
||||
/** 显示的名称 */
|
||||
const displayName = computed(() => {
|
||||
if (hasLogin.value) {
|
||||
return userInfo.value.nickname || userInfo.value.username
|
||||
}
|
||||
if (hasGuestInfo.value) {
|
||||
return guestStore.info.displayName
|
||||
}
|
||||
return '未登录'
|
||||
})
|
||||
|
||||
/** 显示的副标题 */
|
||||
const displaySubtitle = computed(() => {
|
||||
if (hasLogin.value) {
|
||||
return userInfo.value.role || userInfo.value.username
|
||||
}
|
||||
if (hasGuestInfo.value) {
|
||||
return guestStore.info.email
|
||||
}
|
||||
return '登录后解锁更多功能'
|
||||
})
|
||||
|
||||
/** 用户状态标签 */
|
||||
const statusLabel = computed(() => {
|
||||
if (hasLogin.value) return '已登录'
|
||||
if (hasGuestInfo.value) return '游客'
|
||||
return '未登录'
|
||||
})
|
||||
|
||||
const statusColor = computed(() => {
|
||||
if (hasLogin.value) return 'bg-green-50 text-green-600'
|
||||
if (hasGuestInfo.value) return 'bg-amber-50 text-amber-600'
|
||||
return 'bg-gray-100 text-gray-500'
|
||||
})
|
||||
|
||||
// ---- 游客信息编辑 ----
|
||||
const showGuestPanel = ref(false)
|
||||
|
||||
function handleEditGuest() {
|
||||
showGuestPanel.value = true
|
||||
}
|
||||
|
||||
function handleGuestSaved() {
|
||||
showGuestPanel.value = false
|
||||
uni.showToast({ title: '保存成功', icon: 'success' })
|
||||
}
|
||||
|
||||
// ---- 登录/退出 ----
|
||||
function handleLogin() {
|
||||
// #ifdef MP-WEIXIN
|
||||
tokenStore.wxLogin()
|
||||
// #endif
|
||||
// #ifndef MP-WEIXIN
|
||||
uni.navigateTo({
|
||||
url: `${LOGIN_PAGE}`,
|
||||
})
|
||||
uni.navigateTo({ url: LOGIN_PAGE })
|
||||
// #endif
|
||||
}
|
||||
|
||||
@@ -43,93 +97,121 @@ function handleLogout() {
|
||||
content: '确定要退出登录吗?',
|
||||
success: (res) => {
|
||||
if (res.confirm) {
|
||||
// 清空用户信息
|
||||
useTokenStore().logout()
|
||||
// 执行退出登录逻辑
|
||||
uni.showToast({
|
||||
title: '退出登录成功',
|
||||
icon: 'success',
|
||||
})
|
||||
// #ifdef MP-WEIXIN
|
||||
// 微信小程序,去首页
|
||||
// uni.reLaunch({ url: '/pages/index/index' })
|
||||
// #endif
|
||||
// #ifndef MP-WEIXIN
|
||||
// 非微信小程序,去登录页
|
||||
// uni.navigateTo({ url: LOGIN_PAGE })
|
||||
// #endif
|
||||
tokenStore.logout()
|
||||
uni.showToast({ title: '已退出登录', icon: 'success' })
|
||||
}
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
const current = ref(uni.getLocale())
|
||||
const languages = [
|
||||
{
|
||||
value: 'zh-Hans',
|
||||
name: '中文',
|
||||
checked: 'true',
|
||||
},
|
||||
{
|
||||
value: 'en',
|
||||
name: '英文',
|
||||
},
|
||||
// ---- 功能导航 ----
|
||||
interface NavItem {
|
||||
icon: string
|
||||
label: string
|
||||
path?: string
|
||||
showArrow?: boolean
|
||||
}
|
||||
|
||||
const navList: NavItem[] = [
|
||||
{ icon: 'file', label: '免责声明', path: '', showArrow: true },
|
||||
{ icon: 'chat', label: '在线客服', path: '', showArrow: true },
|
||||
{ icon: 'edit', label: '意见反馈', path: '', showArrow: true },
|
||||
{ icon: 'info-circle', label: '关于项目', path: '/subpkg-blog/about/about', showArrow: true },
|
||||
]
|
||||
|
||||
function radioChange(evt) {
|
||||
// console.log(evt)
|
||||
current.value = evt.detail.value
|
||||
// 下面2句缺一不可!!!
|
||||
uni.setLocale(evt.detail.value)
|
||||
i18n.global.locale = evt.detail.value
|
||||
|
||||
// 底部tabbar需要重新设置一下
|
||||
setTabbarItem()
|
||||
// 本页的标题也需要重新设置一下
|
||||
uni.setNavigationBarTitle({
|
||||
title: t('i18n.title'),
|
||||
})
|
||||
function handleNavClick(item: NavItem) {
|
||||
if (item.path) {
|
||||
uni.navigateTo({ url: item.path })
|
||||
}
|
||||
else {
|
||||
uni.showToast({ title: '即将开放,敬请期待', icon: 'none' })
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<view class="bg-page3 box-border min-h-screen w-full flex flex-col items-center justify-center gap-y-6 px-4">
|
||||
<view class="mt-3 break-all px-3 text-center text-green-500">
|
||||
{{ userInfo.username ? '已登录' : '未登录' }}
|
||||
</view>
|
||||
<view class="mt-3 break-all px-3">
|
||||
{{ JSON.stringify(userInfo, null, 2) }}
|
||||
</view>
|
||||
|
||||
<!-- 切换语言 -->
|
||||
<view class="mt-6 w-full flex flex-col items-center justify-center">
|
||||
<view class="mb-2 text-gray-900 font-bold">
|
||||
切换语言
|
||||
</view>
|
||||
<view class="w-full flex items-center justify-center gap-4">
|
||||
<radio-group class="flex flex-col items-center justify-center gap-2" @change="radioChange">
|
||||
<label
|
||||
v-for="item in languages"
|
||||
:key="item.value"
|
||||
class="flex items-center gap-x-2"
|
||||
>
|
||||
<view>
|
||||
<radio :value="item.value" :checked="item.value === current" />
|
||||
<view class="bg-page3 box-border min-h-screen w-full flex flex-col gap-y-4 px-4 pt-4">
|
||||
<!-- 用户信息卡片 -->
|
||||
<view class="uh-shadow-xs box-border flex flex-col rounded-2xl bg-white p-4">
|
||||
<view class="w-full flex items-center gap-x-3">
|
||||
<!-- 头像 -->
|
||||
<image
|
||||
class="uh-shadow-xs h-16 w-16 shrink-0 border-2 border-white rounded-full border-solid"
|
||||
:src="displayAvatar"
|
||||
mode="scaleToFill"
|
||||
/>
|
||||
<!-- 信息区 -->
|
||||
<view class="flex flex-1 flex-col gap-y-1">
|
||||
<view class="flex items-center gap-x-2">
|
||||
<text class="text-base text-gray-900 font-bold">{{ displayName }}</text>
|
||||
<view class="rounded-full px-2 py-0.5" :class="statusColor">
|
||||
<text class="text-[10px] font-medium">{{ statusLabel }}</text>
|
||||
</view>
|
||||
<view>{{ item.name }}</view>
|
||||
</label>
|
||||
</radio-group>
|
||||
</view>
|
||||
<text class="line-clamp-1 text-xs text-gray-500">{{ displaySubtitle }}</text>
|
||||
</view>
|
||||
<!-- 游客编辑入口 -->
|
||||
<view
|
||||
v-if="!hasLogin && hasGuestInfo"
|
||||
class="h-8 w-8 center shrink-0 rounded-full bg-gray-50"
|
||||
@click="handleEditGuest"
|
||||
>
|
||||
<wd-icon name="edit" color="#6B7280" :size="16" />
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 游客信息快捷编辑入口(未登录且未填写游客信息时) -->
|
||||
<view
|
||||
v-if="!hasLogin && !hasGuestInfo"
|
||||
class="mt-3 box-border flex items-center gap-x-2 rounded-xl bg-gray-50 px-3 py-2.5"
|
||||
@click="handleEditGuest"
|
||||
>
|
||||
<wd-icon name="edit" color="#9CA3AF" :size="14" />
|
||||
<text class="text-xs text-gray-400">填写游客信息(用于评论互动)</text>
|
||||
<wd-icon name="arrow-right" color="#D1D5DB" :size="14" />
|
||||
</view>
|
||||
|
||||
<!-- 已登录时显示的额外信息 -->
|
||||
<view v-if="hasLogin" class="mt-3 my-1 h-px w-full bg-gray-50" />
|
||||
<view v-if="hasLogin" class="flex items-center justify-between">
|
||||
<text class="text-xs text-gray-400">账号:{{ userInfo.username }}</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="mt-6">
|
||||
<view class="m-auto w-160px text-center">
|
||||
<button v-if="tokenStore.hasLogin" type="warn" class="w-full rounded-xl text-xs" @click="handleLogout">
|
||||
退出登录
|
||||
</button>
|
||||
<button v-else class="w-full rounded-xl bg-gray-900 py-2.5 text-xs text-white" @click="handleLogin">
|
||||
立即登录
|
||||
</button>
|
||||
<!-- 功能导航 -->
|
||||
<view class="uh-shadow-xs box-border flex flex-col rounded-2xl bg-white">
|
||||
<view
|
||||
v-for="(item, index) in navList"
|
||||
:key="item.label"
|
||||
class="box-border flex items-center justify-between px-4 py-3.5"
|
||||
:class="{ 'border-b border-gray-50': index < navList.length - 1 }"
|
||||
@click="handleNavClick(item)"
|
||||
>
|
||||
<view class="flex items-center gap-x-3">
|
||||
<view class="h-8 w-8 center rounded-xl bg-gray-50">
|
||||
<wd-icon :name="item.icon" color="#6B7280" :size="16" />
|
||||
</view>
|
||||
<text class="text-sm text-gray-800">{{ item.label }}</text>
|
||||
</view>
|
||||
<wd-icon v-if="item.showArrow" name="arrow-right" color="#D1D5DB" :size="14" />
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 登录/退出按钮 -->
|
||||
<view class="mt-2 w-full">
|
||||
<view
|
||||
v-if="hasLogin"
|
||||
class="uh-shadow-xs h-11 w-full center rounded-2xl bg-white text-sm text-red-500 font-medium"
|
||||
@click="handleLogout"
|
||||
>
|
||||
退出登录
|
||||
</view>
|
||||
<view
|
||||
v-else
|
||||
class="h-11 w-full center rounded-2xl bg-gray-900 text-sm text-white font-medium"
|
||||
@click="handleLogin"
|
||||
>
|
||||
立即登录
|
||||
</view>
|
||||
</view>
|
||||
|
||||
@@ -137,5 +219,12 @@ function radioChange(evt) {
|
||||
<view class="w-full shrink-0">
|
||||
<uh-tabbar-page-placeholder />
|
||||
</view>
|
||||
|
||||
<!-- 游客信息编辑面板 -->
|
||||
<GuestInfoPanel
|
||||
v-if="showGuestPanel"
|
||||
@close="showGuestPanel = false"
|
||||
@saved="handleGuestSaved"
|
||||
/>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
Reference in New Issue
Block a user