20250618-添加已读未读,增加去重2.1

This commit is contained in:
luoyu 2025-06-18 13:04:58 +08:00
parent d5282f5587
commit 17d42ffddf
6 changed files with 823 additions and 292 deletions

View File

@ -139,7 +139,7 @@ export function repairRemindListRq(data) {
// 根据会议ID获取消息提醒列表 // 根据会议ID获取消息提醒列表
export function repairRemindListByRepairIdRq(data) { export function repairRemindListByRepairIdRq(data) {
return request({ return request({
url: `/app/repairRemind/listByRepairId`, url: `/app/repairRemind/listByRepairId?repairId=${data.repairId}${data.userId ? '&userId=' + data.userId : ''}`,
method: "get", method: "get",
data data
}); });

View File

@ -6,9 +6,9 @@ App({
// parkId : '26', // 园区id // parkId : '26', // 园区id
// parkName : '长阳智会云控', // 园区名称 // parkName : '长阳智会云控', // 园区名称
// 本地测试 // 本地测试
// DOMAIN_NAME_PREFIX: 'http://192.168.0.58:9227', // DOMAIN_NAME_PREFIX: 'http://192.168.0.17:9227',
// DOMAIN_NAME: 'http://192.168.0.58:9227', //接口域名 // DOMAIN_NAME: 'http://192.168.0.17:9227', //接口域名
// IMG_NAME: 'http://192.168.0.58:9227', // IMG_NAME: 'http://192.168.0.17:9227',
// DOMAIN_NAME_PREFIX: 'http://127.0.0.1:9227', // DOMAIN_NAME_PREFIX: 'http://127.0.0.1:9227',
// DOMAIN_NAME: 'http://127.0.0.1:9227', //接口域名 // DOMAIN_NAME: 'http://127.0.0.1:9227', //接口域名
// IMG_NAME: 'http://127.0.0.1:9227', // IMG_NAME: 'http://127.0.0.1:9227',
@ -32,7 +32,49 @@ App({
onLaunch(res) { onLaunch(res) {
var that = this var that = this
// 初始化通知状态监听器列表
this.notificationStatusListeners = [];
}, },
// 注册通知状态更新监听器
registerNotificationStatusChange(callback) {
if (typeof callback === 'function') {
this.notificationStatusListeners = this.notificationStatusListeners || [];
this.notificationStatusListeners.push(callback);
console.log('注册通知状态更新监听器成功,当前监听器数量:', this.notificationStatusListeners.length);
return true;
}
return false;
},
// 取消注册通知状态更新监听器
unregisterNotificationStatusChange(callback) {
if (!this.notificationStatusListeners || !callback) return false;
const index = this.notificationStatusListeners.indexOf(callback);
if (index > -1) {
this.notificationStatusListeners.splice(index, 1);
console.log('取消注册通知状态更新监听器成功,当前监听器数量:', this.notificationStatusListeners.length);
return true;
}
return false;
},
// 通知所有监听器状态更新
notifyNotificationStatusChange(data) {
if (!this.notificationStatusListeners) return;
console.log('通知所有监听器状态更新:', data);
this.notificationStatusListeners.forEach(callback => {
try {
callback(data);
} catch (err) {
console.error('执行通知状态更新回调出错:', err);
}
});
},
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
//获取当前用户的openid //获取当前用户的openid
Getopenid: function () { Getopenid: function () {

View File

@ -355,18 +355,11 @@ Page({
} }
} }
// 判断是否有选择,至少需要选择一个音控组人员和一个会务服务组人员 // 判断是否有选择人员(允许只选择一种类型的人员)
if (musicSelectedCount < 1) { if (musicSelectedCount < 1 && serviceSelectedCount < 1) {
return Notify({ return Notify({
type: 'danger', type: 'danger',
message: '请至少选择一个音控组人员' message: '请至少选择一个会务人员'
});
}
if (serviceSelectedCount < 1) {
return Notify({
type: 'danger',
message: '请至少选择一个会务服务组人员'
}); });
} }

View File

@ -276,28 +276,23 @@ Page({
}); });
}, },
// 获取数据 /**
* 获取会议列表数据
*/
getDataList() { getDataList() {
// 获取参数
let _this = this; let _this = this;
let {
userData
} = _this.data;
// 确保每次获取数据时使用最新的用户信息 console.log('页面加载完成,获取通知状态');
let currentUserData = wx.getStorageSync('user');
if(currentUserData && (!_this.data.userData || _this.data.userData.roomRole !== currentUserData.roomRole)) {
_this.setData({
userData: currentUserData
});
}
let tabTitle = _this.data.tabTitle if (!userData) return;
let userId = _this.data.userData.id let userId = userData.id;
let isDataAll = null // 请求参数
let pageNum = null let isDataAll = _this.data.reservationIsDataAll
let pageSize = null let pageNum = _this.data.reservationPageNum
// 预约记录参数,目前只保留预约记录,其余去掉 let pageSize = _this.data.reservationPageSize
isDataAll = _this.data.reservationIsDataAll
pageNum = _this.data.reservationPageNum
pageSize = _this.data.reservationPageSize
// 判断数据是否已全部加载 // 判断数据是否已全部加载
if (isDataAll) { if (isDataAll) {
@ -310,127 +305,43 @@ Page({
pageSize pageSize
} }
_this.getReservationData(param) _this.getReservationData(param)
.then(() => {
console.log('所有预约数据加载完成,共', _this.data.reservationDataList.length, '条记录');
// 注意不要在这里调用getStaffNotificationStatus
// 通知状态会在loadStaffInfoForItems函数中处理
})
.catch(err => {
console.error('加载预约数据失败:', err);
});
}, },
// 获取会务人员通知状态 // 获取会务人员通知状态
getStaffNotificationStatus() { getStaffNotificationStatus() {
let _this = this; let _this = this;
console.log('开始获取会务人员通知状态...'); console.log('开始获取会务人员通知状态...');
// 初始化staffNotifications对象 // 获取当前会议列表
let staffNotifications = {}; const meetingItems = _this.data.reservationDataList || [];
// 获取所有待审核和待开始状态的会议ID列表 // 过滤出有会务负责人的会议
const pendingMeetingIds = _this.data.reservationDataList const meetingsWithStaff = meetingItems.filter(item =>
.filter(meeting => meeting.status == 5 || meeting.status == 7) (item.serviceStaff || item.musicStaff) &&
.map(meeting => meeting.id); ((item.serviceIds && item.serviceIds.length > 0) || (item.musicIds && item.musicIds.length > 0)));
console.log('需要获取通知状态的会议数量:', pendingMeetingIds.length);
if (pendingMeetingIds.length === 0) { console.log('需要获取通知状态的会议数量:', meetingsWithStaff.length);
_this.setData({ staffNotifications: {} });
return; if (meetingsWithStaff.length === 0) {
return Promise.resolve();
} }
// 使用Promise.all处理所有会议的通知状态请求 // 为每个有会务人员的会议项查询通知状态
const notificationRequests = pendingMeetingIds.map(meetingId => { const notificationPromises = meetingsWithStaff.map(item => {
// 使用新的API按会议ID查询通知 return this.queryMeetingNotificationStatus(item);
return repairRemindListByRepairIdRq({
repairId: meetingId,
pageNum: 1,
pageSize: 100
}).then(res => {
console.log(`获取会议ID ${meetingId} 的通知状态:`, res);
if (res && res.rows && res.rows.length > 0) {
// 获取该会议的所有通知
const notifications = res.rows;
// 找到当前会议对应的会议项
const meetingItem = _this.data.reservationDataList.find(item => item.id === meetingId);
if (!meetingItem) {
console.error('未找到会议项:', meetingId);
return null;
}
// 处理会务人员状态获取会务人员ID列表
const staffUserIds = _this.processStaffStatus(meetingItem) || [];
// 统计已读人数和总人数
let readCount = 0;
const readUserIds = [];
// 此会议的总会务人员数量 - 使用确定的会务人员数量
const totalStaffCount = staffUserIds.length;
// 如果没有选择会务负责人,则不显示已读/未读信息
if (totalStaffCount === 0) {
staffNotifications[meetingId + '_readCount'] = 0;
staffNotifications[meetingId + '_totalCount'] = 0;
staffNotifications[meetingId + '_readUserIds'] = [];
staffNotifications[meetingId] = false;
return null;
}
// 确保meetingItem.totalStaffCount和计算的totalStaffCount一致
meetingItem.totalStaffCount = totalStaffCount;
notifications.forEach(notification => {
// 只处理会务负责人的通知
if (staffUserIds.includes(notification.userId)) {
// 记录通知ID方便后续标记已读
staffNotifications[meetingId + '_notificationId_' + notification.userId] = notification.id;
// 根据read字段判断是否已读read === 1表示已读
if (notification.read === 1) {
// 添加到已读用户列表
if (!readUserIds.includes(notification.userId)) {
readUserIds.push(notification.userId);
readCount++;
}
}
}
});
// 确保已读数不超过总数
readCount = Math.min(readCount, totalStaffCount);
// 存储通知状态数据
staffNotifications[meetingId + '_readCount'] = readCount;
staffNotifications[meetingId + '_totalCount'] = totalStaffCount;
staffNotifications[meetingId + '_readUserIds'] = readUserIds;
staffNotifications[meetingId] = readCount > 0; // 任一会务人员已读则标记为已读
console.log('会议ID:', meetingId,
'已读会务人员数:', readCount,
'总会务人员数:', totalStaffCount,
'最终已读状态:', readCount > 0);
return {
meetingId,
readCount,
totalCount: totalStaffCount,
hasUnread: readCount < totalStaffCount
};
}
return null;
}).catch(err => {
console.error(`获取会议ID ${meetingId} 的通知状态失败:`, err);
return null;
});
}); });
// 处理所有通知请求 // 等待所有会议通知状态查询完成
Promise.all(notificationRequests).then(() => { return Promise.all(notificationPromises).then(() => {
// 更新通知状态 console.log('所有会议通知状态处理完成');
_this.setData({
staffNotifications: staffNotifications
});
// 更新会议列表中的通知状态
_this.updateMeetingListNotificationStatus();
}); });
}, },
@ -450,65 +361,6 @@ Page({
)); ));
}, },
// 更新会议列表中的通知状态
updateMeetingListNotificationStatus() {
let _this = this;
let reservationDataList = _this.data.reservationDataList;
let staffNotifications = _this.data.staffNotifications;
console.log('开始更新会议列表通知状态,会议列表数量:', reservationDataList.length);
// 计数器
let updatedCount = 0;
// 遍历会议列表,更新通知状态
reservationDataList.forEach((meeting, index) => {
// 为所有待审核和待开始的会议添加通知标记
if (meeting.status == 5 || meeting.status == 7) {
// 获取当前会议的通知状态
let readCount = parseInt(staffNotifications[meeting.id + '_readCount'] || 0);
let totalCount = parseInt(staffNotifications[meeting.id + '_totalCount'] || 0);
const readUserIds = staffNotifications[meeting.id + '_readUserIds'] || [];
// 确保计数逻辑正确
readCount = Math.min(readCount, totalCount);
// 只有在有选择会务负责人的情况下才显示通知状态
const showNotification = totalCount > 0;
// 标记会议是否有未读通知
const isStaffNotificationRead = readCount > 0;
const hasUnreadNotification = totalCount > readCount;
// 更新会议项的通知状态
meeting.hasUnreadNotification = showNotification ? hasUnreadNotification : false;
meeting.isStaffNotificationRead = showNotification ? isStaffNotificationRead : false;
meeting.readCount = readCount;
meeting.totalStaffCount = totalCount;
meeting.readUserIds = readUserIds;
meeting.showNotification = showNotification;
console.log('更新会议通知状态:', meeting.id, {
showNotification: showNotification,
hasUnreadNotification: hasUnreadNotification,
isStaffNotificationRead: isStaffNotificationRead,
readCount: readCount,
totalStaffCount: totalCount
});
updatedCount++;
}
});
// 只有存在更新时才重新渲染列表
if (updatedCount > 0) {
console.log('已更新', updatedCount, '条会议通知状态');
_this.setData({
reservationDataList: reservationDataList
});
}
},
// 获取预约数据 // 获取预约数据
getReservationData(param) { getReservationData(param) {
let _this = this; let _this = this;
@ -527,8 +379,8 @@ Page({
mask: true mask: true
}); });
// 查询数据 // 查询数据并返回Promise
selectReservationListByUserIdRq({ return selectReservationListByUserIdRq({
role: currentRole, // 使用最新的角色 role: currentRole, // 使用最新的角色
pageNum, pageNum,
pageSize, pageSize,
@ -545,45 +397,25 @@ Page({
// 检查是否还有更多数据可加载 // 检查是否还有更多数据可加载
if (_this.data.reservationDataList.length < res.total) { if (_this.data.reservationDataList.length < res.total) {
// 格式化新获取的数据 // 更新数据
let formattedData = _this.formartData(queryDataList); let reservationDataList = _this.data.reservationDataList.concat(_this.formartData(queryDataList));
// 更新参数
let reservationDataList = _this.data.reservationDataList.concat(formattedData);
let reservationPageNum = _this.data.reservationPageNum + 1; let reservationPageNum = _this.data.reservationPageNum + 1;
_this.setData({ _this.setData({
reservationPageNum, reservationPageNum,
reservationDataList, reservationDataList,
}); });
// 获取会务人员通知状态
_this.getStaffNotificationStatus();
// 超过总大小,则加载完成
if (_this.data.reservationDataList.length >= res.total) {
_this.setData({
reservationIsDataAll: true
});
console.log('所有预约数据加载完成,共', res.total, '条记录');
} else {
console.log('已加载', _this.data.reservationDataList.length, '条记录,总共', res.total, '条');
}
} else { } else {
// 所有数据已加载完成
_this.setData({ _this.setData({
reservationIsDataAll: true reservationIsDataAll: true
}); });
console.log('所有预约数据已加载完成');
} }
return res; // 返回结果以便链式调用
}).catch(err => { }).catch(err => {
wx.hideLoading(); wx.hideLoading();
console.error('获取预约列表失败:', err); console.error('获取预约列表数据失败:', err);
throw err; // 抛出错误以便在上层处理
// 显示错误提示
Notify({
type: 'danger',
message: '获取数据失败,请重试'
});
}); });
}, },
@ -747,6 +579,16 @@ Page({
item.readCount = 0; // 默认0人已读 item.readCount = 0; // 默认0人已读
item.totalStaffCount = 0; // 默认总会务人员数量为0后续从通知接口获取 item.totalStaffCount = 0; // 默认总会务人员数量为0后续从通知接口获取
// 音控组和会务组初始化
item.serviceReadCount = 0; // 会务组已读人数
item.musicReadCount = 0; // 音控组已读人数
item.serviceTotalCount = 0; // 会务组总人数
item.musicTotalCount = 0; // 音控组总人数
item.serviceIds = []; // 会务组ID列表
item.musicIds = []; // 音控组ID列表
item.serviceStaff = false; // 是否有会务组
item.musicStaff = false; // 是否有音控组
// 未读通知显示逻辑: // 未读通知显示逻辑:
// 1. 会务负责人按钮上的红点 - 只在status为7且showStaff为true时显示 // 1. 会务负责人按钮上的红点 - 只在status为7且showStaff为true时显示
// 2. 左侧的红条 - 在status为5(待审核)时显示 // 2. 左侧的红条 - 在status为5(待审核)时显示
@ -832,9 +674,12 @@ Page({
console.log('从voiceWaiter和serveWaiter字段构建waiters数组:', item.waiters); console.log('从voiceWaiter和serveWaiter字段构建waiters数组:', item.waiters);
} }
// 重新处理会务负责人状态 // 重新处理会务状态
this.processStaffStatus(item); this.processStaffStatus(item);
// 为单个会议项查询通知状态
this.queryMeetingNotificationStatus(item);
// 触发视图更新 // 触发视图更新
this.setData({ this.setData({
reservationDataList: this.data.reservationDataList reservationDataList: this.data.reservationDataList
@ -845,6 +690,126 @@ Page({
}); });
}, },
// 为单个会议项查询通知状态
queryMeetingNotificationStatus(item) {
if (!item || (!item.serviceIds || !item.musicIds)) {
console.log('会议项缺少必要信息,无法查询通知状态:', item?.id);
return Promise.resolve();
}
console.log('开始查询会议(ID:' + item.id + ')的通知状态');
let _this = this;
const meetingId = item.id;
// 初始化音控组和会务组已读计数
let serviceReadCount = 0;
let musicReadCount = 0;
// 处理音控组通知状态
const processAudioStaffStatus = () => {
if (item.musicIds && item.musicIds.length > 0) {
console.log('开始查询音控组通知状态,音控组成员:', item.musicIds);
const musicPromises = item.musicIds.map(userId => {
return repairRemindListByRepairIdRq({
repairId: meetingId,
userId: userId,
pageNum: 1,
pageSize: 10
}).then(res => {
console.log('诊断: 会议ID ' + meetingId + ' 音控人员ID ' + userId + ' 通知状态:', res);
// 检查是否有通知并且是否已读
if (res && res.rows && res.rows.length > 0) {
const isRead = res.rows.some(notice => notice.read === 1);
if (isRead) {
musicReadCount++;
}
return { userId, isRead };
}
return { userId, isRead: false };
}).catch(err => {
console.error('获取音控人员通知状态失败:', err);
return { userId, isRead: false };
});
});
return Promise.all(musicPromises).then(() => {
// 更新音控组已读数量
item.musicReadCount = musicReadCount;
console.log('会议ID:', meetingId, '音控组:',
'已读人数:', musicReadCount,
'总人数:', item.musicTotalCount);
// 刷新显示
_this.setData({
reservationDataList: _this.data.reservationDataList
});
});
} else {
return Promise.resolve();
}
};
// 处理会务服务组通知状态
const processServiceStaffStatus = () => {
if (item.serviceIds && item.serviceIds.length > 0) {
console.log('开始查询会务组通知状态,会务组成员:', item.serviceIds);
const servicePromises = item.serviceIds.map(userId => {
return repairRemindListByRepairIdRq({
repairId: meetingId,
userId: userId,
pageNum: 1,
pageSize: 10
}).then(res => {
console.log('诊断: 会议ID ' + meetingId + ' 会务人员ID ' + userId + ' 通知状态:', res);
// 检查是否有通知并且是否已读
if (res && res.rows && res.rows.length > 0) {
const isRead = res.rows.some(notice => notice.read === 1);
if (isRead) {
serviceReadCount++;
}
return { userId, isRead };
}
return { userId, isRead: false };
}).catch(err => {
console.error('获取会务人员通知状态失败:', err);
return { userId, isRead: false };
});
});
return Promise.all(servicePromises).then(() => {
// 更新会务服务组已读数量
item.serviceReadCount = serviceReadCount;
console.log('会议ID:', meetingId, '会务服务组:',
'已读人数:', serviceReadCount,
'总人数:', item.serviceTotalCount);
// 刷新显示
_this.setData({
reservationDataList: _this.data.reservationDataList
});
});
} else {
return Promise.resolve();
}
};
// 顺序处理会务服务组和音控组状态
return processServiceStaffStatus()
.then(() => processAudioStaffStatus())
.then(() => {
// 诊断输出会务人员和音控人员的阅读状态
console.log('诊断结果 - 会议ID ' + meetingId + ':');
console.log('音控组已读人数: ' + item.musicReadCount + ' / ' + item.musicTotalCount);
console.log('会务组已读人数: ' + item.serviceReadCount + ' / ' + item.serviceTotalCount);
})
.catch(err => {
console.error('处理通知状态失败:', err);
});
},
// 处理会务人员状态 // 处理会务人员状态
processStaffStatus(item) { processStaffStatus(item) {
try { try {
@ -935,6 +900,24 @@ Page({
// 更新会务人员总数计数 - 使用实际选择的负责人数量,而不是默认值或来自其他地方的计数 // 更新会务人员总数计数 - 使用实际选择的负责人数量,而不是默认值或来自其他地方的计数
item.totalStaffCount = uniqueStaffIds.length; item.totalStaffCount = uniqueStaffIds.length;
// 保存音控组和会务服务组的信息
item.serviceStaff = hasServiceStaffFromServer;
item.musicStaff = hasMusicStaffFromServer;
item.serviceTotalCount = serviceIdsFromServer.length;
item.musicTotalCount = musicIdsFromServer.length;
item.serviceIds = serviceIdsFromServer;
item.musicIds = musicIdsFromServer;
// 初始化已读计数(如果不存在)
if (typeof item.serviceReadCount === 'undefined') {
item.serviceReadCount = 0;
}
if (typeof item.musicReadCount === 'undefined') {
item.musicReadCount = 0;
}
item.showNotification = hasServiceStaffFromServer || hasMusicStaffFromServer;
console.log('服务器返回的会务负责人状态(ID:' + item.id + '):', { console.log('服务器返回的会务负责人状态(ID:' + item.id + '):', {
音控组: hasMusicStaffFromServer, 音控组: hasMusicStaffFromServer,
会务服务组: hasServiceStaffFromServer, 会务服务组: hasServiceStaffFromServer,
@ -949,7 +932,14 @@ Page({
let hasMusicStaff = hasMusicStaffFromServer; let hasMusicStaff = hasMusicStaffFromServer;
let hasServiceStaff = hasServiceStaffFromServer; let hasServiceStaff = hasServiceStaffFromServer;
console.log('最终判断的会务负责人状态(ID:' + item.id + '):', {hasMusicStaff, hasServiceStaff}); console.log('最终判断的会务负责人状态(ID:' + item.id + '):', {
hasMusicStaff,
hasServiceStaff,
musicTotalCount: item.musicTotalCount,
serviceTotalCount: item.serviceTotalCount,
musicReadCount: item.musicReadCount,
serviceReadCount: item.serviceReadCount
});
if (hasMusicStaff && hasServiceStaff) { if (hasMusicStaff && hasServiceStaff) {
// 音控组和会务服务组都有选择 // 音控组和会务服务组都有选择
@ -1009,17 +999,57 @@ Page({
const readCount = readUserIds.length; const readCount = readUserIds.length;
const totalCount = parseInt(staffNotifications[id + '_totalCount'] || 1); const totalCount = parseInt(staffNotifications[id + '_totalCount'] || 1);
// 更新存储的通知状态
staffNotifications[id + '_readCount'] = readCount; staffNotifications[id + '_readCount'] = readCount;
staffNotifications[id + '_readUserIds'] = readUserIds; staffNotifications[id + '_readUserIds'] = readUserIds;
staffNotifications[id] = readCount > 0; staffNotifications[id] = readCount > 0;
// 更新状态 // 查找并更新会议项
_this.setData({ const meetingItem = _this.data.reservationDataList.find(item => item.id === id);
staffNotifications: staffNotifications if (meetingItem) {
meetingItem.readCount = readCount;
meetingItem.isStaffNotificationRead = readCount > 0;
meetingItem.hasUnreadNotification = readCount < totalCount;
meetingItem.readUserIds = readUserIds;
// 更新未读标签文本
meetingItem.notificationText = readCount > 0 ?
`已读(${readCount}/${totalCount})` :
`未读(${readCount}/${totalCount})`;
// 更新状态
_this.setData({
staffNotifications: staffNotifications,
reservationDataList: _this.data.reservationDataList
});
} else {
_this.setData({
staffNotifications: staffNotifications
});
}
// 在本地存储通知状态更新信息,以便其他页面同步
wx.setStorageSync('meeting_notification_updated', {
meetingId: id,
userId: userId,
notificationId: notificationId,
isStaffUser: true,
timestamp: new Date().getTime(),
readCount: readCount,
totalCount: totalCount
}); });
// 刷新会议列表通知状态 // 触发全局通知状态更新
_this.updateMeetingListNotificationStatus(); const app = getApp();
if (app && app.notifyNotificationStatusChange) {
app.notifyNotificationStatusChange({
meetingId: id,
userId: userId,
isStaffUser: true,
readCount: readCount,
totalCount: totalCount
});
}
} }
return Promise.resolve(res); return Promise.resolve(res);
@ -1029,7 +1059,65 @@ Page({
}); });
} else { } else {
console.log('未找到对应的通知ID - 用户ID:', userId, '会议ID:', id); console.log('未找到对应的通知ID - 用户ID:', userId, '会议ID:', id);
return Promise.resolve(null);
// 尝试重新获取该用户的通知状态
return repairRemindListByRepairIdRq({
repairId: id,
userId: userId,
pageNum: 1,
pageSize: 10
}).then(notifyRes => {
if (notifyRes && notifyRes.rows && notifyRes.rows.length > 0) {
const notification = notifyRes.rows[0]; // 取最新一条
staffNotifications[id + '_notificationId_' + userId] = notification.id;
// 如果通知未读,则标记为已读
if (notification.read !== 1) {
return _this.markNotificationAsRead(id, userId); // 递归调用标记为已读
} else {
console.log('通知已经是已读状态,无需再次标记');
// 更新已读状态计数
const meetingItem = _this.data.reservationDataList.find(item => item.id === id);
if (meetingItem) {
let readUserIds = staffNotifications[id + '_readUserIds'] || [];
if (!readUserIds.includes(userId)) {
readUserIds.push(userId);
const readCount = readUserIds.length;
const totalCount = parseInt(staffNotifications[id + '_totalCount'] || meetingItem.totalStaffCount || 1);
// 更新通知状态
staffNotifications[id + '_readCount'] = readCount;
staffNotifications[id + '_readUserIds'] = readUserIds;
staffNotifications[id] = readCount > 0;
// 更新会议项
meetingItem.readCount = readCount;
meetingItem.isStaffNotificationRead = readCount > 0;
meetingItem.hasUnreadNotification = readCount < totalCount;
meetingItem.readUserIds = readUserIds;
meetingItem.notificationText = readCount > 0 ?
`已读(${readCount}/${totalCount})` :
`未读(${readCount}/${totalCount})`;
_this.setData({
staffNotifications: staffNotifications,
reservationDataList: _this.data.reservationDataList
});
}
}
return Promise.resolve(null);
}
} else {
console.log('没有找到该用户的通知');
return Promise.resolve(null);
}
}).catch(err => {
console.error('获取通知状态失败:', err);
return Promise.resolve(null);
});
} }
}, },
@ -1149,6 +1237,9 @@ Page({
meetingItem.readCount = readCount; meetingItem.readCount = readCount;
meetingItem.isStaffNotificationRead = readCount > 0; meetingItem.isStaffNotificationRead = readCount > 0;
meetingItem.hasUnreadNotification = readCount < totalCount; meetingItem.hasUnreadNotification = readCount < totalCount;
meetingItem.notificationText = readCount > 0 ?
`已读(${readCount}/${totalCount})` :
`未读(${readCount}/${totalCount})`;
// 更新数据 // 更新数据
_this.setData({ _this.setData({
@ -1215,25 +1306,57 @@ Page({
// 如果会务人员选择页面提供了会议ID优先处理特定会议的通知状态 // 如果会务人员选择页面提供了会议ID优先处理特定会议的通知状态
if (staffPageUpdated.meetingId) { if (staffPageUpdated.meetingId) {
// 获取会议项数据 // 获取会议详情并更新通知状态
const meetingItem = _this.data.reservationDataList.find( selectReservationByIdRq({
item => item.id === staffPageUpdated.meetingId id: staffPageUpdated.meetingId
); }).then(res => {
console.log('获取会议详情成功:', res);
if (res) {
// 查找对应的会议项
const meetingItem = _this.data.reservationDataList.find(
item => item.id === staffPageUpdated.meetingId
);
if (meetingItem) {
console.log('找到需要更新的会议项:', meetingItem.id, meetingItem.title);
// 更新会议项的会务人员信息
if (res.waiters) {
meetingItem.waiters = res.waiters;
}
if (res.voiceWaiter) {
meetingItem.voiceWaiter = res.voiceWaiter;
}
if (res.serveWaiter) {
meetingItem.serveWaiter = res.serveWaiter;
}
// 重新处理会务人员状态
const staffUserIds = _this.processStaffStatus(meetingItem);
// 对单个会议项查询通知状态
_this.queryMeetingNotificationStatus(meetingItem);
} else {
// 未找到会议项,可能需要重新加载数据
console.log('未找到对应的会议项,重新加载会议列表');
_this.setData({
reservationPageNum: 1,
reservationDataList: [],
reservationIsDataAll: false,
});
_this.getDataList();
}
}
}).catch(err => {
console.error('获取会议详情失败:', err);
});
if (meetingItem) { return;
console.log('找到需要更新的会议项:', meetingItem.id, meetingItem.title);
// 重新获取该会议的会务人员ID列表
const staffUserIds = _this.processStaffStatus(meetingItem);
// 需要重新获取通知状态
_this.getStaffNotificationStatus();
return;
}
} }
// 仅刷新通知状态,不需要重新获取整个列表 // 仅刷新通知状态,不需要重新获取整个列表
_this.getStaffNotificationStatus(); // 不要在这里调用getStaffNotificationStatus会在loadStaffInfoForItems中处理
} else { } else {
// 检查是否有全局通知状态更新 // 检查是否有全局通知状态更新
const notificationUpdated = wx.getStorageSync('meeting_notification_updated'); const notificationUpdated = wx.getStorageSync('meeting_notification_updated');
@ -1243,23 +1366,37 @@ Page({
// 清除标记,避免重复处理 // 清除标记,避免重复处理
wx.removeStorageSync('meeting_notification_updated'); wx.removeStorageSync('meeting_notification_updated');
// 更新通知状态 // 如果有特定会议ID只更新该会议的通知状态
_this.updateNotificationStatus(notificationUpdated); if (notificationUpdated.meetingId) {
const meetingItem = _this.data.reservationDataList.find(
item => item.id === notificationUpdated.meetingId
);
if (meetingItem) {
_this.queryMeetingNotificationStatus(meetingItem);
return;
}
}
// 重新加载数据
_this.setData({
reservationPageNum: 1,
reservationDataList: [],
reservationIsDataAll: false,
});
_this.getDataList();
} else {
// 重新加载数据
_this.setData({
reservationPageNum: 1,
reservationDataList: [],
reservationIsDataAll: false,
});
_this.getDataList();
} }
} }
} else {
// 检查是否有全局通知状态更新
const notificationUpdated = wx.getStorageSync('meeting_notification_updated');
if (notificationUpdated) {
console.log('检测到通知状态有更新:', notificationUpdated);
// 清除标记,避免重复处理
wx.removeStorageSync('meeting_notification_updated');
// 更新通知状态
_this.updateNotificationStatus(notificationUpdated);
}
} }
// 注意不要在这里调用getStaffNotificationStatus会在loadStaffInfoForItems中处理
}, },
// 取消预约一系列方法 // 取消预约一系列方法
cancelConfirm(e) { cancelConfirm(e) {
@ -1553,8 +1690,6 @@ Page({
}, },
/** /**
* 生命周期函数--监听页面隐藏 * 生命周期函数--监听页面隐藏
*/ */

View File

@ -29,16 +29,25 @@
<view class="priceView"> <view class="priceView">
<view class="cancelContent" wx:if="{{item.status == 1 && item.operate && item.operate.length > 0}}">取消原因:{{item.operate[item.operate.length - 1].content}}</view> <view class="cancelContent" wx:if="{{item.status == 1 && item.operate && item.operate.length > 0}}">取消原因:{{item.operate[item.operate.length - 1].content}}</view>
<view class="cancelContent" wx:if="{{item.status == 3 && item.operate && item.operate.length > 0}}">驳回原因:{{item.operate[item.operate.length - 1].content}}</view> <view class="cancelContent" wx:if="{{item.status == 3 && item.operate && item.operate.length > 0}}">驳回原因:{{item.operate[item.operate.length - 1].content}}</view>
<view class="staff-tip" wx:if="{{item.showStaff && item.staffTip}}">{{item.staffTip}}</view>
<view class="staff-read-status-container" wx:if="{{item.showNotification && item.totalStaffCount > 0}}">
<view class="staff-read-status {{item.readCount > 0 ? 'read-tag' : 'unread-tag'}}">
{{item.readCount > 0 ? '已读' : '未读'}}
({{item.readCount}}/{{item.totalStaffCount}})
</view>
</view>
</view> </view>
<!-- 会务人员选择提示 -->
<view class="staff-simple-tip" wx:if="{{item.showStaff && item.staffTip}}">{{item.staffTip}}</view>
<view class="btnView"> <view class="btnView">
<view class="action-buttons"> <view class="action-buttons">
<!-- 会务人员通知状态-左侧竖排 -->
<view class="vertical-notification-container" wx:if="{{item.showNotification}}">
<!-- 会务服务组通知状态 -->
<view wx:if="{{item.serviceStaff}}" class="vertical-notification-status {{item.serviceReadCount > 0 ? 'read' : 'unread'}}">
<text class="status-text">会务({{item.serviceReadCount}}/{{item.serviceTotalCount}})</text>
</view>
<!-- 音控组通知状态 -->
<view wx:if="{{item.musicStaff}}" class="vertical-notification-status {{item.musicReadCount > 0 ? 'read' : 'unread'}}">
<text class="status-text">音控({{item.musicReadCount}}/{{item.musicTotalCount}})</text>
</view>
</view>
<van-button class="action-btn" size="small" plain type="warning" wx:if="{{item.showCancel}}" bind:tap="cancelConfirm" data-id="{{item.id}}" data-status="{{item.status}}">取消预约</van-button> <van-button class="action-btn" size="small" plain type="warning" wx:if="{{item.showCancel}}" bind:tap="cancelConfirm" data-id="{{item.id}}" data-status="{{item.status}}">取消预约</van-button>
<van-button class="action-btn" size="small" plain type="info" wx:if="{{item.showEdit}}" bind:tap="editConfirm" data-id="{{item.id}}">修改信息</van-button> <van-button class="action-btn" size="small" plain type="info" wx:if="{{item.showEdit}}" bind:tap="editConfirm" data-id="{{item.id}}">修改信息</van-button>
<view class="staff-btn-container" wx:if="{{item.showStaff}}"> <view class="staff-btn-container" wx:if="{{item.showStaff}}">
@ -54,7 +63,6 @@
<view class="loadAllLine" wx:if="{{reservationIsDataAll}}"> <view class="loadAllLine" wx:if="{{reservationIsDataAll}}">
<van-divider class="van-divider" customStyle="font-size: 26rpx;" contentPosition="center">数据已全部加载</van-divider> <van-divider class="van-divider" customStyle="font-size: 26rpx;" contentPosition="center">数据已全部加载</van-divider>
</view> </view>
</view> </view>
<!-- 提示框 --> <!-- 提示框 -->
<van-dialog id="van-dialog" /> <van-dialog id="van-dialog" />

View File

@ -69,6 +69,13 @@
justify-content: flex-start; justify-content: flex-start;
align-items: center; align-items: center;
background: #f2f2f2; background: #f2f2f2;
position: relative;
}
.itemView .contentView .img-container {
position: relative;
width: 200rpx;
height: 110rpx;
} }
.itemView .contentView .img { .itemView .contentView .img {
@ -112,7 +119,13 @@
text-overflow: ellipsis; text-overflow: ellipsis;
overflow: hidden; overflow: hidden;
word-break: break-all; word-break: break-all;
white-space: nowrap; white-space: normal;
box-sizing: border-box;
padding: 10rpx;
background-color: #f9f9f9;
border-radius: 8rpx;
line-height: 1.4;
min-height: 52rpx;
} }
.itemView .priceView .priceContent { .itemView .priceView .priceContent {
@ -137,7 +150,9 @@
flex-direction: column; flex-direction: column;
align-items: flex-end; align-items: flex-end;
padding-top: 10rpx; padding-top: 10rpx;
padding-bottom: 10rpx;
border-top: 1rpx solid rgba(0, 0, 0, 0.05); border-top: 1rpx solid rgba(0, 0, 0, 0.05);
min-height: 90rpx;
} }
.itemView .btnView .btn { .itemView .btnView .btn {
@ -164,14 +179,6 @@
margin-top: 80rpx; margin-top: 80rpx;
} }
.staff-tip {
color: #ff4d4f;
font-size: 28rpx;
margin: 10rpx 0;
text-align: right;
font-weight: bold;
}
/* 通过按钮绿色样式 */ /* 通过按钮绿色样式 */
.approve-btn-success { .approve-btn-success {
color: #000000 !important; color: #000000 !important;
@ -225,6 +232,7 @@
justify-content: flex-end; justify-content: flex-end;
margin-top: 16rpx; margin-top: 16rpx;
width: 100%; width: 100%;
position: relative;
} }
/* 会务服务人员阅读状态容器 */ /* 会务服务人员阅读状态容器 */
@ -248,8 +256,6 @@
vertical-align: middle; vertical-align: middle;
text-align: center; text-align: center;
box-shadow: 0 1rpx 2rpx rgba(0, 0, 0, 0.1); box-shadow: 0 1rpx 2rpx rgba(0, 0, 0, 0.1);
position: relative;
overflow: visible;
} }
/* 已读状态 */ /* 已读状态 */
@ -285,16 +291,363 @@
font-weight: 600; font-weight: 600;
} }
/* 添加左侧通知标签的样式 */
.notification-inline {
position: absolute;
left: 0;
bottom: 12rpx;
z-index: 10;
}
/* 添加/优化会务服务人员阅读状态 */
.notification-inline .staff-read-status {
border-radius: 0 8rpx 8rpx 0;
padding: 4rpx 12rpx;
font-size: 24rpx;
white-space: nowrap;
box-shadow: 0 2rpx 6rpx rgba(0, 0, 0, 0.15);
font-weight: bold;
display: flex;
align-items: center;
transform: translateX(-2rpx);
}
/* 状态图标样式 */
.status-icon {
font-weight: bold;
margin-right: 5rpx;
font-size: 22rpx;
}
/* 已读标签 - 绿色 */ /* 已读标签 - 绿色 */
.read-tag { .read-tag {
color: #07c160; background-color: #f6ffed;
background-color: rgba(7, 193, 96, 0.1); color: #52c41a;
border: 1rpx solid rgba(7, 193, 96, 0.2); border: 1px solid #b7eb8f;
} }
/* 未读标签 - 红色 */ /* 未读标签 - 红色 */
.unread-tag { .unread-tag {
color: #ee0a24; background-color: #fff0f0;
background-color: rgba(238, 10, 36, 0.1); color: #ff4d4f;
border: 1rpx solid rgba(238, 10, 36, 0.2); border: 1px solid #ffccc7;
}
/* 已读/未读标签的统一样式 */
.staff-read-status {
display: inline-block;
padding: 6rpx 14rpx;
border-radius: 8rpx;
font-size: 24rpx;
margin-right: 0;
min-height: 32rpx;
line-height: 32rpx;
text-align: center;
}
/* 添加通知容器样式 */
.notification-container {
display: flex;
flex-direction: column;
align-items: flex-start;
margin-bottom: 12rpx;
width: 100%;
}
.notification-container .staff-read-status {
margin-bottom: 8rpx;
border-radius: 8rpx;
padding: 8rpx 16rpx;
font-size: 24rpx;
min-height: 32rpx;
line-height: 32rpx;
text-align: left;
display: flex;
align-items: center;
white-space: nowrap;
box-shadow: 0 2rpx 6rpx rgba(0, 0, 0, 0.1);
width: auto;
min-width: 180rpx;
}
.notification-container .staff-read-status:last-child {
margin-bottom: 0;
}
/* 已读/未读标签的统一样式 */
.staff-read-status {
display: inline-block;
padding: 6rpx 14rpx;
border-radius: 8rpx;
font-size: 24rpx;
margin-right: 0;
min-height: 32rpx;
line-height: 32rpx;
text-align: center;
}
/* 已读标签 - 绿色 */
.read-tag {
background-color: #f6ffed;
color: #52c41a;
border: 1px solid #b7eb8f;
}
/* 未读标签 - 红色 */
.unread-tag {
background-color: #fff0f0;
color: #ff4d4f;
border: 1px solid #ffccc7;
}
/* 状态图标样式 */
.status-icon {
font-weight: bold;
margin-right: 5rpx;
font-size: 22rpx;
}
.status-text {
font-size: 24rpx;
}
/* 会务人员通知状态容器新样式 */
.read-status-wrapper {
padding: 0 20rpx;
margin-bottom: 15rpx;
display: flex;
justify-content: flex-end;
}
/* 已读未读通知状态样式 */
.notification-status-container {
display: flex;
flex-direction: row;
gap: 10rpx;
justify-content: flex-end;
}
.notification-status {
display: flex;
align-items: center;
padding: 5rpx 15rpx;
border-radius: 8rpx;
font-size: 24rpx;
width: fit-content;
}
.notification-status.read {
background-color: rgba(76, 175, 80, 0.1);
color: #4CAF50;
border: 1px solid #4CAF50;
}
.notification-status.unread {
background-color: rgba(244, 67, 54, 0.1);
color: #F44336;
border: 1px solid #F44336;
}
.status-icon {
font-weight: bold;
margin-right: 5rpx;
font-size: 22rpx;
}
.status-text {
font-size: 24rpx;
}
/* 未读通知的项目样式 */
.unread-item {
border-left: 5px solid #F44336;
}
/* 待审核状态的项目样式 */
.pre-checked-item {
border-left: 5px solid #FFB119;
}
/* 记录项目样式 */
.record-item {
background-color: #fff;
border-radius: 10rpx;
margin: 20rpx;
padding: 20rpx;
box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.1);
position: relative;
}
.record-title {
font-size: 32rpx;
font-weight: bold;
margin-bottom: 15rpx;
color: #333;
}
.meeting-room-info {
display: flex;
margin-bottom: 15rpx;
}
.meeting-room-img {
width: 160rpx;
height: 120rpx;
border-radius: 8rpx;
margin-right: 15rpx;
}
.meeting-room-text {
flex: 1;
font-size: 28rpx;
color: #666;
}
.detail-info {
font-size: 24rpx;
color: #999;
margin-top: 5rpx;
}
.record-date {
font-size: 28rpx;
color: #666;
margin: 10rpx 0;
}
.special-date {
color: #1989fa;
font-weight: bold;
}
.record-status {
font-size: 28rpx;
margin: 10rpx 0;
}
.record-action {
display: flex;
justify-content: flex-end;
flex-wrap: wrap;
gap: 15rpx;
margin-top: 15rpx;
}
.record-action-btn {
padding: 10rpx 20rpx;
font-size: 24rpx;
border-radius: 8rpx;
text-align: center;
position: relative;
}
.action-cancel {
color: #ff9800;
border: 1px solid #ff9800;
background-color: rgba(255, 152, 0, 0.05);
}
.action-edit {
color: #2196F3;
border: 1px solid #2196F3;
background-color: rgba(33, 150, 243, 0.05);
}
.action-reject {
color: #F44336;
border: 1px solid #F44336;
background-color: rgba(244, 67, 54, 0.05);
}
.action-pass {
color: #4CAF50;
border: 1px solid #4CAF50;
background-color: rgba(76, 175, 80, 0.05);
}
/* 会务人员选择警告样式 */
.staff-warning-container {
width: 100%;
padding: 16rpx 10rpx;
margin-bottom: 16rpx;
border: 1px solid #f56c6c;
background-color: #fff3f3;
border-radius: 8rpx;
display: flex;
justify-content: center;
align-items: center;
}
.staff-warning-text {
color: #f56c6c;
font-size: 28rpx;
text-align: center;
font-weight: 500;
}
/* 左侧竖排通知状态容器 */
.vertical-notification-container {
position: absolute;
left: 0;
top: 50%;
transform: translateY(-50%);
display: flex;
flex-direction: column;
gap: 16rpx;
z-index: 10;
}
/* 调整通知状态标签样式 */
.vertical-notification-status {
display: flex;
align-items: center;
padding: 6rpx 15rpx;
border-radius: 0 8rpx 8rpx 0;
font-size: 22rpx;
width: fit-content;
box-shadow: 0 2rpx 6rpx rgba(0, 0, 0, 0.15);
min-height: 36rpx;
line-height: 36rpx;
}
.vertical-notification-status.read {
background-color: rgba(76, 175, 80, 0.1);
color: #4CAF50;
border: 1px solid #4CAF50;
}
.vertical-notification-status.unread {
background-color: rgba(244, 67, 54, 0.1);
color: #F44336;
border: 1px solid #F44336;
}
.status-icon {
font-weight: bold;
margin-right: 5rpx;
font-size: 22rpx;
}
.status-text {
font-size: 24rpx;
}
/* 会务人员选择警告样式 - 简单红色文字版本 */
.staff-simple-tip {
width: 100%;
text-align: right;
color: #f56c6c;
font-size: 28rpx;
padding: 10rpx 20rpx;
margin-bottom: 10rpx;
font-weight: 700;
}
/* 添加✓和!图标的特定样式 */
.status-check {
color: #4CAF50;
}
.status-alert {
color: #F44336;
} }