// pages/exhibition/activeDetails/index.js const { museumApi } = require('../../../utils/api.js'); const WxParse = require('../../../utils/wxParse/wxParse.js'); Page({ /** * 页面的初始数据 */ data: { loading: false, detailData: null, contentItems: [], fromtype: '', isFrom: '', shouldShowBackButton: true, isPreviewMode: false, formattedPublishTime: '', isLoggedIn: false }, /** * 生命周期函数--监听页面加载 */ onLoad(options) { // 检查登录状态 this.checkLoginStatus(); // 检查是否来自微信,如果是则隐藏返回按钮 if (options.isfrom === 'weixin') { this.setData({ shouldShowBackButton: false, isFrom: 'weixin' }); } // 检查是否为预览模式 if (options.preview === '1') { this.setData({ isPreviewMode: true }); } // 设置页面参数 this.setData({ fromtype: options.type || '', isFrom: options.isFrom || '' }); // 加载详情数据 this.loadDetailData(options); }, /** * 返回上一页 */ goBack() { wx.navigateBack({ delta: 1 }); }, /** * 跳转到线上观展 */ goToOnlineExhibition() { const { detailData, isPreviewMode } = this.data; let targetUrl; // 如果是预览模式,优先使用webSiteB if (isPreviewMode && detailData.webSiteB) { targetUrl = detailData.webSiteB; } else { targetUrl = detailData.webSite; } if (targetUrl) { // 小程序中使用web-view或复制链接 wx.setClipboardData({ data: targetUrl, success: function() { wx.showToast({ title: '链接已复制', icon: 'success' }); } }); } }, /** * 跳转到活动预约页面 */ goToActivePreview() { const { detailData } = this.data; const activityId = detailData.activityId || detailData.id; wx.navigateTo({ url: `/pages/index/active-page/active-page?activityId=${activityId}&type=2` }); }, /** * 处理链接点击 */ onLinkTap(e) { const { url } = e.currentTarget.dataset; if (url) { // 复制链接到剪贴板 wx.setClipboardData({ data: url, success: function() { wx.showToast({ title: '链接已复制', icon: 'success' }); } }); } }, /** * 处理rich-text中的链接点击 */ onRichTextTap(e) { const { links } = e.currentTarget.dataset; if (links && links.length > 0) { // 如果只有一个链接,直接打开 if (links.length === 1) { const url = links[0].url; this.openLink(url); } else { // 如果有多个链接,显示选择列表 const itemList = links.map(link => link.text); wx.showActionSheet({ itemList: itemList, success: (res) => { const selectedLink = links[res.tapIndex]; this.openLink(selectedLink.url); } }); } } }, /** * 打开链接 */ openLink(url) { if (url) { // 复制链接到剪贴板 wx.setClipboardData({ data: url, success: function() { wx.showToast({ title: '链接已复制', icon: 'success' }); } }); } }, /** * 格式化时间(横线分隔) */ formatTimeWithDash(timeStr) { console.log('formatTimeWithDash:', timeStr); if (!timeStr) return ''; const date = new Date(timeStr); const year = date.getFullYear(); const month = String(date.getMonth() + 1).padStart(2, '0'); const day = String(date.getDate()).padStart(2, '0'); return `${year}-${month}-${day}`; }, /** * 获取字段值(支持预览模式) */ getFieldValue(fieldName) { const { detailData, isPreviewMode } = this.data; if (!detailData) return ''; if (isPreviewMode) { // 预览模式下优先读取带B后缀的字段 const bFieldName = fieldName + 'B'; return detailData[bFieldName] || detailData[fieldName] || ''; } else { return detailData[fieldName] || ''; } }, /** * 加载详情数据 */ loadDetailData(options) { const { id, type } = options; const that = this; if (!id) { console.error('缺少ID参数'); return; } this.setData({ loading: true }); let apiPromise; // 根据类型调用不同的接口 switch (type) { case 'information': apiPromise = museumApi.getInformationDetail(id); break; case 'exhibition': apiPromise = museumApi.getExhibitDetail(id); break; case 'activity': apiPromise = museumApi.getActivityDetail(id); break; case 'news': apiPromise = museumApi.getNewsDetail(id); break; case 'museum': apiPromise = museumApi.getMuseumDetail(1); break; default: console.error('未知的详情类型:', type); this.setData({ loading: false }); return; } apiPromise .then(response => { if (response) { // 获取内容字段 // const content = this.getContentForParsing(response); // const parsedContent = this.parseContent(content); let article = response.context; WxParse.wxParse('article', 'html', article, that, 5); // 格式化发布时间 const formattedTime = this.formatTimeWithDash(response.publish); this.setData({ detailData: response, // contentItems: parsedContent, formattedPublishTime: formattedTime }); } }) .catch(error => { console.error('获取详情数据失败:', error); this.setData({ detailData: null }); wx.showToast({ title: '加载失败', icon: 'none' }); }) .finally(() => { this.setData({ loading: false }); }); }, /** * 获取用于解析的内容 */ getContentForParsing(detailData) { const { isPreviewMode } = this.data; if (isPreviewMode) { // 预览模式下优先使用带B后缀的字段 return detailData.contextB || detailData.context || ''; } else { return detailData.context || ''; } }, /** * 解析HTML内容为不同类型的内容项(使用map页面的解析规则) */ parseContent(content) { if (!content) return []; const contentItems = []; const matches = []; // 定义所有匹配规则 const patterns = [ { regex: /]*>(.*?)<\/p>/gi, type: 'text', handler: (match) => { let content = match[1]; // 检查是否包含缩进样式 const hasIndent = match[0].includes('text-indent:2em') || match[0].includes('text-indent: 2em'); // 检查是否包含a标签链接 const linkRegex = /]*href="([^"]+)"[^>]*>(.*?)<\/a>/gi; const hasLinks = linkRegex.test(content); if (hasLinks) { // 如果包含链接,转换为rich-text节点格式 let processedContent = content; const links = []; let linkMatch; linkRegex.lastIndex = 0; // 重置正则表达式 // 收集所有链接信息 while ((linkMatch = linkRegex.exec(content)) !== null) { links.push({ url: linkMatch[1], text: linkMatch[2].replace(/<[^>]*>/g, '') }); } // 将a标签转换为带样式的span标签 processedContent = processedContent.replace( /]*href="([^"]+)"[^>]*>(.*?)<\/a>/gi, '$2' ); return { type: 'text_with_links', content: processedContent, links: links, indent: hasIndent }; } else { // 普通文本处理 let text = content.replace(/<[^>]*>/g, ''); // 将HTML实体编码的空格转换为对应数量的  text = text.replace(/ /g, ' '); text = text.replace(/ /g, '  '); text = text.replace(/ /g, '    '); text = text.replace(/ /g, ' '); // 将普通空格也转换为  text = text.replace(/ /g, ' '); // 如果有缩进样式,在文本前添加缩进 if (hasIndent) { text = '    ' + text; } return { type: 'text', content: text, indent: hasIndent }; } } }, { regex: /]*class="[^"]*media-wrap[^"]*image-wrap[^"]*"[^>]*>.*?]*src="([^"]+)"[^>]*(?:alt="([^"]*)")?\/??>.*?<\/div>/gi, type: 'image', handler: (match) => ({ type: 'image', src: match[1], alt: match[2] || '图片' }) }, { regex: /]*class="[^"]*media-wrap[^"]*video-wrap[^"]*"[^>]*>.*?]*src="([^"]+)"[^>]*(?:poster="([^"]*)")?\/??>.*?<\/div>/gi, type: 'video', handler: (match) => ({ type: 'video', src: match[1], poster: match[2] || '' }) }, { regex: /]*class="[^"]*media-wrap[^"]*audio-wrap[^"]*"[^>]*>.*?]*src="([^"]+)"[^>]*(?:title="([^"]*)")?\/??>.*?<\/div>/gi, type: 'audio', handler: (match) => ({ type: 'audio', src: match[1], title: match[2] || '音频' }) } ]; // 收集所有匹配项及其位置 patterns.forEach(pattern => { let match; pattern.regex.lastIndex = 0; // 重置正则表达式的lastIndex while ((match = pattern.regex.exec(content)) !== null) { const item = pattern.handler(match); if ((item.type === 'text' && item.content.trim()) || item.type !== 'text') { matches.push({ index: match.index, item: item }); } } }); // 按照在原HTML中的位置排序 matches.sort((a, b) => a.index - b.index); // 提取排序后的内容项 return matches.map(match => match.item); }, /** * 生命周期函数--监听页面初次渲染完成 */ onReady() { }, /** * 生命周期函数--监听页面显示 */ onShow() { // 每次显示页面时检查登录状态 this.checkLoginStatus(); }, /** * 检查登录状态 */ checkLoginStatus() { const app = getApp(); const token = wx.getStorageSync('token'); const isLoggedIn = !!(token && !app.globalData.isGuest); this.setData({ isLoggedIn: isLoggedIn }); }, /** * 生命周期函数--监听页面隐藏 */ onHide() { }, /** * 生命周期函数--监听页面卸载 */ onUnload() { }, /** * 页面相关事件处理函数--监听用户下拉动作 */ onPullDownRefresh() { }, /** * 页面上拉触底事件的处理函数 */ onReachBottom() { }, /** * 用户点击右上角分享 */ onShareAppMessage() { } });