图书馆小程序
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

213 lines
4.9 KiB

<template>
<view class="activity-detail">
<image class="activity-img" :src="detail.imgUrl" mode="aspectFill"></image>
<view class="activity-base">
<text class="title">{{ detail.title }}</text>
<view class="time">
<uni-icons class="detail-icon" custom-prefix="iconfont" type="icon-shijian" size="15"></uni-icons>
<text>{{ detail.time }}</text>
</view>
<view class="location">
<uni-icons class="detail-icon" type="location" size="20"></uni-icons>
<text>{{ detail.location }}</text>
</view>
</view>
<view class="rich-content">
<text class="content-title">活动介绍/回顾</text>
<rich-text :nodes="contentNodes"></rich-text>
</view>
<view class="detail-bottom">
<view class="detail-left">
<button open-type="share" class="handle-btn">
<uni-icons custom-prefix="iconfont" type="icon-fenxiang01" size="20"></uni-icons>
<text>分享</text>
</button>
<button class="handle-btn" @click="toggleCollect">
<uni-icons :type="isCollected ? 'heart-filled' : 'heart'" size="20" color="#ff4444"></uni-icons>
<text>{{ isCollected ? '已收藏' : '收藏' }}</text>
</button>
</view>
<button class="join-btn" :class="detail.status === 0 ? 'disabled-btn' : ''">
{{ detail.status === 1 ? '我要参加' : '活动结束' }}
</button>
</view>
</view>
</template>
<script>
export default {
data() {
return {
detail: {},
isCollected: false,
activityId: "",
contentNodes: ""
};
},
onLoad(options) {
const item = JSON.parse(decodeURIComponent(options.item));
this.detail = item;
this.activityId = item.title;
this.formatContent();
this.checkCollectStatus();
},
methods: {
formatContent() {
let content = this.detail.content || "";
// ======================================
// 1. 把 content 里的 <image src="@/static/..."> 转成 <img> 标签
// ======================================
const localImgReg = /<image\s+src="@\/static\/([^"]+)"[^>]*>/gi;
content = content.replace(localImgReg, (match, path) => {
return `
<div style="text-align:center; margin:12px 0;">
<img src="/static/${path}" style="width:90%; border-radius:8px;">
</div>
`;
});
// ======================================
// 2. 把 https://mmbiz.qpic.cn 图片链接转成图片
// ======================================
const httpImgReg = /https:\/\/mmbiz\.qpic\.cn[^ \n\r]+/g;
content = content.replace(httpImgReg, url => {
return `
<div style="text-align:center; margin:12px 0;">
<img src="${url}" style="width:90%; border-radius:8px;">
</div>
`;
});
this.contentNodes = content;
},
checkCollectStatus() {
const list = uni.getStorageSync('activityCollectList') || [];
this.isCollected = list.includes(this.activityId);
},
toggleCollect() {
let list = uni.getStorageSync('activityCollectList') || [];
if (this.isCollected) {
list = list.filter(i => i !== this.activityId);
uni.showToast({ title: "取消收藏" });
} else {
list.push(this.activityId);
uni.showToast({ title: "收藏成功", icon: "success" });
}
uni.setStorageSync('activityCollectList', list);
this.isCollected = !this.isCollected;
}
},
onShareAppMessage() {
return {
title: this.detail.title,
path: "/subpkg/pages/activity-detail/activity-detail?item=" + encodeURIComponent(JSON.stringify(this.detail)),
imageUrl: this.detail.imgUrl
};
}
};
</script>
<style lang="scss" scoped>
.activity-detail {
padding-bottom: 60px;
background: #f5f5f5;
}
.activity-img {
width: 100%;
height: 180px;
}
.activity-base {
background: #fff;
padding: 15px;
margin-bottom: 10px;
.title {
font-size: 16px;
font-weight: bold;
padding-bottom: 10px;
}
.time,
.location {
display: flex;
align-items: center;
font-size: 12px;
color: #999;
padding-top: 10px;
.detail-icon {
padding-right: 4px;
}
}
.time{
padding-left: 3px;
}
}
.rich-content {
background: #fff;
padding: 10px 0;
.content-title{
position: relative;
font-size: 16px;
font-weight: bold;
color: #333;
padding-left: 12px;
&::before{
position: absolute;
left: 0;
top: 50%;
margin-top: -9px;
content: "";
width: 4px;
height: 18px;
background-color: #01a4fe;
}
}
}
.detail-bottom {
position: fixed;
bottom: 0;
left: 0;
right: 0;
height: 50px;
background: #fff;
display: flex;
align-items: center;
justify-content: space-between;
padding: 0 15px;
box-shadow: 0 -2px 5px rgba(0, 0, 0, 0.05);
}
.detail-left {
display: flex;
gap: 10px;
}
.handle-btn {
display: flex;
align-items: center;
gap: 4px;
background: #f5f5f5;
border-radius: 30px;
padding: 0 12px;
height: 36px;
font-size: 14px;
}
.join-btn {
background: #01a4fe;
color: #fff;
border-radius: 30px;
padding: 0 20px;
height: 36px;
}
.disabled-btn {
background: #ccc !important;
}
</style>