diff --git a/admin/src/api/memberTier.ts b/admin/src/api/memberTier.ts index 3003942..933da94 100644 --- a/admin/src/api/memberTier.ts +++ b/admin/src/api/memberTier.ts @@ -11,6 +11,7 @@ export interface MemberTier { benefitsImage?: string sort: number status: number + durationMonths: number createTime: string updateTime: string } @@ -25,6 +26,7 @@ export interface CreateMemberTierRequest { benefitsImage?: string sort: number status: number + durationMonths: number } export interface UpdateMemberTierRequest extends CreateMemberTierRequest {} diff --git a/admin/src/views/content/memberTier.vue b/admin/src/views/content/memberTier.vue index ed6c6ff..5dc08eb 100644 --- a/admin/src/views/content/memberTier.vue +++ b/admin/src/views/content/memberTier.vue @@ -41,6 +41,9 @@ ¥{{ tier.originalPrice }}
{{ tier.discount }}
+
+ {{ tier.durationMonths === 0 ? '永久' : tier.durationMonths + '个月' }} +
@@ -103,6 +106,7 @@ + @@ -139,6 +143,15 @@ + + + + +
填0表示永久,其他数字为月数
+
+
+
+
{ formData.benefitsImage = '' formData.sort = 0 formData.status = 1 + formData.durationMonths = 0 editingId.value = null } @@ -296,6 +311,7 @@ const handleEdit = (row: MemberTier) => { formData.benefitsImage = row.benefitsImage || '' formData.sort = row.sort formData.status = row.status + formData.durationMonths = row.durationMonths || 0 dialogVisible.value = true } @@ -356,7 +372,8 @@ const handleSubmit = async () => { discount: formData.discount || undefined, benefitsImage: formData.benefitsImage || undefined, sort: formData.sort, - status: formData.status + status: formData.status, + durationMonths: formData.durationMonths } if (isEdit.value && editingId.value) { @@ -506,6 +523,16 @@ onMounted(() => { display: inline-block; } +.tier-duration { + font-size: 12px; + color: #409eff; + background: #ecf5ff; + padding: 2px 8px; + border-radius: 4px; + display: inline-block; + margin-top: 8px; +} + /* 权益图预览 */ .tier-image { height: 120px; diff --git a/admin/src/views/member/list.vue b/admin/src/views/member/list.vue index bde0801..0904e6d 100644 --- a/admin/src/views/member/list.vue +++ b/admin/src/views/member/list.vue @@ -45,7 +45,8 @@ const memberLevelOptions = [ { label: '全部', value: '' }, { label: '不限时', value: 1 }, { label: '诚意', value: 2 }, - { label: '家庭版', value: 3 } + { label: '家庭版', value: 3 }, + { label: '限时', value: 4 } ] // 会员状态选项 @@ -121,7 +122,8 @@ const getMemberLevelType = (level: number): 'success' | 'warning' | 'danger' | ' const types: Record = { 1: 'success', 2: 'warning', - 3: 'danger' + 3: 'danger', + 4: 'primary' } return types[level] || 'info' } diff --git a/admin/src/views/user/detail.vue b/admin/src/views/user/detail.vue index a56889c..c344e80 100644 --- a/admin/src/views/user/detail.vue +++ b/admin/src/views/user/detail.vue @@ -111,7 +111,8 @@ const memberLevelOptions = [ { value: 0, label: '非会员' }, { value: 1, label: '不限时会员' }, { value: 2, label: '诚意会员' }, - { value: 3, label: '家庭版会员' } + { value: 3, label: '家庭版会员' }, + { value: 4, label: '限时会员' } ] // 修改会员等级对话框 diff --git a/admin/src/views/user/list.vue b/admin/src/views/user/list.vue index 821a17a..71a3e4f 100644 --- a/admin/src/views/user/list.vue +++ b/admin/src/views/user/list.vue @@ -59,7 +59,8 @@ const memberLevelOptions = [ { label: '非会员', value: 0 }, { label: '不限时', value: 1 }, { label: '诚意', value: 2 }, - { label: '家庭版', value: 3 } + { label: '家庭版', value: 3 }, + { label: '限时', value: 4 } ] // 实名认证选项 diff --git a/miniapp/App.vue b/miniapp/App.vue index b5bd500..b4a0d48 100644 --- a/miniapp/App.vue +++ b/miniapp/App.vue @@ -28,6 +28,9 @@ return } + // 获取未读消息数并更新badge + chatStore.fetchAllUnreadCounts() + try { // 连接 SignalR(如果已连接会直接返回) await signalR.connect() @@ -110,7 +113,7 @@ return } - // 不在聊天页面时,增加未读数 + // 不在聊天页面时,增加未读数并更新badge if (message.sessionId) { chatStore.incrementUnreadCount(message.sessionId) } diff --git a/miniapp/api/member.js b/miniapp/api/member.js index 45a5ff9..8e64a46 100644 --- a/miniapp/api/member.js +++ b/miniapp/api/member.js @@ -41,6 +41,17 @@ export async function bindFamily(bindUserId) { return response } +/** + * 通过相亲编号绑定家庭成员 + * + * @param {string} xiangQinNo - 相亲编号 + * @returns {Promise} 绑定结果 + */ +export async function bindFamilyByXiangQinNo(xiangQinNo) { + const response = await post('/member/bindFamilyByXiangQinNo', { xiangQinNo }) + return response +} + /** * 获取家庭成员列表 * @@ -66,6 +77,7 @@ export default { getMemberInfo, purchase, bindFamily, + bindFamilyByXiangQinNo, getFamilyMembers, unbindFamilyMember } diff --git a/miniapp/config/index.js b/miniapp/config/index.js index 6bdbd8d..7794e45 100644 --- a/miniapp/config/index.js +++ b/miniapp/config/index.js @@ -23,7 +23,7 @@ const ENV = { } // 当前环境 - 开发时使用 development,打包时改为 production -const CURRENT_ENV = 'production' +const CURRENT_ENV = 'development' // 导出配置 export const config = { diff --git a/miniapp/pages/message/index.vue b/miniapp/pages/message/index.vue index 6e9b62f..4c270f0 100644 --- a/miniapp/pages/message/index.vue +++ b/miniapp/pages/message/index.vue @@ -67,6 +67,9 @@ 系统消息 + + {{ systemUnreadCount > 99 ? '99+' : systemUnreadCount }} + @@ -161,6 +164,9 @@ getInteractCounts, markInteractAsRead } from '@/api/interact.js' + import { + getUnreadCount as getSystemUnreadCount + } from '@/api/message.js' import { formatTimestamp } from '@/utils/format.js' @@ -181,6 +187,7 @@ // 数据 const sessions = ref([]) + const systemUnreadCount = ref(0) const interactCounts = ref({ viewedMe: 0, favoritedMe: 0, @@ -247,7 +254,10 @@ if (!userStore.isLoggedIn) return try { - const res = await getSessions() + const [res, sysRes] = await Promise.all([ + getSessions(), + getSystemUnreadCount() + ]) console.log('[Message] 加载会话列表:', res) if (res?.success || res?.code === 0) { sessions.value = res.data || [] @@ -258,6 +268,11 @@ }))) chatStore.setSessions(sessions.value) } + // 更新系统消息未读数 + if (sysRes?.code === 0) { + systemUnreadCount.value = sysRes.data?.unreadCount || 0 + chatStore.setSystemUnreadCount(systemUnreadCount.value) + } } catch (error) { console.error('加载会话列表失败:', error) uni.showToast({ @@ -645,6 +660,24 @@ } } + .system-badge { + min-width: 36rpx; + height: 36rpx; + background: #FF3B30; + border-radius: 18rpx; + padding: 0 10rpx; + margin-right: 12rpx; + display: flex; + align-items: center; + justify-content: center; + + .badge-text { + font-size: 20rpx; + color: #fff; + line-height: 1; + } + } + .system-arrow { .arrow-icon { font-size: 32rpx; diff --git a/miniapp/pages/message/system.vue b/miniapp/pages/message/system.vue index c92bef9..8b1153e 100644 --- a/miniapp/pages/message/system.vue +++ b/miniapp/pages/message/system.vue @@ -70,7 +70,8 @@