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.
389 lines
10 KiB
389 lines
10 KiB
<template>
|
|
<div class="notice-box opacity" v-if="dataList.length > 0" :class="elder ? 'elder-wrapper' : ''">
|
|
<van-notice-bar
|
|
left-icon="volume-o"
|
|
mode="link"
|
|
:scrollable="false"
|
|
:color="fontColor"
|
|
:background="bgColor"
|
|
@click.stop="selectedPopup($event)"
|
|
>
|
|
<van-swipe
|
|
vertical
|
|
class="notice-swipe"
|
|
:autoplay="3000"
|
|
:scrollable="false"
|
|
:show-indicators="false"
|
|
@change="onChange"
|
|
>
|
|
<van-swipe-item class="van-ellipsis" v-for="(item, index) in dataList" :key="index">{{
|
|
item.noticeTitle
|
|
}}</van-swipe-item>
|
|
</van-swipe>
|
|
</van-notice-bar>
|
|
<!-- popup弹窗内容(全屏) -->
|
|
<van-popup
|
|
class="notice-popup"
|
|
v-model:show="noticeShow"
|
|
position="bottom"
|
|
:duration="0.3"
|
|
:close-on-click-overlay="true"
|
|
:style="{ height: '100%', 'background-color': contentBg }"
|
|
>
|
|
<div class="notice-box-main">
|
|
<div class="notice-header">
|
|
<van-nav-bar
|
|
class="notice-bar-box"
|
|
:class="{ 'notice-title': !isWX }"
|
|
:title="title"
|
|
@click-left="handleHide"
|
|
>
|
|
<template #left><van-icon name="cross" /></template>
|
|
</van-nav-bar>
|
|
</div>
|
|
<div
|
|
style="
|
|
margin-top: 10px;
|
|
margin-right: 0.4rem;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: flex-end;
|
|
"
|
|
v-if="Tips"
|
|
>
|
|
<van-checkbox
|
|
v-model="checked"
|
|
:icon-size="elder ? '20px' : '17px'"
|
|
:shape="elder ? 'round' : 'square'"
|
|
style="color: #000"
|
|
>
|
|
<span :class="elder ? 'tip' : ''" style="color: #000; font-weight: 500"
|
|
>本周不再提示</span
|
|
>
|
|
</van-checkbox>
|
|
</div>
|
|
<div class="notice-content" v-if="content" v-html="content"></div>
|
|
</div>
|
|
</van-popup>
|
|
<!-- popup弹窗内容(半屏) -->
|
|
<van-popup
|
|
class="notice-popup"
|
|
v-model:show="noticeShowban"
|
|
overlay-class="noticeBg"
|
|
position="center"
|
|
:duration="0.6"
|
|
:close-on-click-overlay="true"
|
|
:style="{ background: 'none' }"
|
|
>
|
|
<div class="notice-box-main" style="width: 300px">
|
|
<div
|
|
:class="elder ? 'notice-box-main-icon' : ''"
|
|
style="margin-bottom: 10px; text-align: right"
|
|
>
|
|
<van-icon
|
|
:name="elder ? 'cross' : 'close'"
|
|
:size="elder ? 16 : 20"
|
|
:color="elder ? '#979797' : '#fff'"
|
|
@click="handleHide"
|
|
/>
|
|
</div>
|
|
<div
|
|
class="notice-content"
|
|
style="
|
|
background: #fff;
|
|
border-radius: 10px;
|
|
width: 300px;
|
|
height: 300px;
|
|
box-sizing: border-box;
|
|
padding: 15px;
|
|
"
|
|
v-if="content"
|
|
v-html="content"
|
|
></div>
|
|
<div
|
|
style="margin-top: 10px; display: flex; align-items: center; justify-content: center"
|
|
v-if="Tips"
|
|
>
|
|
<van-checkbox
|
|
v-model="checked"
|
|
:icon-size="elder ? '20px' : '17px'"
|
|
:shape="elder ? 'round' : 'square'"
|
|
style="color: #fff"
|
|
>
|
|
<span :class="elder ? 'tip' : ''" style="color: #fff; font-weight: 500"
|
|
>本周不再提示</span
|
|
>
|
|
</van-checkbox>
|
|
</div>
|
|
</div>
|
|
</van-popup>
|
|
</div>
|
|
</template>
|
|
|
|
<script setup>
|
|
import { ref, inject, onMounted, nextTick } from 'vue'
|
|
import { showToast } from 'vant'
|
|
import { Post } from '@/utils/https'
|
|
import imageService from '@/utils/imageService'
|
|
|
|
const props = defineProps({ isWX: { type: Boolean, default: false } })
|
|
const emit = defineEmits(['isNoticeHandle'])
|
|
|
|
const store = inject('appStore', null)
|
|
const source = inject('source', ref(''))
|
|
const isLostMessage = inject('isLostMessage', ref(null))
|
|
const hotUser = inject('hotUser', ref(false))
|
|
const elder = inject('elder', false)
|
|
|
|
const current = ref(0)
|
|
const fontColor = ref('#ed6a0c')
|
|
const bgColor = ref('#fffbe8')
|
|
const contentBg = ref('#fff')
|
|
const noticeShow = ref(false)
|
|
const noticeShowban = ref(false)
|
|
const content = ref('')
|
|
const title = ref('')
|
|
const dataList = ref([])
|
|
const checked = ref(false)
|
|
const Tips = ref(false)
|
|
|
|
function handleHide() {
|
|
noticeShow.value = false
|
|
noticeShowban.value = false
|
|
if (checked.value) localStorage['liccsAds'] = new Date().getTime()
|
|
}
|
|
|
|
async function replaceDomainDev(txt) {
|
|
if (window.location.href.indexOf('localhost') !== -1) {
|
|
txt = txt.replace('../', '//ssp-dev.trace.com.cn/')
|
|
}
|
|
const imgRegex = /<img[^>]+src=["']([^"']+)["'][^>]*>/gi
|
|
const matches = []
|
|
let match
|
|
const originalTxt = txt
|
|
while ((match = imgRegex.exec(originalTxt)) !== null) {
|
|
matches.push({ fullTag: match[0], src: match[1], index: match.index })
|
|
}
|
|
if (matches.length === 0) return txt
|
|
|
|
const results = await Promise.all(
|
|
matches.map(async (item) => {
|
|
try {
|
|
let fileKey = item.src
|
|
if (fileKey.startsWith('..')) fileKey = fileKey.substring(2)
|
|
if (
|
|
!fileKey.includes('/') ||
|
|
fileKey.startsWith('http://') ||
|
|
fileKey.startsWith('https://') ||
|
|
fileKey.startsWith('data:')
|
|
)
|
|
return null
|
|
const imageUrl = await imageService.getImageByKey(fileKey, {
|
|
useCache: true,
|
|
timeout: 10000,
|
|
})
|
|
return { originalTag: item.fullTag, originalSrc: item.src, newUrl: imageUrl }
|
|
} catch {
|
|
return null
|
|
}
|
|
})
|
|
)
|
|
|
|
let processedTxt = txt
|
|
results.forEach((result) => {
|
|
if (result?.newUrl) {
|
|
const escapedSrc = result.originalSrc.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')
|
|
processedTxt = processedTxt.replace(
|
|
new RegExp(`src=["']${escapedSrc}["']`, 'g'),
|
|
`src="${result.newUrl}"`
|
|
)
|
|
}
|
|
})
|
|
return processedTxt
|
|
}
|
|
|
|
async function selectedPopup() {
|
|
Tips.value = false
|
|
checked.value = false
|
|
const index = current.value
|
|
const item = dataList.value[index]
|
|
if (item?.noticeDesc) {
|
|
content.value = await replaceDomainDev(item.noticeDesc)
|
|
if (source.value === '95290000') title.value = item.noticeTitle
|
|
if (item.screenType === 1) noticeShow.value = true
|
|
else noticeShowban.value = true
|
|
}
|
|
store?.dispatch?.('userBehavior', { eventType: '9', eventMsg: '点击通知栏' }).catch(console.log)
|
|
}
|
|
|
|
function onChange(index) {
|
|
current.value = index
|
|
}
|
|
|
|
async function getDataList() {
|
|
Tips.value = true
|
|
const param = { source: source.value || source }
|
|
Post('message/info', param)
|
|
.then(async (res) => {
|
|
if (res.code && res.code !== 0) {
|
|
emit('isNoticeHandle', false)
|
|
showToast(res.msg)
|
|
return
|
|
}
|
|
fontColor.value = res.data.fontColor
|
|
bgColor.value = res.data.bgColor
|
|
dataList.value = res.data.list || []
|
|
if (dataList.value.length > 0) {
|
|
emit('isNoticeHandle', true)
|
|
if (source.value === '95290000') title.value = dataList.value[0].noticeTitle
|
|
const lostMsg = isLostMessage.value || isLostMessage
|
|
if ((lostMsg === 2 || lostMsg === 3) && !hotUser.value) {
|
|
if (res.data.isPop === 1) {
|
|
content.value = await replaceDomainDev(dataList.value[0].noticeDesc)
|
|
if (adsIsWeek(dataList.value[0].id)) {
|
|
setTimeout(() => {
|
|
if (dataList.value[0].screenType === 1) noticeShow.value = true
|
|
else noticeShowban.value = true
|
|
}, 500)
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
emit('isNoticeHandle', false)
|
|
}
|
|
})
|
|
.catch((error) => {
|
|
emit('isNoticeHandle', false)
|
|
console.log(error)
|
|
})
|
|
}
|
|
|
|
function adsIsWeek(id) {
|
|
const oldtime = localStorage['liccsAds']
|
|
const nowData = new Date(new Date().toLocaleDateString())
|
|
let currentDay = nowData.getDay()
|
|
if (currentDay === 0) currentDay = 7
|
|
const monDayTime = nowData.getTime() - (currentDay - 1) * 24 * 60 * 60 * 1000
|
|
const sunDayTime =
|
|
nowData.getTime() + (7 - currentDay) * 24 * 60 * 60 * 1000 + 24 * 60 * 60 * 1000 - 1
|
|
return !(oldtime && monDayTime <= oldtime && sunDayTime >= oldtime)
|
|
}
|
|
|
|
onMounted(() => {
|
|
nextTick(() => getDataList())
|
|
})
|
|
</script>
|
|
|
|
<style scoped>
|
|
.notice-box {
|
|
height: 40px;
|
|
overflow: hidden;
|
|
text-align: left;
|
|
}
|
|
|
|
.notice-swipe {
|
|
height: 40px;
|
|
line-height: 40px;
|
|
}
|
|
|
|
.notice-box-main {
|
|
position: relative;
|
|
display: flex;
|
|
flex-direction: column;
|
|
align-items: stretch;
|
|
overflow-y: visible;
|
|
height: 100%;
|
|
border-radius: 20px 20px 0 0;
|
|
}
|
|
|
|
.notice-header {
|
|
height: 43px;
|
|
flex-shrink: 0;
|
|
}
|
|
|
|
.notice-content {
|
|
padding: 15px 15px 30px 15px;
|
|
font-size: 14px;
|
|
flex: 1 1 auto;
|
|
overflow-y: scroll;
|
|
-webkit-overflow-scrolling: touch;
|
|
}
|
|
|
|
.notice-content :deep(p) {
|
|
padding: 6px 0;
|
|
}
|
|
|
|
.notice-content :deep(em),
|
|
.notice-content :deep(i) {
|
|
font-style: italic;
|
|
}
|
|
|
|
.notice-content :deep(table tr th),
|
|
.notice-content :deep(table tr td) {
|
|
border: 1px solid #ddd;
|
|
padding: 5px;
|
|
}
|
|
|
|
.notice-title {
|
|
height: 100%;
|
|
background: #0074e1;
|
|
}
|
|
|
|
.notice-bar-box.van-nav-bar :deep(.van-icon) {
|
|
font-size: 22px;
|
|
line-height: 40px;
|
|
color: #1989fa;
|
|
}
|
|
|
|
.notice-bar-box.van-nav-bar :deep(.van-nav-bar__text) {
|
|
line-height: 40px;
|
|
}
|
|
|
|
.notice-title.van-nav-bar :deep(.van-icon),
|
|
.notice-title.van-nav-bar :deep(.van-nav-bar__text),
|
|
.notice-title.van-nav-bar :deep(.van-nav-bar__title) {
|
|
color: #fff;
|
|
}
|
|
|
|
.notice-content :deep(h1) {
|
|
font-size: 36px !important;
|
|
}
|
|
|
|
.notice-content :deep(h2) {
|
|
font-size: 24px !important;
|
|
}
|
|
|
|
.notice-content :deep(h3) {
|
|
font-size: 21px !important;
|
|
}
|
|
|
|
.notice-content :deep(h4) {
|
|
font-size: 18px !important;
|
|
}
|
|
|
|
.notice-content :deep(h5) {
|
|
font-size: 16px !important;
|
|
}
|
|
|
|
.notice-content :deep(h6) {
|
|
font-size: 14px !important;
|
|
}
|
|
|
|
.notice-content :deep(h1),
|
|
.notice-content :deep(h2),
|
|
.notice-content :deep(h3),
|
|
.notice-content :deep(h4),
|
|
.notice-content :deep(h5),
|
|
.notice-content :deep(h6) {
|
|
font-weight: bold !important;
|
|
}
|
|
|
|
.notice-content :deep(img) {
|
|
width: auto;
|
|
max-width: 100%;
|
|
}
|
|
|
|
.notice-content :deep(img:not([class='eleImg'])) {
|
|
margin: 20px 0;
|
|
}
|
|
</style> |