2025-06-17 23:30:12 +08:00

1651 lines
50 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

const app = getApp()
import Dialog from '@vant/weapp/dialog/dialog';
import Notify from '@vant/weapp/notify/notify';
import {
selfFormatTimeYMD,
selfFormatTimeHM,
getWeekday,
getNowDate
} from "../../../../utils/util.js"
import {
selectReservationListByUserIdRq,
selectVisitorInvitationRecordRq,
cancelOrderRq,
approveOrderRq,
approveOrderDel,
selectReservationByIdRq,
getStaff
} from "../../../../api/meeting/meetingRoom.js"
// 引入消息通知相关API
import {
repairRemindListRq,
repairRemindListByRepairIdRq,
repairRemindReadRq
} from "../../../../api/repair/repair.js"
Page({
/**
* 页面的初始数据
*/
data: {
IMG_NAME: app.IMG_NAME,
userData: null,
dataChange: false,
tabTitle: '预约记录',
// 预约记录参数
reservationPageNum: 1,
reservationPageSize: 10,
reservationDataList: [],
reservationIsDataAll: false,
// 会务人员通知状态
staffNotifications: {},
search: {
title: {
text: '会议名称',
value: ''
},
status: {
text: '',
value: 5,
option: [{
text: '全部预约',
value: ''
},
{
text: '待审核',
value: 5
},
{
text: '待开始',
value: 7
},
{
text: '已结束',
value: 11
},
{
text: '已取消',
value: 1
},
{
text: '已驳回',
value: 3
}, {
text: '占用',
value: 4
}, {
text: '进行中',
value: 9
},
]
},
sort: {
value: 'start',
option: [{
text: '排序方式',
value: ''
},
{
text: '会议开始时间',
value: 'start'
},
{
text: '创建时间',
value: 'create'
},
]
}
},
showRejectReason: false, // 是否展示弹出层
rejectlId: '', // 驳回预约会议id
rejectReason: '', // 驳回预约原因
beforeReject(action) {
return new Promise(resolve => {
if (action === 'confirm') {
resolve(false)
} else {
resolve(true)
}
});
}, // 弹出层点击确认不关闭,手动关
// 会议重新预约需要参数
editId: '',
showEdit: false,
editAction: [{
name: '重新选择时间、会议室',
type: 1
},
{
name: '重新编辑会议信息',
type: 2
},
],
timeShow: false,
currentDate: new Date().getTime(),
minDate: new Date().getTime(),
maxDate: '',
formatter(type, value) {
if (type === 'year') {
return `${value}`;
}
if (type === 'month') {
return `${value}`;
}
if (type === 'day') {
return `${value}`;
}
return value;
},
// 参与记录参数,不需要
// participatePageNum: 1,
// participatePageSize: 10,
// participateDataList: [],
// participateIsDataAll: false,
},
changeSearchTitle(e) {
this.setData({
['search.title.value']: e.detail,
})
},
searchTitle() {
// 刷新预约数据
this.setData({
reservationPageNum: 1,
reservationDataList: [],
reservationIsDataAll: false,
})
this.getDataList()
this.selectComponent('#item').toggle()
},
changeSearchStatus(e) {
// 刷新预约数据
this.setData({
reservationPageNum: 1,
reservationDataList: [],
reservationIsDataAll: false,
['search.status.value']: e.detail
})
// 更新状态文本
const statusOption = this.data.search.status.option;
const selectedOption = statusOption.find(option => option.value === e.detail);
if (selectedOption) {
this.setData({
['search.status.text']: selectedOption.text
});
}
this.getDataList()
},
changeSearchSort(e) {
// 刷新预约数据
this.setData({
reservationPageNum: 1,
reservationDataList: [],
reservationIsDataAll: false,
['search.sort.value']: e.detail
})
// 更新排序文本
const sortOption = this.data.search.sort.option;
const selectedOption = sortOption.find(option => option.value === e.detail);
if (selectedOption) {
this.setData({
['search.sort.text']: selectedOption.text
});
}
this.getDataList()
},
/**
* 生命周期函数--监听页面加载
*/
onLoad(options) {
// 这里opt接收options以处理查看更多
if (options.act == 'show') {
wx.setNavigationBarTitle({
title: '预约记录',
})
this.setData({
'search.status.value': ''
})
}
// 检查是否有URL参数指定状态
if (options && options.status) {
this.setData({
'search.status.value': parseInt(options.status) || 7
});
// 初始化状态文本
const statusOption = this.data.search.status.option;
const selectedOption = statusOption.find(option => option.value === this.data.search.status.value);
if (selectedOption) {
this.setData({
'search.status.text': selectedOption.text
});
}
}
let _this = this;
let userDetail = wx.getStorageSync('user')
_this.setData({
userData: userDetail
})
// 获取两周后时间,默认只能选两周之后,管理员可以选一年后的
const today = new Date()
const newDate = new Date(today)
if (userDetail.roomRole == 5) {
newDate.setFullYear(newDate.getFullYear() + 1)
} else {
newDate.setDate(newDate.getDate() + 14)
}
_this.setData({
maxDate: newDate.getTime()
})
// 注册全局通知状态更新监听器
const app = getApp();
if (app && app.registerNotificationStatusChange) {
this.notificationStatusChangeCallback = (data) => {
console.log('approve页面收到全局通知状态更新:', data);
// 如果是会务人员(音控或服务人员)的通知,则更新状态
if (data && data.meetingId && data.isStaffUser) {
_this.updateNotificationStatus(data);
}
};
app.registerNotificationStatusChange(this.notificationStatusChangeCallback);
console.log('已注册全局通知状态更新监听器');
}
// 获取数据
_this.getDataList()
// 页面加载完成后获取通知状态
wx.nextTick(() => {
console.log('页面加载完成,获取通知状态');
_this.getStaffNotificationStatus();
});
},
// 获取数据
getDataList() {
// 获取参数
let _this = this;
// 确保每次获取数据时使用最新的用户信息
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
let userId = _this.data.userData.id
let isDataAll = null
let pageNum = null
let pageSize = null
// 预约记录参数,目前只保留预约记录,其余去掉
isDataAll = _this.data.reservationIsDataAll
pageNum = _this.data.reservationPageNum
pageSize = _this.data.reservationPageSize
// 判断数据是否已全部加载
if (isDataAll) {
return;
}
// 传递参数
let param = {
userId,
pageNum,
pageSize
}
_this.getReservationData(param)
},
// 获取会务人员通知状态
getStaffNotificationStatus() {
let _this = this;
console.log('开始获取会务人员通知状态...');
// 初始化staffNotifications对象
let staffNotifications = {};
// 获取所有待审核和待开始状态的会议ID列表
const pendingMeetingIds = _this.data.reservationDataList
.filter(meeting => meeting.status == 5 || meeting.status == 7)
.map(meeting => meeting.id);
console.log('需要获取通知状态的会议数量:', pendingMeetingIds.length);
if (pendingMeetingIds.length === 0) {
_this.setData({ staffNotifications: {} });
return;
}
// 使用Promise.all处理所有会议的通知状态请求
const notificationRequests = pendingMeetingIds.map(meetingId => {
// 使用新的API按会议ID查询通知
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(() => {
// 更新通知状态
_this.setData({
staffNotifications: staffNotifications
});
// 更新会议列表中的通知状态
_this.updateMeetingListNotificationStatus();
});
},
// 判断是否为会议相关通知
isMeetingNotification(content) {
if (!content) return false;
return content.includes('会议预约') ||
content.includes('会务负责人') ||
(content.includes('您收到会议预约') && content.includes('待审核')) ||
(content.includes('会议预约') && content.includes('已取消')) ||
(content.includes('您的会议预约') && (
content.includes('被驳回') ||
content.includes('已被管理员修改') ||
content.includes('已审核通过') ||
content.includes('即将开始')
));
},
// 更新会议列表中的通知状态
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) {
let _this = this;
let {
pageNum,
pageSize,
userId
} = param
// 确保使用最新的用户角色
let currentUserData = wx.getStorageSync('user');
let currentRole = currentUserData ? currentUserData.roomRole : _this.data.userData.roomRole;
wx.showLoading({
title: '加载中...',
mask: true
});
// 查询数据
selectReservationListByUserIdRq({
role: currentRole, // 使用最新的角色
pageNum,
pageSize,
userId: _this.data.userData.id, // 确保传递用户ID
title: _this.data.search.title.value,
status: _this.data.search.status.value === '' ? null : _this.data.search.status.value,
sort: _this.data.search.sort.value, // 排序
}).then(res => {
wx.hideLoading();
console.log('获取预约列表数据:', res);
// 判断数据是否全部查询
let queryDataList = res.rows || [];
// 检查是否还有更多数据可加载
if (_this.data.reservationDataList.length < res.total) {
// 格式化新获取的数据
let formattedData = _this.formartData(queryDataList);
// 更新参数
let reservationDataList = _this.data.reservationDataList.concat(formattedData);
let reservationPageNum = _this.data.reservationPageNum + 1;
_this.setData({
reservationPageNum,
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 {
_this.setData({
reservationIsDataAll: true
});
console.log('所有预约数据已加载完成');
}
}).catch(err => {
wx.hideLoading();
console.error('获取预约列表失败:', err);
// 显示错误提示
Notify({
type: 'danger',
message: '获取数据失败,请重试'
});
});
},
// 获取参与数据,此处不需要
getParticipateData(param) {
let _this = this;
let {
pageNum,
pageSize,
userId
} = param
// 查询数据
selectVisitorInvitationRecordRq({
pageNum,
pageSize,
userId
}).then(res => {
console.log('selectVisitorInvitationRecordRq', res);
// 判断数据是否全部查询
let queryDataList = res.page.records;
if (queryDataList && queryDataList.length > 0) {
// 更新参数
let participateDataList = _this.data.participateDataList.concat(_this.formartData(queryDataList));
let participatePageNum = _this.data.participatePageNum + 1;
_this.setData({
participatePageNum,
participateDataList,
})
} else {
_this.setData({
participateIsDataAll: true
})
}
})
},
// 格式化数据
formartData(queryDataList) {
// 格式化数据
let _this = this;
let userRole = _this.data.userData.roomRole; // 获取用户角色
// 获取当前日期、第二天日期和第三天日期
let nowDate = new Date();
let secondDate = new Date();
secondDate.setDate(nowDate.getDate() + 1);
let thirdDate = new Date();
thirdDate.setDate(nowDate.getDate() + 2);
// 格式化当前日期、第二天日期和第三天日期为YYYY-MM-DD格式
let nowDateStr = selfFormatTimeYMD(nowDate);
let secondDateStr = selfFormatTimeYMD(secondDate);
let thirdDateStr = selfFormatTimeYMD(thirdDate);
console.log('格式化数据,记录数量:', queryDataList.length);
// 首先进行基本格式化
let formattedData = queryDataList.map(item => {
// 会议开始日期
let meetingDateStr = selfFormatTimeYMD(item.start);
// 判断是哪一天
item.isToday = meetingDateStr === nowDateStr;
item.isSecondDay = meetingDateStr === secondDateStr;
item.isThirdDay = meetingDateStr === thirdDateStr;
item.isNowDay = item.isToday; // 保持兼容性
// 添加星期几属性,但不再用于颜色判断
item.weekDay = getWeekday(item.start);
// 完全移除基于星期几的颜色逻辑
// 确保不保留任何可能影响颜色的旧数据
if(item.dateColor) {
delete item.dateColor;
}
item.timeSlot = selfFormatTimeYMD(item.start) + ' '+ getWeekday(item.start) +' ' + selfFormatTimeHM(item.start) + '~' + selfFormatTimeHM(item.end);
// 状态字体颜色
let statusColor = "#FFB119";
// 按钮是否显示
let statusValue = item.status;
let showCancel = false // 显示取消操作
let showEdit = false // 显示编辑操作
let showStaff = false // 显示会务人员
let showApprove = false // 显示审批操作
let statusName = ''
// 预约状态1 取消 3 驳回 4 占用 5 待审核 7 审核通过,待开始 9 进行中 11已结束
if (statusValue == 1) {
// 取消
// 状态字体颜色
statusColor = "#333333"
statusName = '已取消'
}
if (statusValue == 3) {
// 驳回,可以修改
statusColor = "#333333"
statusName = '已驳回'
}
if (statusValue == 4) {
// 占用,仅管理员可以修改
statusName = '已占用'
if (userRole == 5) { // 只有管理员可以编辑和取消占用
showEdit = true
showCancel = true
}
}
if (statusValue == 5) {
// 待审核,管理员可以审批
statusName = '待审核'
if (userRole == 5) { // 只有管理员可以编辑和审批
showEdit = true
showApprove = true
}
}
if (statusValue == 7) {
// 审核通过,管理员可修改
statusName = '待开始'
if (userRole == 5) { // 只有管理员可以取消、编辑和分配会务人员
showCancel = true
showEdit = true
showStaff = true
// 根据会务负责人选择状态设置按钮颜色和提示
// 预先进行一次状态判断,稍后将异步获取详细信息
this.processStaffStatus(item);
}
}
if (statusValue == 9) {
// 进行中
statusName = '进行中'
}
if (statusValue == 11) {
// 已结束
statusColor = "#333333"
statusName = '已结束'
}
// 赋值
item.showCancel = showCancel
item.showEdit = showEdit
item.showApprove = showApprove
item.showStaff = showStaff
item.statusName = statusName
// 状态字体颜色
item.statusColor = statusColor;
// 图片
if (item.imgs) {
try {
item.indoorPicUrlFirst = item.imgs[0].url
} catch (error) {
console.log(`JSON error : ${error}`);
}
}
// 初始化会务通知状态
item.isStaffNotificationRead = false; // 默认未读
// 初始化已读计数
item.readCount = 0; // 默认0人已读
item.totalStaffCount = 0; // 默认总会务人员数量为0后续从通知接口获取
// 未读通知显示逻辑:
// 1. 会务负责人按钮上的红点 - 只在status为7且showStaff为true时显示
// 2. 左侧的红条 - 在status为5(待审核)时显示
// 3. 状态文字 - 在status为5或7时显示
item.hasUnreadNotification = (item.status == 5 || item.status == 7); // 如果是待审核或待开始状态,默认显示未读标记
for (let key in item) {
// null设置为空
if (item[key] == null) {
item[key] = ''
}
}
return item
});
// 异步加载所有"待开始"状态的预约记录的会务人员信息
this.loadStaffInfoForItems(formattedData);
return formattedData;
},
// 为所有待开始状态的预约记录加载会务人员信息
loadStaffInfoForItems(items) {
if (!items || items.length === 0) return;
// 过滤出所有"待开始"状态的记录
const pendingItems = items.filter(item => item.status == 7);
console.log('需要获取会务人员信息的记录数:', pendingItems.length);
if (pendingItems.length === 0) return;
// 为每个待开始的预约记录异步获取会务人员信息
pendingItems.forEach(item => {
selectReservationByIdRq({
id: item.id
}).then(res => {
console.log('获取预约详情(ID:' + item.id + '):', res);
// 1. 检查waiters数组格式
if (res && res.waiters && Array.isArray(res.waiters)) {
item.waiters = res.waiters;
console.log('使用waiters数组格式数据');
}
// 2. 检查voiceWaiter和serveWaiter字段
else if (res) {
// 创建一个模拟的waiters数组
item.waiters = [];
// 处理音控组数据 - voiceWaiter
if (res.voiceWaiter) {
const voiceIds = typeof res.voiceWaiter === 'string'
? res.voiceWaiter.split(',').filter(id => id)
: (Array.isArray(res.voiceWaiter) ? res.voiceWaiter : []);
voiceIds.forEach(id => {
item.waiters.push({
userId: id,
type: '1' // 音控组类型为1
});
});
// 同步数据到会议项中
item.voiceWaiter = res.voiceWaiter;
}
// 处理会务服务组数据 - serveWaiter
if (res.serveWaiter) {
const serveIds = typeof res.serveWaiter === 'string'
? res.serveWaiter.split(',').filter(id => id)
: (Array.isArray(res.serveWaiter) ? res.serveWaiter : []);
serveIds.forEach(id => {
item.waiters.push({
userId: id,
type: '3' // 会务服务组类型为3
});
});
// 同步数据到会议项中
item.serveWaiter = res.serveWaiter;
}
console.log('从voiceWaiter和serveWaiter字段构建waiters数组:', item.waiters);
}
// 重新处理会务负责人状态
this.processStaffStatus(item);
// 触发视图更新
this.setData({
reservationDataList: this.data.reservationDataList
});
}).catch(err => {
console.error('获取预约详情失败(ID:' + item.id + '):', err);
});
});
},
// 处理会务人员状态
processStaffStatus(item) {
try {
console.log('处理会务负责人状态:', item.id, item.title);
// 初始化音控组和会务服务组状态
let hasMusicStaffFromServer = false;
let hasServiceStaffFromServer = false;
let musicIdsFromServer = [];
let serviceIdsFromServer = [];
let staffIds = []; // 存储所有会务负责人的ID
// 处理从服务器获取的会务负责人数据
if (item.waiters) {
// 如果waiters是数组形式
if (Array.isArray(item.waiters)) {
console.log('处理数组形式的waiters数据');
// 分别检查服务器返回的数据中是否有音控组和会务服务组的人员
for (let i = 0; i < item.waiters.length; i++) {
// 音控组
if (item.waiters[i].type === '1' || item.waiters[i].type === 1) {
hasMusicStaffFromServer = true;
const userId = item.waiters[i].userId;
musicIdsFromServer.push(userId);
staffIds.push(userId);
}
// 会务服务组
else if (item.waiters[i].type === '3' || item.waiters[i].type === 3) {
hasServiceStaffFromServer = true;
const userId = item.waiters[i].userId;
serviceIdsFromServer.push(userId);
staffIds.push(userId);
}
}
}
// 如果waiters是字符串形式(后台可能直接返回字符串ID)
else if (typeof item.waiters === 'string') {
console.log('处理字符串形式的waiters数据');
const waiterIds = item.waiters.split(',').filter(id => id);
if (waiterIds.length > 0) {
hasServiceStaffFromServer = true;
waiterIds.forEach(id => {
serviceIdsFromServer.push(id);
staffIds.push(id);
});
}
}
}
// 处理单独的音控组和会务服务组字段
if (item.voiceWaiter) {
console.log('处理voiceWaiter字段');
const voiceIds = typeof item.voiceWaiter === 'string'
? item.voiceWaiter.split(',').filter(id => id)
: (Array.isArray(item.voiceWaiter) ? item.voiceWaiter : []);
if (voiceIds.length > 0) {
hasMusicStaffFromServer = true;
voiceIds.forEach(id => {
if (!musicIdsFromServer.includes(id)) {
musicIdsFromServer.push(id);
staffIds.push(id);
}
});
}
}
if (item.serveWaiter) {
console.log('处理serveWaiter字段');
const serveIds = typeof item.serveWaiter === 'string'
? item.serveWaiter.split(',').filter(id => id)
: (Array.isArray(item.serveWaiter) ? item.serveWaiter : []);
if (serveIds.length > 0) {
hasServiceStaffFromServer = true;
serveIds.forEach(id => {
if (!serviceIdsFromServer.includes(id)) {
serviceIdsFromServer.push(id);
staffIds.push(id);
}
});
}
}
// 去重获取实际会务人员ID列表
const uniqueStaffIds = [...new Set(staffIds)];
// 更新会务人员总数计数 - 使用实际选择的负责人数量,而不是默认值或来自其他地方的计数
item.totalStaffCount = uniqueStaffIds.length;
console.log('服务器返回的会务负责人状态(ID:' + item.id + '):', {
音控组: hasMusicStaffFromServer,
会务服务组: hasServiceStaffFromServer,
音控组IDs: musicIdsFromServer,
会务服务组IDs: serviceIdsFromServer,
音控组人数: musicIdsFromServer.length,
会务服务组人数: serviceIdsFromServer.length,
会务人员总数: item.totalStaffCount,
实际负责人IDs: uniqueStaffIds
});
let hasMusicStaff = hasMusicStaffFromServer;
let hasServiceStaff = hasServiceStaffFromServer;
console.log('最终判断的会务负责人状态(ID:' + item.id + '):', {hasMusicStaff, hasServiceStaff});
if (hasMusicStaff && hasServiceStaff) {
// 音控组和会务服务组都有选择
item.staffBtnType = ''; // 绿色(无类型)
item.staffTip = '';
item.isStaffComplete = true;
} else if (!hasMusicStaff && !hasServiceStaff) {
// 音控组和会务服务组都没有选择
item.staffBtnType = 'danger'; // 红色
item.staffTip = '请选择音控组和会务服务组';
item.isStaffComplete = false;
} else if (hasMusicStaff && !hasServiceStaff) {
// 只选择了音控组
item.staffBtnType = 'warning'; // 灰色
item.staffTip = '请选择会务服务组';
item.isStaffComplete = false;
} else if (!hasMusicStaff && hasServiceStaff) {
// 只选择了会务服务组
item.staffBtnType = 'warning'; // 灰色
item.staffTip = '请选择音控组';
item.isStaffComplete = false;
}
// 存储会务人员ID列表
item.staffUserIds = uniqueStaffIds;
return uniqueStaffIds; // 返回会务人员ID列表
} catch (error) {
console.error('处理会务负责人状态异常(ID:' + item.id + '):', error);
return []; // 出错时返回空数组
}
},
// 标记通知为已读
markNotificationAsRead(id, userId) {
let _this = this;
let staffNotifications = _this.data.staffNotifications || {};
// 获取该用户对应的通知ID
const notificationId = staffNotifications[id + '_notificationId_' + userId];
if (notificationId) {
console.log('准备标记通知为已读 - 通知ID:', notificationId, '用户ID:', userId, '会议ID:', id);
// 调用后端接口标记为已读
return repairRemindReadRq({
id: notificationId
}).then(res => {
console.log('通知标记已读成功:', res);
// 更新本地通知状态
let readUserIds = staffNotifications[id + '_readUserIds'] || [];
if (!readUserIds.includes(userId)) {
readUserIds.push(userId);
// 更新已读人数
const readCount = readUserIds.length;
const totalCount = parseInt(staffNotifications[id + '_totalCount'] || 1);
staffNotifications[id + '_readCount'] = readCount;
staffNotifications[id + '_readUserIds'] = readUserIds;
staffNotifications[id] = readCount > 0;
// 更新状态
_this.setData({
staffNotifications: staffNotifications
});
// 刷新会议列表通知状态
_this.updateMeetingListNotificationStatus();
}
return Promise.resolve(res);
}).catch(err => {
console.error('标记通知已读失败:', err);
return Promise.reject(err);
});
} else {
console.log('未找到对应的通知ID - 用户ID:', userId, '会议ID:', id);
return Promise.resolve(null);
}
},
// 跳转-预约详情
jumpMeetingDetail(e) {
let _this = this;
let id = e.currentTarget.dataset.id;
console.log('跳转会议详情ID:', id);
// 获取当前用户信息
let userId = _this.data.userData ? _this.data.userData.id : '';
if (!userId) {
console.error('未获取到当前用户ID');
wx.navigateTo({
url: `/pages/meeting/reservationRecord/meetingRecord/meetingDetail/meetingDetail?act=approve&id=${id}`,
});
return;
}
// 先标记该用户的通知为已读
_this.markNotificationAsRead(id, userId).then(() => {
// 无论是否成功标记已读,都跳转到详情页
wx.navigateTo({
url: `/pages/meeting/reservationRecord/meetingRecord/meetingDetail/meetingDetail?act=approve&id=${id}`,
});
}).catch(err => {
console.error('标记通知已读失败:', err);
// 出错时仍然跳转
wx.navigateTo({
url: `/pages/meeting/reservationRecord/meetingRecord/meetingDetail/meetingDetail?act=approve&id=${id}`,
});
});
},
/**
* 跳转-会务负责人
*/
goStaff(e) {
let _this = this;
let id = e.currentTarget.dataset.id;
console.log('跳转会务负责人页面ID:', id);
// 获取当前用户信息
let userId = _this.data.userData ? _this.data.userData.id : '';
if (!userId) {
console.error('未获取到当前用户ID');
wx.navigateTo({
url: `/pages/meeting/meetingRoom/meetingStaff/meetingStaff?rId=${id}`,
});
return;
}
// 标记该用户的通知为已读
_this.markNotificationAsRead(id, userId).then(() => {
// 跳转到会务负责人页面
wx.navigateTo({
url: `/pages/meeting/meetingRoom/meetingStaff/meetingStaff?rId=${id}`,
});
}).catch(err => {
console.error('标记通知已读失败:', err);
// 出错时仍然跳转
wx.navigateTo({
url: `/pages/meeting/meetingRoom/meetingStaff/meetingStaff?rId=${id}`,
});
});
},
/**
* 更新通知状态 - 当用户阅读通知后调用
*/
updateNotificationStatus(data) {
let _this = this;
if (!data || !data.meetingId) {
console.error('更新通知状态失败:缺少必要参数');
return;
}
console.log('收到通知状态更新请求:', data);
const meetingId = data.meetingId;
const userId = data.userId;
// 获取会议项
const meetingItem = _this.data.reservationDataList.find(item => item.id === meetingId);
if (!meetingItem) {
console.error('未找到相关会议:', meetingId);
return;
}
// 获取当前通知状态
let staffNotifications = _this.data.staffNotifications || {};
// 获取已读用户ID列表
let readUserIds = staffNotifications[meetingId + '_readUserIds'] || [];
// 如果用户ID不在已读列表中添加到已读列表
if (userId && !readUserIds.includes(userId)) {
readUserIds.push(userId);
staffNotifications[meetingId + '_readUserIds'] = readUserIds;
// 更新已读计数
const totalCount = Math.max(
meetingItem.totalStaffCount || 0,
meetingItem.staffUserIds ? meetingItem.staffUserIds.length : 0,
1
);
const readCount = Math.min(readUserIds.length, totalCount);
// 更新通知状态
staffNotifications[meetingId] = readCount > 0;
staffNotifications[meetingId + '_readCount'] = readCount;
// 更新会议项的通知状态
meetingItem.readCount = readCount;
meetingItem.isStaffNotificationRead = readCount > 0;
meetingItem.hasUnreadNotification = readCount < totalCount;
// 更新数据
_this.setData({
staffNotifications: staffNotifications
});
console.log('已更新会议通知状态 - 会议ID:', meetingId,
'用户ID:', userId,
'已读人数:', readCount,
'总人数:', totalCount);
// 调用后端API标记通知为已读
if (data.notificationId) {
repairRemindReadRq({
id: data.notificationId
}).then(res => {
console.log('标记通知已读成功:', res);
// 在成功后重新获取通知状态确保UI更新
setTimeout(() => {
_this.getStaffNotificationStatus();
}, 500);
}).catch(err => {
console.error('标记通知已读失败:', err);
});
}
}
},
/**
* 生命周期函数--监听页面显示
* 添加刷新会务负责人状态按钮显示逻辑
*/
onShow() {
let _this = this;
// 每次页面显示时检查用户角色是否有变化
let currentUserData = wx.getStorageSync('user');
let userRoleChanged = false;
// 检查用户角色是否发生变化
if(_this.data.userData && currentUserData && _this.data.userData.roomRole !== currentUserData.roomRole) {
userRoleChanged = true;
// 更新用户数据
_this.setData({
userData: currentUserData
});
console.log('用户角色已变更,重新加载数据');
}
// 数据是否变化或用户角色变化
if (_this.data.dataChange || userRoleChanged) {
// 重置数据变化标志
_this.setData({
dataChange: false
});
// 检查是否从会务负责人页面返回
const staffPageUpdated = wx.getStorageSync('staffPage_updated');
if (staffPageUpdated) {
console.log('检测到会务负责人页面有更新:', staffPageUpdated);
// 清除标记,避免重复处理
wx.removeStorageSync('staffPage_updated');
// 如果会务人员选择页面提供了会议ID优先处理特定会议的通知状态
if (staffPageUpdated.meetingId) {
// 获取会议项数据
const meetingItem = _this.data.reservationDataList.find(
item => item.id === staffPageUpdated.meetingId
);
if (meetingItem) {
console.log('找到需要更新的会议项:', meetingItem.id, meetingItem.title);
// 重新获取该会议的会务人员ID列表
const staffUserIds = _this.processStaffStatus(meetingItem);
// 需要重新获取通知状态
_this.getStaffNotificationStatus();
return;
}
}
// 仅刷新通知状态,不需要重新获取整个列表
_this.getStaffNotificationStatus();
} else {
// 检查是否有全局通知状态更新
const notificationUpdated = wx.getStorageSync('meeting_notification_updated');
if (notificationUpdated) {
console.log('检测到通知状态有更新:', notificationUpdated);
// 清除标记,避免重复处理
wx.removeStorageSync('meeting_notification_updated');
// 更新通知状态
_this.updateNotificationStatus(notificationUpdated);
}
}
} else {
// 检查是否有全局通知状态更新
const notificationUpdated = wx.getStorageSync('meeting_notification_updated');
if (notificationUpdated) {
console.log('检测到通知状态有更新:', notificationUpdated);
// 清除标记,避免重复处理
wx.removeStorageSync('meeting_notification_updated');
// 更新通知状态
_this.updateNotificationStatus(notificationUpdated);
}
}
},
// 取消预约一系列方法
cancelConfirm(e) {
console.log('cancelConfirm', e);
let status = e.currentTarget.dataset.status
let _this = this;
let id = e.currentTarget.dataset.id
if (status == '4') {
// 占用,占用的取消直接删除
Dialog.confirm({
title: '确认',
message: '取消后不可撤销,是否确认?',
})
.then(() => {
// on confirm
approveOrderDel({
id: id,
}).then(res => {
console.log('delApprove', res)
if (res.code == 0) {
// 刷新预约数据
_this.setData({
reservationPageNum: 1,
reservationDataList: [],
reservationIsDataAll: false,
showRejectReason: false
})
Notify({
type: 'success',
message: '已取消'
})
_this.getDataList()
} else {
// 危险通知
Notify({
type: 'danger',
message: res.msg
});
}
})
})
.catch(() => {
// on cancel
});
} else {
// 其余的取消,需要输入原因
_this.setData({
cancelId: id,
showCancelReason: true,
cancelReason: ''
})
}
},
onCloseCancel(e) {
let _this = this;
_this.setData({
cancelId: '',
showCancelReason: false,
cancelReason: ''
})
},
onChangeCancelReason(e) {
let _this = this;
_this.setData({
cancelReason: e.detail
})
},
// 取消订单
cancelOrder() {
let _this = this;
let id = _this.data.cancelId
let reason = _this.data.cancelReason
if (id === '') {
return
}
if (reason === '') {
Notify('请输入取消原因!')
return
}
cancelOrderRq({
id: id,
content: reason
}).then(res => {
console.log('cancelOrderRq', res);
if (res.code == 0) {
// 刷新预约数据
_this.setData({
reservationPageNum: 1,
reservationDataList: [],
reservationIsDataAll: false,
showCancelReason: false
})
_this.getDataList()
} else {
// 危险通知
Notify({
type: 'danger',
message: res.msg
});
}
})
},
editConfirm(e) {
let id = e.currentTarget.dataset.id
this.setData({
editId: id,
showEdit: true
})
},
hideEdit() {
this.setData({
showEdit: false
})
},
editMode(e) {
let _this = this
if (e.detail.type === 1) {
// 重选时间会议室
this.setData({
showEdit: false,
timeShow: true
})
} else {
// 直接跳转
console.log('重新编辑会议基本信息!')
this.setData({
showEdit: false,
})
wx.navigateTo({
url: "/pages/meeting/meetingRoom/meetingOrder/meetingOrder?rId=" + _this.data.editId,
})
}
},
showTimePicker() {
this.setData({
timeShow: true
});
},
hideTimePicker() {
this.setData({
timeShow: false
});
},
// 跳转会议预约页面
goRes(e) {
let _this = this
let date = new Date(e.detail);
let year = date.getFullYear()
let month = date.getMonth() + 1
let day = date.getDate()
// IOS不支持-,必须用/
let chooseTime = year + '/' + month + '/' + day + ' 00:00:00'
let chooseTimeStr = new Date(chooseTime).getTime()
// 加入rId参数为预约id用于重新修改
wx.navigateTo({
url: '/pages/meeting/meetingReservation/meetingReservation?rId=' + _this.data.editId + '&time=' + chooseTimeStr,
})
},
pass(e) {
let _this = this;
let id = e.currentTarget.dataset.id
Dialog.confirm({
title: '确认',
message: '是否确认通过会议室申请?',
})
.then(() => {
// on confirm
approveOrderRq({
id: id,
content: '审核通过',
operate: 'PASS'
}).then(res => {
console.log('passOrder', res)
if (res.code == 0) {
// 通知成功
Notify({
type: 'success',
message: '已通过该申请!'
})
// 先提示用户选择会务负责人,再刷新数据
wx.showModal({
title: '会务负责人',
content: '请选择会议的音控组和会务服务组负责人',
confirmText: '去选择',
cancelText: '我知道了',
success(res) {
if (res.confirm) {
// 点击"去选择",跳转到会务负责人页面
wx.navigateTo({
url: "/pages/meeting/meetingRoom/meetingStaff/meetingStaff?rId=" + id,
})
} else {
// 点击"我知道了",只刷新数据
console.log('用户选择稍后设置会务负责人')
// 刷新预约数据
_this.setData({
reservationPageNum: 1,
reservationDataList: [],
reservationIsDataAll: false,
showRejectReason: false
})
_this.getDataList()
}
}
})
} else {
// 危险通知
Notify({
type: 'danger',
message: res.msg
});
}
})
})
.catch(() => {
// on cancel
});
},
// 驳回预约
rejectConfirm(e) {
console.log('rejectConfirm', e);
let _this = this;
let id = e.currentTarget.dataset.id
_this.setData({
rejectId: id,
showRejectReason: true,
rejectReason: ''
})
},
onCloseReject(e) {
let _this = this;
_this.setData({
rejectId: '',
showRejectReason: false,
rejectReason: ''
})
},
onChangeRejectReason(e) {
let _this = this;
_this.setData({
rejectReason: e.detail
})
},
// 取消订单
rejectOrder() {
let _this = this;
let id = _this.data.rejectId
let reason = _this.data.rejectReason
if (id === '') {
return
}
if (reason === '') {
Notify('请输入驳回原因!')
return
}
// 执行驳回方法
console.log('驳回,原因为' + reason)
approveOrderRq({
id: id,
content: reason,
operate: 'REJECTED'
}).then(res => {
console.log('rejectOrder', res);
if (res.code == 0) {
// 刷新预约数据
_this.setData({
reservationPageNum: 1,
reservationDataList: [],
reservationIsDataAll: false,
showRejectReason: false
})
Notify({
type: 'danger',
message: '已驳回该申请!'
})
_this.getDataList()
} else {
// 危险通知
Notify({
type: 'danger',
message: res.msg
});
}
})
},
/**
* 生命周期函数--监听页面初次渲染完成
*/
onReady() {
},
/**
* 生命周期函数--监听页面隐藏
*/
onHide() {
},
/**
* 生命周期函数--监听页面卸载
*/
onUnload() {
// 取消注册通知状态更新监听器
const app = getApp();
if (app && app.unregisterNotificationStatusChange && this.notificationStatusChangeCallback) {
app.unregisterNotificationStatusChange(this.notificationStatusChangeCallback);
console.log('已取消注册全局通知状态更新监听器');
}
},
/**
* 页面相关事件处理函数--监听用户下拉动作
*/
onPullDownRefresh() {
console.log('onPullDownRefresh', '页面相关事件处理函数--监听用户下拉动作');
let _this = this;
// 重置数据
_this.setData({
reservationPageNum: 1,
reservationDataList: [],
reservationIsDataAll: false,
});
// 重新获取数据
_this.getDataList();
// 停止下拉刷新动画
wx.stopPullDownRefresh();
// 提示用户
Notify({
type: 'success',
message: '刷新成功'
});
},
/**
* 页面上拉触底事件的处理函数
*/
onReachBottom() {
console.log('onReachBottom', '页面上拉触底事件的处理函数');
let _this = this;
// 如果数据已全部加载完成,则不再请求
if (_this.data.reservationIsDataAll) {
Notify({
type: 'primary',
message: '已加载全部数据'
});
return;
}
// 显示加载中提示
wx.showLoading({
title: '加载更多...',
mask: true
});
// 延迟一下再加载,避免频繁请求
setTimeout(() => {
// 获取数据
_this.getDataList();
wx.hideLoading();
}, 300);
},
/**
* 用户点击右上角分享
*/
onShareAppMessage(e) {
console.log('onShareAppMessage', e);
let _this = this;
let id = e.target.dataset.id;
let detail = _this.data.reservationDataList.find(item => item.id == id)
//
let param = {
title: detail.title,
path: "/pages/meeting/invite/invite?id=" + id,
imageUrl: app.IMG_NAME + detail.roomContent.indoorPicUrlFirst,
}
console.log('onShareAppMessage', param);
return param;
}
})