6 changed files with 364 additions and 37 deletions
@ -0,0 +1,189 @@ |
|||||
|
<template> |
||||
|
<a-modal |
||||
|
v-model:visible="visible" |
||||
|
:title="noticeDetail.title || '平台协议'" |
||||
|
width="800px" |
||||
|
:maskClosable="false" |
||||
|
:keyboard="false" |
||||
|
:closable="false" |
||||
|
> |
||||
|
<a-spin :spinning="loading"> |
||||
|
<div class="agreement-content" @scroll="handleScroll"> |
||||
|
<div v-if="noticeDetail.title" class="agreement-text"> |
||||
|
<div class="content-header"> |
||||
|
<h3>{{ noticeDetail.title }}</h3> |
||||
|
</div> |
||||
|
<div class="content-html" v-html="noticeDetail.contentHtml"></div> |
||||
|
<div v-if="!noticeDetail.contentHtml" class="default-content"> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div v-else class="agreement-text"> |
||||
|
|
||||
|
</div> |
||||
|
</div> |
||||
|
</a-spin> |
||||
|
|
||||
|
<template #footer> |
||||
|
<a-button @click="handleCancel" size="large">关闭</a-button> |
||||
|
</template> |
||||
|
</a-modal> |
||||
|
</template> |
||||
|
|
||||
|
<script setup> |
||||
|
import { ref, onMounted, reactive, watch } from 'vue'; |
||||
|
import { letterApi } from '/@/api/business/letter/letter-api'; |
||||
|
import { smartSentry } from '/@/lib/smart-sentry'; |
||||
|
|
||||
|
const props = defineProps({ |
||||
|
// 承诺书ID |
||||
|
letterId: { |
||||
|
type: [String, Number], |
||||
|
default: null |
||||
|
} |
||||
|
}); |
||||
|
|
||||
|
const emit = defineEmits(['confirm', 'cancel']); |
||||
|
const visible = ref(false); |
||||
|
const loading = ref(false); |
||||
|
|
||||
|
// 滚动到底部检测 |
||||
|
const hasScrolledToBottom = ref(false); |
||||
|
|
||||
|
// 公告详情数据 |
||||
|
const noticeDetail = reactive({ |
||||
|
title: '', |
||||
|
contentHtml: '', |
||||
|
author: '', |
||||
|
source: '', |
||||
|
publishTime: '' |
||||
|
}); |
||||
|
|
||||
|
// 监听letterId变化 |
||||
|
watch(() => props.letterId, (newLetterId) => { |
||||
|
if (newLetterId) { |
||||
|
getLetterDetail(newLetterId); |
||||
|
} |
||||
|
}, { immediate: true }); |
||||
|
|
||||
|
onMounted(() => { |
||||
|
visible.value = true; |
||||
|
|
||||
|
// 如果有letterId,获取承诺书详情;否则获取首页公告 |
||||
|
if (props.letterId) { |
||||
|
getLetterDetail(props.letterId); |
||||
|
} |
||||
|
}); |
||||
|
|
||||
|
// 滚动事件处理 |
||||
|
function handleScroll(event) { |
||||
|
const element = event.target; |
||||
|
// 检查是否滚动到底部 |
||||
|
if (element.scrollTop + element.clientHeight >= element.scrollHeight - 1) { |
||||
|
hasScrolledToBottom.value = true; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// 获取承诺书详情 |
||||
|
async function getLetterDetail(letterId) { |
||||
|
try { |
||||
|
loading.value = true; |
||||
|
|
||||
|
// 使用/letter/detail/{letterId}接口获取承诺书内容 |
||||
|
const result = await letterApi.isLetter(letterId); |
||||
|
|
||||
|
if (result.data) { |
||||
|
Object.assign(noticeDetail, result.data); |
||||
|
} |
||||
|
} catch (err) { |
||||
|
smartSentry.captureError(err); |
||||
|
console.error('获取承诺书详情失败:', err); |
||||
|
|
||||
|
// 如果接口调用失败,显示默认内容 |
||||
|
Object.assign(noticeDetail, { |
||||
|
title: '承诺书详情', |
||||
|
contentHtml: '', |
||||
|
author: '系统管理员', |
||||
|
source: '平台管理', |
||||
|
publishTime: new Date().toLocaleDateString() |
||||
|
}); |
||||
|
} finally { |
||||
|
loading.value = false; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
const handleConfirm = () => { |
||||
|
emit('confirm'); |
||||
|
visible.value = false; |
||||
|
}; |
||||
|
|
||||
|
const handleCancel = () => { |
||||
|
emit('cancel'); |
||||
|
visible.value = false; |
||||
|
}; |
||||
|
</script> |
||||
|
|
||||
|
<style scoped> |
||||
|
.agreement-content { |
||||
|
max-height: 400px; |
||||
|
overflow-y: auto; |
||||
|
padding: 0 10px; |
||||
|
} |
||||
|
|
||||
|
.agreement-text { |
||||
|
line-height: 1.6; |
||||
|
} |
||||
|
|
||||
|
.content-header { |
||||
|
border-bottom: 1px solid #e8e8e8; |
||||
|
padding-bottom: 15px; |
||||
|
margin-bottom: 20px; |
||||
|
} |
||||
|
|
||||
|
.content-header h3 { |
||||
|
text-align: center; |
||||
|
color: #1e3a8a; |
||||
|
margin-bottom: 10px; |
||||
|
font-size: 18px; |
||||
|
} |
||||
|
|
||||
|
.content-header-info { |
||||
|
text-align: center; |
||||
|
color: #666; |
||||
|
font-size: 12px; |
||||
|
} |
||||
|
|
||||
|
.content-header-info span { |
||||
|
margin: 0 10px; |
||||
|
} |
||||
|
|
||||
|
.content-html { |
||||
|
margin-bottom: 20px; |
||||
|
} |
||||
|
|
||||
|
.content-html >>> p { |
||||
|
margin-bottom: 10px; |
||||
|
line-height: 1.6; |
||||
|
} |
||||
|
|
||||
|
.content-html >>> h4 { |
||||
|
color: #333; |
||||
|
margin: 15px 0 10px 0; |
||||
|
} |
||||
|
|
||||
|
.default-content h4 { |
||||
|
color: #333; |
||||
|
margin: 15px 0 10px 0; |
||||
|
} |
||||
|
|
||||
|
.default-content p { |
||||
|
margin-bottom: 8px; |
||||
|
color: #666; |
||||
|
} |
||||
|
|
||||
|
.important { |
||||
|
color: #ff4d4f !important; |
||||
|
font-weight: bold; |
||||
|
margin-top: 20px !important; |
||||
|
text-align: center; |
||||
|
} |
||||
|
</style> |
||||
Loading…
Reference in new issue