提交
This commit is contained in:
1 parent
0e1b750457
commit
8c49021d38
93 files changed
+22731
-12107
No files matched your search
@@ -15,14 +15,14 @@
|
||||
<div class="oa-flow-card__row">
|
||||
<span class="oa-flow-card__name">{{ item.title }}</span>
|
||||
<span v-if="statusBadge(item)" class="oa-flow-badge" :class="statusBadge(item)">
|
||||
{{ statusText(item.status) }}
|
||||
{{ nodeStatusText(item) }}
|
||||
</span>
|
||||
<span v-if="signBadge(item)" class="oa-flow-badge" :class="signBadge(item)">
|
||||
{{ signBadgeText(item) }}
|
||||
</span>
|
||||
<span v-else-if="item.taskType === 'cc'" class="oa-flow-badge cc">抄送</span>
|
||||
<span v-else-if="item.taskType === 'end'" class="oa-flow-badge mute">结束</span>
|
||||
<template v-if="item.timestamp">
|
||||
<template v-if="showNodeTimestamp(item)">
|
||||
<span class="oa-flow-card__sep">·</span>
|
||||
<span class="oa-flow-card__meta" :title="item.timestamp">{{ item.timestamp }}</span>
|
||||
</template>
|
||||
@@ -66,6 +66,12 @@
|
||||
{{ line.text }}
|
||||
</p>
|
||||
</div>
|
||||
<div
|
||||
v-else-if="item.kind === 'terminal' && item.status === 'cancelled' && terminalWithdrawText(item)"
|
||||
class="oa-person-lines"
|
||||
>
|
||||
<p class="oa-person-line is-danger">{{ terminalWithdrawText(item) }}</p>
|
||||
</div>
|
||||
<div v-else-if="showNodeComment(item)" class="oa-flow-card__comment">
|
||||
意见:{{ item.commentText }}
|
||||
</div>
|
||||
@@ -134,9 +140,17 @@
|
||||
return map[s] || s
|
||||
}
|
||||
|
||||
/** 任务节点 cancelled=系统清待办 →「无需处理」;终态 cancelled 仍为「已撤销」 */
|
||||
function nodeStatusText(item: OaProgressChainItem) {
|
||||
const s = item.status || ''
|
||||
if (item.kind !== 'terminal' && s === 'cancelled') return '无需处理'
|
||||
return statusText(s)
|
||||
}
|
||||
|
||||
/** 徽章色:与 Fresh Mint 语义一致 */
|
||||
function statusBadge(item: OaProgressChainItem) {
|
||||
const s = item.status || ''
|
||||
if (item.kind !== 'terminal' && s === 'cancelled') return 'mute'
|
||||
if (s === 'approved' || s === 'completed' || s === 'done' || s === 'submitted') return 'ok'
|
||||
if (s === 'pending' || s === 'running') return 'or'
|
||||
if (s === 'rejected' || s === 'cancelled' || s === 'returned') return 'danger'
|
||||
@@ -183,15 +197,31 @@
|
||||
function showNodeComment(item: OaProgressChainItem): boolean {
|
||||
// 有按人行时不再展示节点级拼接意见,避免双份
|
||||
if (personLines(item).length) return false
|
||||
if (item.kind === 'terminal' && item.status === 'cancelled') return false
|
||||
return Boolean(item.commentText)
|
||||
}
|
||||
|
||||
function terminalWithdrawText(item: OaProgressChainItem): string {
|
||||
const name = (item.assignee || '').trim()
|
||||
const tip = (item.commentText || '').trim() || '发起人撤销'
|
||||
return name ? `${name} ${tip}` : tip
|
||||
}
|
||||
|
||||
/** 任务节点 cancelled 为系统清待办,不展示时间(时间归终态「已撤销」) */
|
||||
function showNodeTimestamp(item: OaProgressChainItem): boolean {
|
||||
const ts = (item.timestamp || '').trim()
|
||||
if (!ts) return false
|
||||
if (item.kind !== 'terminal' && item.status === 'cancelled') return false
|
||||
return true
|
||||
}
|
||||
|
||||
function personChipClass(status?: string) {
|
||||
const s = status || ''
|
||||
if (s === 'approved' || s === 'completed') return 'is-ok'
|
||||
if (s === 'pending' || s === 'running') return 'is-pending'
|
||||
if (s === 'rejected' || s === 'returned' || s === 'cancelled') return 'is-danger'
|
||||
if (s === 'done' || s === 'not_reached' || s === 'transferred') return 'is-mute'
|
||||
if (s === 'rejected' || s === 'returned') return 'is-danger'
|
||||
if (s === 'done' || s === 'not_reached' || s === 'transferred' || s === 'cancelled')
|
||||
return 'is-mute'
|
||||
return ''
|
||||
}
|
||||
|
||||
@@ -201,7 +231,7 @@
|
||||
if (s === 'rejected') return '已拒绝'
|
||||
if (s === 'returned') return '已打回'
|
||||
if (s === 'pending' || s === 'running') return '待处理'
|
||||
if (s === 'done') return '无需处理'
|
||||
if (s === 'done' || s === 'cancelled') return '无需处理'
|
||||
if (s === 'not_reached') return '未到达'
|
||||
if (s === 'transferred') return '已转交'
|
||||
return ''
|
||||
@@ -212,13 +242,17 @@
|
||||
const statusLabel =
|
||||
p.status === 'transferred' && target
|
||||
? `转交给${target}`
|
||||
: statusText(p.status || '')
|
||||
const parts = [p.nickName || '', statusLabel, p.timestamp || ''].filter(Boolean)
|
||||
: personStatusHint(p.status) || statusText(p.status || '')
|
||||
// cancelled/done 人员行不展示操作时间
|
||||
const ts =
|
||||
p.status === 'cancelled' || p.status === 'done' ? '' : String(p.timestamp || '').trim()
|
||||
const parts = [p.nickName || '', statusLabel, ts].filter(Boolean)
|
||||
return parts.join(' · ')
|
||||
}
|
||||
|
||||
function dotClass(item: OaProgressChainItem) {
|
||||
const s = item.status || ''
|
||||
if (item.kind !== 'terminal' && s === 'cancelled') return ''
|
||||
if (s === 'approved' || s === 'completed' || s === 'done' || s === 'submitted') return 'ok'
|
||||
if (s === 'pending' || s === 'running') return 'pending'
|
||||
if (s === 'rejected' || s === 'cancelled' || s === 'returned') return 'danger'
|
||||
|
||||
@@ -129,6 +129,12 @@
|
||||
listTripKits,
|
||||
TRIP_MANUAL_PREFIX
|
||||
} from '@/utils/oa-trip-kit-runtime'
|
||||
import {
|
||||
buildFlowPreviewRequestKey,
|
||||
collectConditionFields,
|
||||
shouldShowFlowPreviewSpinner,
|
||||
shouldSkipFlowPreviewRequest
|
||||
} from '@/utils/oa-flow-preview-refresh'
|
||||
import { useUserStore } from '@/store/modules/user'
|
||||
|
||||
defineOptions({ name: 'OaStartFormDialog' })
|
||||
@@ -162,6 +168,12 @@
|
||||
const flowPendingMessage = ref('必填信息填写后,流程将自动显示')
|
||||
const previewLoading = ref(false)
|
||||
let previewTimer: ReturnType<typeof setTimeout> | null = null
|
||||
/** 流程条件字段:仅这些 formData 变化才重拉预览 */
|
||||
let flowConditionFields: string[] = []
|
||||
let lastFlowPreviewRequestKey: string | null = null
|
||||
let inFlightFlowPreviewKey: string | null = null
|
||||
let hasCompletedFlowPreview = false
|
||||
let flowPreviewReqSeq = 0
|
||||
/** 避免时长自动回写再次触发手改判定 */
|
||||
let leaveKitSyncing = false
|
||||
let leaveKitPrevSnapshot: Record<string, unknown> = {}
|
||||
@@ -242,23 +254,56 @@
|
||||
}
|
||||
|
||||
async function loadFlowPreview(appId: string) {
|
||||
previewLoading.value = true
|
||||
if (!appId) return
|
||||
const requestKey = buildFlowPreviewRequestKey({
|
||||
formData: formData.value,
|
||||
initiatorSelectByNode: initiatorSelectByNode.value,
|
||||
conditionFields: flowConditionFields
|
||||
})
|
||||
if (
|
||||
shouldSkipFlowPreviewRequest(lastFlowPreviewRequestKey, requestKey, {
|
||||
inFlightKey: inFlightFlowPreviewKey
|
||||
})
|
||||
) {
|
||||
return
|
||||
}
|
||||
const seq = ++flowPreviewReqSeq
|
||||
inFlightFlowPreviewKey = requestKey
|
||||
const showSpinner = shouldShowFlowPreviewSpinner({
|
||||
hasCompletedPreview: hasCompletedFlowPreview
|
||||
})
|
||||
if (showSpinner) previewLoading.value = true
|
||||
try {
|
||||
const preview = await fetchOaFlowPreview(appId, {
|
||||
formData: { ...formData.value },
|
||||
initiatorSelectByNode: { ...initiatorSelectByNode.value }
|
||||
})
|
||||
if (seq !== flowPreviewReqSeq) return
|
||||
lastFlowPreviewRequestKey = requestKey
|
||||
flowResolved.value = preview?.resolved !== false
|
||||
flowPendingMessage.value = preview?.message || '必填信息填写后,流程将自动显示'
|
||||
flowSteps.value = flowResolved.value ? preview?.steps || [] : []
|
||||
} catch {
|
||||
if (seq !== flowPreviewReqSeq) return
|
||||
flowSteps.value = []
|
||||
flowResolved.value = true
|
||||
} finally {
|
||||
previewLoading.value = false
|
||||
if (seq === flowPreviewReqSeq) {
|
||||
inFlightFlowPreviewKey = null
|
||||
hasCompletedFlowPreview = true
|
||||
previewLoading.value = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function resetFlowPreviewState(flowRoot: unknown) {
|
||||
flowConditionFields = collectConditionFields(flowRoot)
|
||||
lastFlowPreviewRequestKey = null
|
||||
inFlightFlowPreviewKey = null
|
||||
hasCompletedFlowPreview = false
|
||||
flowPreviewReqSeq += 1
|
||||
}
|
||||
|
||||
function scheduleFlowPreview() {
|
||||
if (!dlgVisible.value || !picked.value?.id) return
|
||||
if (previewTimer) clearTimeout(previewTimer)
|
||||
@@ -335,6 +380,7 @@
|
||||
void syncOvertimeKitDurations()
|
||||
const flow = detail?.flowTreeJson || {}
|
||||
const root = flow.root || flow
|
||||
resetFlowPreviewState(root)
|
||||
needInitiatorSelect.value = flowNeedsInitiatorSelect(root)
|
||||
if (needInitiatorSelect.value && !userOptions.value.length) {
|
||||
await loadUsers()
|
||||
|
||||
Reference in new issue
Block a user