|
|
|
@ -268,8 +268,8 @@
|
|
|
|
{{ idx + 1 }}、{{ template.flow_info?.no || `流程ID: ${template.flow_id}` }} - {{ template.flow_info?.title || template.flow_title || '-' }}({{ template.flow_info?.creator_name || '-' }} {{ formatFlowCreatedAt(template.flow_info?.created_at) }})
|
|
|
|
{{ idx + 1 }}、{{ template.flow_info?.no || `流程ID: ${template.flow_id}` }} - {{ template.flow_info?.title || template.flow_title || '-' }}({{ template.flow_info?.creator_name || '-' }} {{ formatFlowCreatedAt(template.flow_info?.created_at) }})
|
|
|
|
</h3>
|
|
|
|
</h3>
|
|
|
|
<div class="flow-template-content" v-html="template.html"></div>
|
|
|
|
<div class="flow-template-content" v-html="template.html"></div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
@ -376,12 +376,10 @@ const collectedFlowIds = ref(new Set())
|
|
|
|
const renderedPrintTemplates = ref([]) // 存储渲染后的打印模版HTML
|
|
|
|
const renderedPrintTemplates = ref([]) // 存储渲染后的打印模版HTML
|
|
|
|
const REPEATED_MEETING_MINUTES_MESSAGE = '会议纪要再次使用,仅展示标题,不重复打印'
|
|
|
|
const REPEATED_MEETING_MINUTES_MESSAGE = '会议纪要再次使用,仅展示标题,不重复打印'
|
|
|
|
|
|
|
|
|
|
|
|
let meetingMinutesUsageStack = []
|
|
|
|
|
|
|
|
let meetingMinutesUsageCache = {}
|
|
|
|
let meetingMinutesUsageCache = {}
|
|
|
|
let meetingMinutesSeenMap = new Map()
|
|
|
|
let meetingMinutesSeenMap = new Map()
|
|
|
|
|
|
|
|
|
|
|
|
const resetMeetingMinutesUsage = () => {
|
|
|
|
const resetMeetingMinutesUsage = () => {
|
|
|
|
meetingMinutesUsageStack = []
|
|
|
|
|
|
|
|
meetingMinutesUsageCache = {}
|
|
|
|
meetingMinutesUsageCache = {}
|
|
|
|
meetingMinutesSeenMap = new Map()
|
|
|
|
meetingMinutesSeenMap = new Map()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
@ -411,21 +409,38 @@ const getMeetingMinutesDisplayTitle = (rawVal) => {
|
|
|
|
return '会议纪要'
|
|
|
|
return '会议纪要'
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const extractMeetingMinuteId = (rawVal) => {
|
|
|
|
const extractMeetingMinutesContentHash = (rawVal) => {
|
|
|
|
const parsed = parseMeetingMinutesValue(rawVal)
|
|
|
|
const parsed = parseMeetingMinutesValue(rawVal)
|
|
|
|
if (!parsed || typeof parsed !== 'object') return null
|
|
|
|
if (!parsed || typeof parsed !== 'object') return null
|
|
|
|
const id = parsed.meeting_minute_id
|
|
|
|
|
|
|
|
if (id === null || id === undefined || id === '') return null
|
|
|
|
const candidates = [
|
|
|
|
const normalized = Number(id)
|
|
|
|
parsed.content_hash,
|
|
|
|
if (!Number.isFinite(normalized) || normalized <= 0) return null
|
|
|
|
parsed.contentHash
|
|
|
|
return normalized
|
|
|
|
]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (const candidate of candidates) {
|
|
|
|
|
|
|
|
if (candidate === null || candidate === undefined) continue
|
|
|
|
|
|
|
|
const normalized = String(candidate).trim()
|
|
|
|
|
|
|
|
if (normalized) {
|
|
|
|
|
|
|
|
return normalized
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
return null
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const buildMeetingMinutesFingerprint = (rawVal) => {
|
|
|
|
const buildMeetingMinutesFingerprint = (rawVal) => {
|
|
|
|
const meetingMinuteId = extractMeetingMinuteId(rawVal)
|
|
|
|
const contentHash = extractMeetingMinutesContentHash(rawVal)
|
|
|
|
if (meetingMinuteId) {
|
|
|
|
if (contentHash) {
|
|
|
|
return `meeting_minute_id:${meetingMinuteId}`
|
|
|
|
return `meeting_minutes_hash:${contentHash}`
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
const parsed = parseMeetingMinutesValue(rawVal)
|
|
|
|
|
|
|
|
if (!parsed || typeof parsed !== 'object') return null
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const fallbackMeetingMinuteId = parsed.meeting_minute_id || parsed.original_meeting_minute_id || parsed.source_meeting_minute_id
|
|
|
|
|
|
|
|
if (fallbackMeetingMinuteId) {
|
|
|
|
|
|
|
|
return `meeting_minutes_id:${fallbackMeetingMinuteId}`
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return null
|
|
|
|
return null
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@ -456,12 +471,6 @@ const resolveMeetingMinutesUsage = (occurrenceKey, rawVal) => {
|
|
|
|
meetingMinutesSeenMap.set(fingerprint, occurrenceKey)
|
|
|
|
meetingMinutesSeenMap.set(fingerprint, occurrenceKey)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
meetingMinutesUsageStack.push({
|
|
|
|
|
|
|
|
occurrenceKey,
|
|
|
|
|
|
|
|
fingerprint,
|
|
|
|
|
|
|
|
title: state.title,
|
|
|
|
|
|
|
|
isDuplicate: state.isDuplicate
|
|
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
meetingMinutesUsageCache[occurrenceKey] = state
|
|
|
|
meetingMinutesUsageCache[occurrenceKey] = state
|
|
|
|
return state
|
|
|
|
return state
|
|
|
|
}
|
|
|
|
}
|
|
|
|
@ -1518,6 +1527,37 @@ onMounted(async () => {
|
|
|
|
font-weight: 600;
|
|
|
|
font-weight: 600;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
.meeting-minutes-debug {
|
|
|
|
|
|
|
|
margin-top: 24px;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
.debug-block {
|
|
|
|
|
|
|
|
margin-top: 12px;
|
|
|
|
|
|
|
|
border: 1px solid #d1d5db;
|
|
|
|
|
|
|
|
border-radius: 8px;
|
|
|
|
|
|
|
|
background: #f9fafb;
|
|
|
|
|
|
|
|
overflow: hidden;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
.debug-title {
|
|
|
|
|
|
|
|
padding: 10px 12px;
|
|
|
|
|
|
|
|
font-size: 13px;
|
|
|
|
|
|
|
|
font-weight: 700;
|
|
|
|
|
|
|
|
color: #111827;
|
|
|
|
|
|
|
|
border-bottom: 1px solid #e5e7eb;
|
|
|
|
|
|
|
|
background: #f3f4f6;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
.debug-pre {
|
|
|
|
|
|
|
|
margin: 0;
|
|
|
|
|
|
|
|
padding: 12px;
|
|
|
|
|
|
|
|
white-space: pre-wrap;
|
|
|
|
|
|
|
|
word-break: break-all;
|
|
|
|
|
|
|
|
font-size: 12px;
|
|
|
|
|
|
|
|
line-height: 1.6;
|
|
|
|
|
|
|
|
color: #1f2937;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.breadcrumb {
|
|
|
|
.breadcrumb {
|
|
|
|
color: #909399;
|
|
|
|
color: #909399;
|
|
|
|
margin-left: 8px;
|
|
|
|
margin-left: 8px;
|
|
|
|
|