diff --git a/admin/src/components/ImageUpload/index.vue b/admin/src/components/ImageUpload/index.vue
index 5a333b1..7c08334 100644
--- a/admin/src/components/ImageUpload/index.vue
+++ b/admin/src/components/ImageUpload/index.vue
@@ -60,9 +60,8 @@ import { ElMessage } from 'element-plus'
import type { UploadFile, UploadFiles, UploadRawFile, UploadUserFile } from 'element-plus'
import { getToken } from '@/utils/auth'
-// 获取后端基础地址(去掉 /api 后缀)
-const API_BASE = import.meta.env.VITE_API_BASE_URL || ''
-const SERVER_BASE = API_BASE.replace(/\/api$/, '')
+// 获取静态资源服务器地址(AppApi,用于图片等静态资源)
+const STATIC_BASE = import.meta.env.VITE_STATIC_BASE_URL || 'http://localhost:5001'
// 处理图片URL,将相对路径转换为完整URL
function getFullImageUrl(url: string): string {
@@ -71,8 +70,8 @@ function getFullImageUrl(url: string): string {
if (url.startsWith('http://') || url.startsWith('https://')) {
return url
}
- // 相对路径,拼接服务器地址
- return `${SERVER_BASE}${url.startsWith('/') ? '' : '/'}${url}`
+ // 相对路径,拼接静态资源服务器地址
+ return `${STATIC_BASE}${url.startsWith('/') ? '' : '/'}${url}`
}
interface Props {
diff --git a/miniapp/components/Empty/index.vue b/miniapp/components/Empty/index.vue
index bcfd7ca..644654f 100644
--- a/miniapp/components/Empty/index.vue
+++ b/miniapp/components/Empty/index.vue
@@ -49,8 +49,8 @@ export default {
emits: ['click'],
data() {
return {
- defaultImage: '/static/empty.png',
- hasDefaultImage: false // 默认不使用图片,使用emoji
+ defaultImage: '/static/ic_empty.png',
+ hasDefaultImage: true // 使用空占位图
}
},
methods: {
diff --git a/miniapp/components/UserCard/index.vue b/miniapp/components/UserCard/index.vue
index f3ce59f..d8c401f 100644
--- a/miniapp/components/UserCard/index.vue
+++ b/miniapp/components/UserCard/index.vue
@@ -236,7 +236,7 @@ export default {
diff --git a/miniapp/pages/index/index.vue b/miniapp/pages/index/index.vue
index 2739181..751a596 100644
--- a/miniapp/pages/index/index.vue
+++ b/miniapp/pages/index/index.vue
@@ -14,28 +14,36 @@
@@ -70,15 +82,8 @@
-
+
{
pageLoading.value = true
try {
+ // 获取状态栏高度
+ uni.getSystemInfo({
+ success: (res) => {
+ statusBarHeight.value = res.statusBarHeight || 20
+ }
+ })
+
// 恢复用户状态
userStore.restoreFromStorage()
@@ -423,7 +438,24 @@
// 联系用户
const handleUserContact = (userId) => {
- // 检查是否完善资料
+ // 1. 首先检查是否已登录
+ if (!userStore.isLoggedIn) {
+ uni.showModal({
+ title: '提示',
+ content: '请先登录后再联系对方',
+ confirmText: '去登录',
+ success: (res) => {
+ if (res.confirm) {
+ uni.navigateTo({
+ url: '/pages/auth/login'
+ })
+ }
+ }
+ })
+ return
+ }
+
+ // 2. 检查是否完善资料
if (!userStore.isProfileCompleted) {
uni.showModal({
title: '提示',
@@ -440,7 +472,7 @@
return
}
- // 跳转到聊天页面(后续会实现解锁逻辑)
+ // 3. 跳转到聊天页面(后续会实现解锁逻辑)
uni.navigateTo({
url: `/pages/chat/index?targetUserId=${userId}`
})
@@ -487,6 +519,7 @@
})
return {
+ statusBarHeight,
pageLoading,
listLoading,
noMoreData,
@@ -518,13 +551,6 @@
handleRefresh
}
},
- // 下拉刷新
- async onPullDownRefresh() {
- if (this.loadRecommendList) {
- await this.loadRecommendList()
- }
- uni.stopPullDownRefresh()
- },
// 页面显示
onShow() {
// 每次显示页面时检查弹窗
@@ -554,72 +580,84 @@
flex-shrink: 0;
}
- // Banner 轮播图区域
+ // Banner区域
.banner-section {
- width: 100%;
position: relative;
+ width: 100%;
+ }
- .banner-overlay {
- position: absolute;
- top: 0;
- left: 0;
- right: 0;
- z-index: 10;
- padding: 20rpx 24rpx;
- padding-top: calc(20rpx + env(safe-area-inset-top));
+ // Banner 轮播图
+ .banner-swiper {
+ width: 100%;
+ height: 420rpx;
+
+ .banner-image {
+ width: 100%;
+ height: 100%;
+ }
+ }
+
+ .banner-placeholder {
+ width: 100%;
+ height: 420rpx;
+ background: linear-gradient(135deg, #FFB6C1 0%, #FFC0CB 100%);
+ }
+
+ // 浮层(导航栏+搜索框)
+ .banner-overlay {
+ position: absolute;
+ top: 0;
+ left: 0;
+ right: 0;
+ z-index: 10;
+ }
+
+ // 自定义导航栏
+ .custom-navbar {
+ .navbar-content {
+ height: 44px;
+ display: flex;
+ align-items: center;
+ justify-content: center;
.header-title {
font-size: 36rpx;
font-weight: 600;
color: #fff;
- margin-top: 96rpx;
text-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.2);
- margin-bottom: 28rpx;
- text-align: center;
- }
-
- .search-bar {
- display: flex;
- align-items: center;
- justify-content: center;
- background: rgba(255, 255, 255, 0.95);
- border-radius: 40rpx;
- padding: 20rpx 24rpx;
-
- .search-icon {
- font-size: 28rpx;
- margin-right: 12rpx;
- color: #999;
- }
-
- .search-placeholder {
- font-size: 28rpx;
- color: #999;
- }
}
}
+ }
- .banner-swiper {
- width: 100%;
- height: 420rpx;
+ // 搜索框
+ .search-section {
+ padding: 16rpx 24rpx;
- .banner-image {
- width: 100%;
- height: 100%;
+ .search-bar {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ background: rgba(255, 255, 255, 0.95);
+ border-radius: 40rpx;
+ padding: 20rpx 24rpx;
+ box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.08);
+
+ .search-icon {
+ font-size: 28rpx;
+ margin-right: 12rpx;
+ color: #999;
}
- }
- .banner-placeholder {
- width: 100%;
- height: 420rpx;
- background: linear-gradient(135deg, #FFB6C1 0%, #FFC0CB 100%);
+ .search-placeholder {
+ font-size: 28rpx;
+ color: #999;
+ }
}
}
// 金刚位导航
.kingkong-section {
padding: 20rpx;
- background-color: #fff;
.kingkong-grid {
display: flex;
@@ -650,15 +688,38 @@
// 推荐标题栏
.section-header {
display: flex;
+ flex-direction: column;
align-items: center;
- justify-content: space-between;
- padding: 20rpx;
+ justify-content: center;
+ padding: 5rpx 20rpx 24rpx;
background-color: #f8f8f8;
- .section-title {
- font-size: 32rpx;
- font-weight: 600;
- color: #333;
+ .section-title-wrapper {
+ display: flex;
+ align-items: center;
+ margin-bottom: 8rpx;
+
+ .section-title-main {
+ font-size: 36rpx;
+ font-weight: 600;
+ color: #333;
+ }
+
+ .section-title-highlight {
+ font-size: 42rpx;
+ color: #FF6A6A;
+ background: transparent;
+ padding: 0;
+ border-radius: 0;
+ font-weight: 600;
+ font-style: italic;
+ box-shadow: none;
+ }
+ }
+
+ .section-subtitle {
+ font-size: 24rpx;
+ color: #999;
}
.section-more {
diff --git a/miniapp/pages/interact/favoritedMe.vue b/miniapp/pages/interact/favoritedMe.vue
index ffce3d4..5b80c7a 100644
--- a/miniapp/pages/interact/favoritedMe.vue
+++ b/miniapp/pages/interact/favoritedMe.vue
@@ -128,8 +128,8 @@ export default {
const api = activeTab.value === 'favoritedMe' ? getFavoritedMe : getMyFavorite
const res = await api(pageIndex.value, pageSize)
- if (res && res.success) {
- const newList = res.data?.list || []
+ if (res && (res.success || res.code === 0)) {
+ const newList = res.data?.items || []
if (refresh) {
list.value = newList
diff --git a/miniapp/pages/interact/myFavorite.vue b/miniapp/pages/interact/myFavorite.vue
index 5a3c051..705b83e 100644
--- a/miniapp/pages/interact/myFavorite.vue
+++ b/miniapp/pages/interact/myFavorite.vue
@@ -128,8 +128,8 @@ export default {
const api = activeTab.value === 'favoritedMe' ? getFavoritedMe : getMyFavorite
const res = await api(pageIndex.value, pageSize)
- if (res && res.success) {
- const newList = res.data?.list || []
+ if (res && (res.success || res.code === 0)) {
+ const newList = res.data?.items || []
if (refresh) {
list.value = newList
diff --git a/miniapp/pages/interact/myUnlocked.vue b/miniapp/pages/interact/myUnlocked.vue
index 20804d5..5609e67 100644
--- a/miniapp/pages/interact/myUnlocked.vue
+++ b/miniapp/pages/interact/myUnlocked.vue
@@ -128,8 +128,8 @@ export default {
const api = activeTab.value === 'unlockedMe' ? getUnlockedMe : getMyUnlocked
const res = await api(pageIndex.value, pageSize)
- if (res && res.success) {
- const newList = res.data?.list || []
+ if (res && (res.success || res.code === 0)) {
+ const newList = res.data?.items || []
if (refresh) {
list.value = newList
diff --git a/miniapp/pages/interact/myViewed.vue b/miniapp/pages/interact/myViewed.vue
index b857711..73069c8 100644
--- a/miniapp/pages/interact/myViewed.vue
+++ b/miniapp/pages/interact/myViewed.vue
@@ -128,8 +128,8 @@ export default {
const api = activeTab.value === 'viewedMe' ? getViewedMe : getMyViewed
const res = await api(pageIndex.value, pageSize)
- if (res && res.success) {
- const newList = res.data?.list || []
+ if (res && (res.success || res.code === 0)) {
+ const newList = res.data?.items || []
if (refresh) {
list.value = newList
diff --git a/miniapp/pages/interact/unlockedMe.vue b/miniapp/pages/interact/unlockedMe.vue
index d553b53..339ecfd 100644
--- a/miniapp/pages/interact/unlockedMe.vue
+++ b/miniapp/pages/interact/unlockedMe.vue
@@ -128,8 +128,8 @@ export default {
const api = activeTab.value === 'unlockedMe' ? getUnlockedMe : getMyUnlocked
const res = await api(pageIndex.value, pageSize)
- if (res && res.success) {
- const newList = res.data?.list || []
+ if (res && (res.success || res.code === 0)) {
+ const newList = res.data?.items || []
if (refresh) {
list.value = newList
diff --git a/miniapp/pages/interact/viewedMe.vue b/miniapp/pages/interact/viewedMe.vue
index 96e81d9..49d033b 100644
--- a/miniapp/pages/interact/viewedMe.vue
+++ b/miniapp/pages/interact/viewedMe.vue
@@ -128,8 +128,8 @@ export default {
const api = activeTab.value === 'viewedMe' ? getViewedMe : getMyViewed
const res = await api(pageIndex.value, pageSize)
- if (res && res.success) {
- const newList = res.data?.list || []
+ if (res && (res.success || res.code === 0)) {
+ const newList = res.data?.items || []
if (refresh) {
list.value = newList
diff --git a/miniapp/pages/profile/detail.vue b/miniapp/pages/profile/detail.vue
index 4eb8ab8..08d2b18 100644
--- a/miniapp/pages/profile/detail.vue
+++ b/miniapp/pages/profile/detail.vue
@@ -52,6 +52,10 @@
{{ userDetail.nickname }}
({{ relationshipText }})
+
相亲ID: {{ userDetail.xiangQinNo }}
@@ -64,10 +68,6 @@
{{ genderText }} · {{ userDetail.birthYear }}年
-
- 已实名
- 会员
-
@@ -259,7 +259,7 @@
import { ref, computed, onMounted } from 'vue'
import { useUserStore } from '@/store/user.js'
import { getUserDetail } from '@/api/user.js'
-import { favorite, unlock, recordView } from '@/api/interact.js'
+import { favorite, unlock } from '@/api/interact.js'
import { getFullImageUrl } from '@/utils/image.js'
import Loading from '@/components/Loading/index.vue'
import Popup from '@/components/Popup/index.vue'
@@ -459,14 +459,14 @@ const loadUserDetail = async () => {
loading.value = true
try {
const res = await getUserDetail(userId.value)
- if (res && res.code === 0 && res.data) {
+ // 后端返回 code: 0 表示成功
+ if (res && (res.success || res.code === 0) && res.data) {
userDetail.value = res.data
isFavorited.value = res.data.isFavorited || false
isUnlocked.value = res.data.isUnlocked || false
remainingUnlockQuota.value = res.data.remainingUnlockQuota || 0
- // 记录浏览
- await recordView(userId.value)
+ // 已登录用户记录浏览(后端已处理,这里不需要再调用)
}
} catch (error) {
console.error('加载用户详情失败:', error)
@@ -492,9 +492,24 @@ const previewPhoto = (index) => {
// 收藏处理
const handleFavorite = async () => {
+ // 检查是否登录
+ if (!userStore.isLoggedIn) {
+ uni.showModal({
+ title: '提示',
+ content: '请先登录后再收藏',
+ confirmText: '去登录',
+ success: (res) => {
+ if (res.confirm) {
+ uni.navigateTo({ url: '/pages/login/index' })
+ }
+ }
+ })
+ return
+ }
+
try {
const res = await favorite(userId.value)
- if (res && res.code === 0) {
+ if (res && (res.success || res.code === 0)) {
isFavorited.value = res.data?.isFavorited ?? !isFavorited.value
uni.showToast({
title: isFavorited.value ? '收藏成功' : '已取消收藏',
@@ -513,6 +528,21 @@ const handleShare = () => {
// 联系处理
const handleContact = () => {
+ // 检查是否登录
+ if (!userStore.isLoggedIn) {
+ uni.showModal({
+ title: '提示',
+ content: '请先登录后再联系对方',
+ confirmText: '去登录',
+ success: (res) => {
+ if (res.confirm) {
+ uni.navigateTo({ url: '/pages/login/index' })
+ }
+ }
+ })
+ return
+ }
+
if (!userStore.isProfileCompleted) {
showProfilePopup.value = true
return
@@ -550,7 +580,7 @@ const handleConfirmUnlock = async () => {
try {
const res = await unlock(userId.value)
- if (res && res.code === 0) {
+ if (res && (res.success || res.code === 0)) {
isUnlocked.value = true
showUnlockPopup.value = false
remainingUnlockQuota.value = Math.max(0, remainingUnlockQuota.value - 1)
@@ -569,6 +599,21 @@ const handleGoMember = () => {
// 拨打电话
const handleCall = () => {
+ // 检查是否登录
+ if (!userStore.isLoggedIn) {
+ uni.showModal({
+ title: '提示',
+ content: '请先登录后再联系对方',
+ confirmText: '去登录',
+ success: (res) => {
+ if (res.confirm) {
+ uni.navigateTo({ url: '/pages/login/index' })
+ }
+ }
+ })
+ return
+ }
+
if (!isUnlocked.value) {
showUnlockPopup.value = true
return
@@ -641,16 +686,16 @@ defineExpose({
padding: 0 24rpx;
.navbar-back {
- width: 60rpx;
- height: 60rpx;
+ width: 80rpx;
+ height: 80rpx;
display: flex;
align-items: center;
justify-content: center;
.back-icon {
- font-size: 48rpx;
+ font-size: 64rpx;
color: #fff;
- font-weight: 300;
+ font-weight: 400;
}
}
@@ -702,6 +747,8 @@ defineExpose({
display: flex;
align-items: center;
margin-bottom: 8rpx;
+ flex-wrap: wrap;
+ gap: 8rpx;
.nickname {
font-size: 32rpx;
@@ -712,7 +759,28 @@ defineExpose({
.relationship {
font-size: 28rpx;
color: #666;
+ }
+
+ .header-tags {
+ display: flex;
+ gap: 8rpx;
margin-left: 8rpx;
+
+ .tag {
+ font-size: 20rpx;
+ padding: 4rpx 12rpx;
+ border-radius: 16rpx;
+
+ &.tag-realname {
+ background: #e8f5e9;
+ color: #4caf50;
+ }
+
+ &.tag-member {
+ background: linear-gradient(135deg, #fff3e0 0%, #ffe0b2 100%);
+ color: #ff9800;
+ }
+ }
}
}
@@ -758,9 +826,8 @@ defineExpose({
.gender-year-row {
display: flex;
align-items: center;
+ justify-content: space-between;
margin-bottom: 24rpx;
- flex-wrap: wrap;
- gap: 16rpx;
.gender-year {
font-size: 40rpx;
@@ -772,29 +839,7 @@ defineExpose({
}
}
- .tags-row {
- display: flex;
- gap: 12rpx;
-
- .tag {
- font-size: 22rpx;
- padding: 6rpx 16rpx;
- border-radius: 20rpx;
-
- &.tag-realname {
- background: #e8f5e9;
- color: #4caf50;
- }
-
- &.tag-member {
- background: linear-gradient(135deg, #fff3e0 0%, #ffe0b2 100%);
- color: #ff9800;
- }
- }
- }
-
.share-btn {
- margin-left: auto;
padding: 12rpx 32rpx;
font-size: 26rpx;
color: #ff6b6b;
@@ -1034,7 +1079,7 @@ defineExpose({
height: 88rpx;
line-height: 88rpx;
font-size: 30rpx;
- border-radius: 44rpx;
+ border-radius: 16rpx;
border: none;
&::after {
@@ -1043,23 +1088,21 @@ defineExpose({
}
.btn-greet {
- background: linear-gradient(135deg, #ff8a8a 0%, #ff6b6b 100%);
+ background: #4cd964;
color: #fff;
}
.btn-favorite {
- background: #fff;
- color: #666;
- border: 2rpx solid #ddd;
+ background: #f5d742;
+ color: #fff;
&.active {
- color: #ff6b6b;
- border-color: #ff6b6b;
+ background: #e5c732;
}
}
.btn-call {
- background: linear-gradient(135deg, #ffb5b5 0%, #ff9a9a 100%);
+ background: #ff9a9a;
color: #fff;
}
}
diff --git a/miniapp/pages/realname/index.vue b/miniapp/pages/realname/index.vue
index 3ec86c2..cca6c05 100644
--- a/miniapp/pages/realname/index.vue
+++ b/miniapp/pages/realname/index.vue
@@ -3,8 +3,24 @@
+
+
+
+
+
+
+
+
+
+ ‹
+
+ 实名认证
+
+
+
+
-
+
✓
实名认证已完成
@@ -25,198 +41,174 @@
-
-
-