feat: OA(ecology)项目拉取 + 会议邀请函PDF/微信分享 + 参会人/执行意向增强

OA ecology:
- BizEcologyController + EcologyProjectService: 项目编号搜索/详情回填, 负责人静默建档
- ComplianceLoginService: 合规/负责人登录校验 + 视图 role 匹配
- application-prod/test.yml: ecology 只读库数据源

会议邀请函/分享:
- InvitationPdfService + WxShareService: 邀请函 PDF 生成 + 微信分享
- PdfViewer.vue (pdfjs-dist) + MeetingInvitation.vue: PDF 预览 + 邀请函页

参会人/执行意向:
- BizMeetingAttendee*: 参会人模块增强
- BizExecutionIntent*: 执行意向增强

签到/劳务/导入:
- BizSignServiceImpl + SignFill.vue: 签到劳务
- FieldMismatch/ImportMismatch: 导入校验 VO

公示/会议详情:
- PublicityDetail.vue / MeetingDetail.vue 等前端增强

配置:
- test 短信 mock + 供应商/招标接口切生产域名
This commit is contained in:
郭庆泰
2026-09-03 20:12:15 +08:00
parent beb9799a06
commit 56615f9806
55 changed files with 3296 additions and 516 deletions
+31 -5
View File
@@ -84,11 +84,14 @@
<script setup>
import { ref, reactive, computed, onMounted, onBeforeUnmount } from 'vue'
import { useRouter } from 'vue-router'
import { ElMessage } from 'element-plus'
import QRCode from 'qrcode'
import { listMyMessages, markMessageRead, markAllMessagesRead } from '@/api/public'
import { onGlobal } from '@/utils/sseClient'
const router = useRouter()
const props = defineProps({
limit: { type: Number, default: 5 },
showCategory: { type: Boolean, default: false },
@@ -149,8 +152,34 @@ function extractLink(content) {
return m[0].replace(/[。,、;:,.!?;:)\]]+$/, '')
}
/** 点列表项: 打开详情 + 乐观本地标已读 + 后端 markRead (后端会再推 SSE, navbar 角标自动减) */
// bizType → 路由映射: 这类通知点击后直接进入对应页面 (带 layout), 不弹 dialog 二次点击.
// 后端约定: bizId 存路由参数 (如会议邀请函 bizId = attendeeId). 后续新类型在此扩展.
const BIZ_NAV = {
meetingInvitation: (bizId) => `/doctor/invitation/${bizId}`
}
function navigateTarget(n) {
if (!n.bizType || n.bizId == null) return ''
const fn = BIZ_NAV[n.bizType]
return fn ? fn(n.bizId) : ''
}
/** 乐观本地标已读 + 后端 markRead (后端会再推 SSE, navbar 角标自动减) */
function markRead(n) {
if (!n.read) {
n.read = true
markMessageRead(n.id).catch(() => { n.read = false })
}
}
/** 点列表项: 特定类型直接跳页面; 其余打开详情 dialog */
function openDetail(n) {
const target = navigateTarget(n)
if (target) {
markRead(n)
router.push(target)
return
}
detail.value = n
detailOpen.value = true
const link = extractLink(n.content)
@@ -161,10 +190,7 @@ function openDetail(n) {
.then(url => { detailQrUrl.value = url })
.catch(() => { detailQrUrl.value = '' })
}
if (!n.read) {
n.read = true
markMessageRead(n.id).catch(() => { n.read = false })
}
markRead(n)
}
/** 复制消息正文中的链接 */