|
|
@@ -84,166 +84,35 @@
|
|
|
</section>
|
|
|
</div>
|
|
|
|
|
|
- <el-dialog
|
|
|
- v-model="dlgVisible"
|
|
|
- :title="picked?.appName || '发起审批'"
|
|
|
- width="920px"
|
|
|
- class="dialog-form-layout"
|
|
|
- align-center
|
|
|
- append-to-body
|
|
|
- modal-class="protocol-dialog-mask"
|
|
|
- destroy-on-close
|
|
|
- :close-on-click-modal="false"
|
|
|
- >
|
|
|
- <div v-loading="detailLoading">
|
|
|
- <form-create
|
|
|
- v-if="formRule.length"
|
|
|
- v-model="formData"
|
|
|
- v-model:api="fapi"
|
|
|
- :rule="formRule"
|
|
|
- :option="formOption"
|
|
|
- />
|
|
|
- <p
|
|
|
- v-if="confirmationDateManualFields.length"
|
|
|
- class="oa-start__tip oa-start__confirm-relink"
|
|
|
- >
|
|
|
- <el-button link type="primary" @click="restoreConfirmationDateAuto">
|
|
|
- 恢复转正日期自动计算
|
|
|
- </el-button>
|
|
|
- </p>
|
|
|
- <p v-else-if="!formRule.length && !detailLoading" class="oa-start__tip">
|
|
|
- 该模板暂无表单字段,仍可直接提交。
|
|
|
- </p>
|
|
|
- <OaFlowPreview
|
|
|
- v-if="!detailLoading"
|
|
|
- v-model:select-by-node="initiatorSelectByNode"
|
|
|
- :steps="flowSteps"
|
|
|
- :loading="previewLoading"
|
|
|
- :resolved="flowResolved"
|
|
|
- :pending-message="flowPendingMessage"
|
|
|
- :user-options="userOptions"
|
|
|
- @select-change="scheduleFlowPreview"
|
|
|
- />
|
|
|
- </div>
|
|
|
- <template #footer>
|
|
|
- <el-button class="btn-ghost" @click="closeDialog">
|
|
|
- <el-icon><Close /></el-icon>
|
|
|
- 取消
|
|
|
- </el-button>
|
|
|
- <el-button class="btn-ghost" :loading="savingDraft" @click="saveDraft">
|
|
|
- <el-icon><Document /></el-icon>
|
|
|
- {{ editingDraftId ? '保存草稿' : '暂存草稿' }}
|
|
|
- </el-button>
|
|
|
- <el-button class="btn-main" type="primary" :loading="submitting" @click="submit">
|
|
|
- <el-icon><Check /></el-icon>
|
|
|
- 提交
|
|
|
- </el-button>
|
|
|
- </template>
|
|
|
- </el-dialog>
|
|
|
+ <OaStartFormDialog
|
|
|
+ ref="startDialogRef"
|
|
|
+ @saved="onDialogSaved"
|
|
|
+ @submitted="onDialogSubmitted"
|
|
|
+ />
|
|
|
</section>
|
|
|
</div>
|
|
|
</template>
|
|
|
|
|
|
<script setup lang="ts">
|
|
|
- import { computed, onMounted, ref, watch } from 'vue'
|
|
|
+ import { computed, onMounted, ref } from 'vue'
|
|
|
import { useRoute, useRouter } from 'vue-router'
|
|
|
- import { Check, Close, Document, Promotion, Search } from '@element-plus/icons-vue'
|
|
|
+ import { Promotion, Search } from '@element-plus/icons-vue'
|
|
|
import { ElMessage } from 'element-plus'
|
|
|
- import { fetchUserList } from '@/api/admin'
|
|
|
- import {
|
|
|
- fetchCreateOaInstanceDraft,
|
|
|
- fetchOaFlowPreview,
|
|
|
- fetchOaGroupList,
|
|
|
- fetchOaInstanceDetail,
|
|
|
- fetchOaInstanceDraftDetail,
|
|
|
- fetchOaTemplateDetail,
|
|
|
- fetchOaTemplates,
|
|
|
- fetchStartOaInstance,
|
|
|
- fetchSubmitOaInstanceDraft,
|
|
|
- fetchUpdateOaInstanceDraft,
|
|
|
- type OaFlowPreviewStep
|
|
|
- } from '@/api/oaApproval'
|
|
|
+ import { fetchOaGroupList, fetchOaTemplates } from '@/api/oaApproval'
|
|
|
import OaAppIcon from '@/components/oa-approval/OaAppIcon.vue'
|
|
|
- import OaFlowPreview from '@/components/oa-approval/OaFlowPreview.vue'
|
|
|
- import { MAX_ADMIN_LIST_PAGE_SIZE } from '@/utils/fetch-paged-list'
|
|
|
+ import OaStartFormDialog from '@/components/oa-approval/OaStartFormDialog.vue'
|
|
|
import { refreshOaMenuBadges } from '@/utils/oa-menu-badge'
|
|
|
- import {
|
|
|
- OA_FC_DEFAULT_GUTTER,
|
|
|
- ensureOaUploadRuleProps
|
|
|
- } from '@/utils/oa-form-create-upload'
|
|
|
- import {
|
|
|
- applyLeaveKitDurationsToFormData,
|
|
|
- ensureLeaveKitRuleProps,
|
|
|
- LEAVE_MANUAL_PREFIX,
|
|
|
- listLeaveKitBindings,
|
|
|
- markLeaveDurationManual
|
|
|
- } from '@/utils/oa-leave-kit-runtime'
|
|
|
- import { applyOvertimeKitDefaults, ensureOvertimeKitRuleProps } from '@/utils/oa-overtime-kit-runtime'
|
|
|
- import { applyResignationKitDefaults } from '@/utils/oa-resignation-kit-runtime'
|
|
|
- import {
|
|
|
- applyConfirmationKitDateLinkage,
|
|
|
- applyConfirmationKitDefaults,
|
|
|
- clearConfirmationDateManualAndRelink,
|
|
|
- CONFIRMATION_MANUAL_PREFIX,
|
|
|
- ensureConfirmationKitVisibility,
|
|
|
- listConfirmationKitBindings,
|
|
|
- listManualConfirmationDateFields,
|
|
|
- markConfirmationDateManual
|
|
|
- } from '@/utils/oa-confirmation-kit-runtime'
|
|
|
- import {
|
|
|
- applyOwnerFieldDefaults,
|
|
|
- ensureOwnerFieldRuleProps
|
|
|
- } from '@/utils/oa-owner-field-defaults'
|
|
|
- import {
|
|
|
- applyTripKitDaysToFormData,
|
|
|
- listTripKits,
|
|
|
- TRIP_MANUAL_PREFIX
|
|
|
- } from '@/utils/oa-trip-kit-runtime'
|
|
|
- import { useUserStore } from '@/store/modules/user'
|
|
|
|
|
|
defineOptions({ name: 'OaApprovalStart' })
|
|
|
|
|
|
const router = useRouter()
|
|
|
const route = useRoute()
|
|
|
- const userStore = useUserStore()
|
|
|
const loading = ref(false)
|
|
|
const templates = ref<any[]>([])
|
|
|
const groupOptions = ref<Array<{ id: string; groupName: string }>>([])
|
|
|
const searchKeyword = ref('')
|
|
|
const activeGroupId = ref('')
|
|
|
- const dlgVisible = ref(false)
|
|
|
- const detailLoading = ref(false)
|
|
|
- const picked = ref<any>(null)
|
|
|
- const formData = ref<Record<string, any>>({})
|
|
|
- const formRule = ref<any[]>([])
|
|
|
- const formOption = ref<Record<string, any>>({
|
|
|
- submitBtn: false,
|
|
|
- resetBtn: false,
|
|
|
- row: { gutter: OA_FC_DEFAULT_GUTTER }
|
|
|
- })
|
|
|
- const fapi = ref<any>(null)
|
|
|
- const submitting = ref(false)
|
|
|
- const savingDraft = ref(false)
|
|
|
- const editingDraftId = ref('')
|
|
|
- const needInitiatorSelect = ref(false)
|
|
|
- const initiatorSelectByNode = ref<Record<string, string[]>>({})
|
|
|
- const userOptions = ref<Array<{ id: string; nickName: string; userNo: string }>>([])
|
|
|
- const flowSteps = ref<OaFlowPreviewStep[]>([])
|
|
|
- const flowResolved = ref(true)
|
|
|
- const flowPendingMessage = ref('必填信息填写后,流程将自动显示')
|
|
|
- const previewLoading = ref(false)
|
|
|
- let previewTimer: ReturnType<typeof setTimeout> | null = null
|
|
|
- /** 避免时长自动回写再次触发手改判定 */
|
|
|
- let leaveKitSyncing = false
|
|
|
- let leaveKitPrevSnapshot: Record<string, unknown> = {}
|
|
|
- let tripKitSyncing = false
|
|
|
- let tripKitPrevSnapshot: Record<string, unknown> = {}
|
|
|
- let confirmationKitSyncing = false
|
|
|
- let confirmationKitPrevSnapshot: Record<string, unknown> = {}
|
|
|
-
|
|
|
- const confirmationDateManualFields = computed(() =>
|
|
|
- listManualConfirmationDateFields({ rule: formRule.value }, formData.value)
|
|
|
- )
|
|
|
+ const startDialogRef = ref<InstanceType<typeof OaStartFormDialog> | null>(null)
|
|
|
|
|
|
const displayGroups = computed(() => {
|
|
|
const kw = (searchKeyword.value || '').trim().toLowerCase()
|
|
|
@@ -252,7 +121,11 @@
|
|
|
list = list.filter((a) => a.groupId === activeGroupId.value)
|
|
|
}
|
|
|
if (kw) {
|
|
|
- list = list.filter((a) => String(a.appName || '').toLowerCase().includes(kw))
|
|
|
+ list = list.filter((a) =>
|
|
|
+ String(a.appName || '')
|
|
|
+ .toLowerCase()
|
|
|
+ .includes(kw)
|
|
|
+ )
|
|
|
}
|
|
|
|
|
|
const bucket = new Map<string, { id: string; name: string; apps: any[] }>()
|
|
|
@@ -283,433 +156,18 @@
|
|
|
return sections
|
|
|
})
|
|
|
|
|
|
- function flowNeedsInitiatorSelect(node: any): boolean {
|
|
|
- if (!node || typeof node !== 'object') return false
|
|
|
- const cfg = node.approverConfig || {}
|
|
|
- if ((cfg.assigneeType || '') === 'initiator_select') return true
|
|
|
- if (node.child && flowNeedsInitiatorSelect(node.child)) return true
|
|
|
- for (const g of node.conditionGroups || []) {
|
|
|
- if (g?.child && flowNeedsInitiatorSelect(g.child)) return true
|
|
|
- }
|
|
|
- return false
|
|
|
- }
|
|
|
-
|
|
|
- async function loadUsers() {
|
|
|
- try {
|
|
|
- const pageSize = MAX_ADMIN_LIST_PAGE_SIZE
|
|
|
- const raw: any[] = []
|
|
|
- let page = 1
|
|
|
- for (;;) {
|
|
|
- const res = await fetchUserList({ page, pageSize, status: '1' })
|
|
|
- const list = res?.list || []
|
|
|
- raw.push(...list)
|
|
|
- if (list.length < pageSize) break
|
|
|
- if (typeof res?.total === 'number' && raw.length >= res.total) break
|
|
|
- page += 1
|
|
|
- }
|
|
|
- userOptions.value = raw.map((u) => ({
|
|
|
- id: u.id,
|
|
|
- nickName: u.nickName || '',
|
|
|
- userNo: u.userNo || ''
|
|
|
- }))
|
|
|
- } catch {
|
|
|
- userOptions.value = []
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- async function loadFlowPreview(appId: string) {
|
|
|
- previewLoading.value = true
|
|
|
- try {
|
|
|
- const preview = await fetchOaFlowPreview(appId, {
|
|
|
- formData: { ...formData.value },
|
|
|
- initiatorSelectByNode: { ...initiatorSelectByNode.value }
|
|
|
- })
|
|
|
- flowResolved.value = preview?.resolved !== false
|
|
|
- flowPendingMessage.value =
|
|
|
- preview?.message || '必填信息填写后,流程将自动显示'
|
|
|
- flowSteps.value = flowResolved.value ? preview?.steps || [] : []
|
|
|
- } catch {
|
|
|
- flowSteps.value = []
|
|
|
- flowResolved.value = true
|
|
|
- } finally {
|
|
|
- previewLoading.value = false
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- function scheduleFlowPreview() {
|
|
|
- if (!dlgVisible.value || !picked.value?.id) return
|
|
|
- if (previewTimer) clearTimeout(previewTimer)
|
|
|
- previewTimer = setTimeout(() => {
|
|
|
- loadFlowPreview(picked.value.id)
|
|
|
- }, 300)
|
|
|
- }
|
|
|
-
|
|
|
- async function onPick(t: any) {
|
|
|
- editingDraftId.value = ''
|
|
|
- picked.value = t
|
|
|
- formData.value = {}
|
|
|
- formRule.value = []
|
|
|
- leaveKitPrevSnapshot = {}
|
|
|
- tripKitPrevSnapshot = {}
|
|
|
- confirmationKitPrevSnapshot = {}
|
|
|
- needInitiatorSelect.value = false
|
|
|
- initiatorSelectByNode.value = {}
|
|
|
- flowSteps.value = []
|
|
|
- flowResolved.value = false
|
|
|
- flowPendingMessage.value = '必填信息填写后,流程将自动显示'
|
|
|
- dlgVisible.value = true
|
|
|
- detailLoading.value = true
|
|
|
- previewLoading.value = true
|
|
|
- try {
|
|
|
- const detail = await fetchOaTemplateDetail(t.id)
|
|
|
- const schema = detail?.formSchemaJson || {}
|
|
|
- const rawRule = Array.isArray(schema.rule)
|
|
|
- ? schema.rule
|
|
|
- : Array.isArray(schema)
|
|
|
- ? schema
|
|
|
- : []
|
|
|
- formRule.value = ensureConfirmationKitVisibility(
|
|
|
- ensureOwnerFieldRuleProps(
|
|
|
- ensureOvertimeKitRuleProps(
|
|
|
- ensureLeaveKitRuleProps(ensureOaUploadRuleProps(rawRule))
|
|
|
- )
|
|
|
- )
|
|
|
- )
|
|
|
- const savedGutter = Number(schema.option?.row?.gutter)
|
|
|
- formOption.value = {
|
|
|
- ...(schema.option || {}),
|
|
|
- form: {
|
|
|
- ...(schema.option?.form || {}),
|
|
|
- labelPosition: 'top'
|
|
|
- },
|
|
|
- // 顶层字段 col.span 布局用;栅格组件 fcRow 由 ensureOaUploadRuleProps 处理
|
|
|
- row: {
|
|
|
- ...(schema.option?.row || {}),
|
|
|
- gutter: savedGutter > 0 ? savedGutter : OA_FC_DEFAULT_GUTTER
|
|
|
- },
|
|
|
- submitBtn: false,
|
|
|
- resetBtn: false
|
|
|
- }
|
|
|
- let data = await applyOwnerFieldDefaults(
|
|
|
- formRule.value,
|
|
|
- {},
|
|
|
- (userStore.info || userStore.getUserInfo) as any
|
|
|
- )
|
|
|
- data = await applyConfirmationKitDefaults(
|
|
|
- { rule: formRule.value },
|
|
|
- data,
|
|
|
- (userStore.info || userStore.getUserInfo) as any
|
|
|
- )
|
|
|
- data = applyResignationKitDefaults(
|
|
|
- { rule: formRule.value },
|
|
|
- data,
|
|
|
- (userStore.info || userStore.getUserInfo) as any
|
|
|
- )
|
|
|
- data = applyOvertimeKitDefaults(
|
|
|
- { rule: formRule.value },
|
|
|
- data,
|
|
|
- (userStore.info || userStore.getUserInfo) as any
|
|
|
- )
|
|
|
- const linked = applyConfirmationKitDateLinkage({ rule: formRule.value }, data)
|
|
|
- formData.value = linked.data
|
|
|
- confirmationKitPrevSnapshot = { ...linked.data }
|
|
|
- const flow = detail?.flowTreeJson || {}
|
|
|
- const root = flow.root || flow
|
|
|
- needInitiatorSelect.value = flowNeedsInitiatorSelect(root)
|
|
|
- if (needInitiatorSelect.value && !userOptions.value.length) {
|
|
|
- await loadUsers()
|
|
|
- }
|
|
|
- await loadFlowPreview(t.id)
|
|
|
- } catch {
|
|
|
- formRule.value = []
|
|
|
- flowSteps.value = []
|
|
|
- flowResolved.value = true
|
|
|
- previewLoading.value = false
|
|
|
- } finally {
|
|
|
- detailLoading.value = false
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- function closeDialog() {
|
|
|
- dlgVisible.value = false
|
|
|
- editingDraftId.value = ''
|
|
|
- }
|
|
|
-
|
|
|
- async function openDraft(draftId: string) {
|
|
|
- const detail = await fetchOaInstanceDraftDetail(draftId)
|
|
|
- const appId = String(detail?.appId || '').trim()
|
|
|
- if (!appId) {
|
|
|
- ElMessage.error('草稿缺少审批模板')
|
|
|
- return
|
|
|
- }
|
|
|
- let row = templates.value.find((t: any) => t.id === appId)
|
|
|
- if (!row) {
|
|
|
- row = {
|
|
|
- id: appId,
|
|
|
- appName: detail?.appName || '发起审批'
|
|
|
- }
|
|
|
- }
|
|
|
- await onPick(row)
|
|
|
- editingDraftId.value = draftId
|
|
|
- const saved = { ...(detail?.formData || {}) }
|
|
|
- formData.value = await applyOwnerFieldDefaults(
|
|
|
- formRule.value,
|
|
|
- saved,
|
|
|
- (userStore.info || userStore.getUserInfo) as any
|
|
|
- )
|
|
|
- formData.value = applyOvertimeKitDefaults(
|
|
|
- { rule: formRule.value },
|
|
|
- formData.value,
|
|
|
- (userStore.info || userStore.getUserInfo) as any
|
|
|
- )
|
|
|
- const linked = applyConfirmationKitDateLinkage(
|
|
|
- { rule: formRule.value },
|
|
|
- formData.value
|
|
|
- )
|
|
|
- formData.value = linked.data
|
|
|
- confirmationKitPrevSnapshot = { ...linked.data }
|
|
|
- leaveKitPrevSnapshot = { ...formData.value }
|
|
|
- tripKitPrevSnapshot = { ...formData.value }
|
|
|
- const sel = detail?.initiatorSelectByNode
|
|
|
- initiatorSelectByNode.value =
|
|
|
- sel && typeof sel === 'object' && !Array.isArray(sel) ? { ...sel } : {}
|
|
|
- await loadFlowPreview(appId)
|
|
|
- }
|
|
|
-
|
|
|
- async function saveDraft() {
|
|
|
- if (!picked.value?.id) return
|
|
|
- savingDraft.value = true
|
|
|
- try {
|
|
|
- const payload = {
|
|
|
- formData: { ...formData.value },
|
|
|
- initiatorSelectByNode: { ...initiatorSelectByNode.value },
|
|
|
- title: picked.value.appName || ''
|
|
|
- }
|
|
|
- if (editingDraftId.value) {
|
|
|
- await fetchUpdateOaInstanceDraft(editingDraftId.value, payload)
|
|
|
- } else {
|
|
|
- const created: any = await fetchCreateOaInstanceDraft({
|
|
|
- appId: picked.value.id,
|
|
|
- ...payload
|
|
|
- })
|
|
|
- if (created?.id) editingDraftId.value = created.id
|
|
|
- }
|
|
|
- void refreshOaMenuBadges()
|
|
|
- closeDialog()
|
|
|
- } finally {
|
|
|
- savingDraft.value = false
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- function syncLeaveKitDurations() {
|
|
|
- if (leaveKitSyncing) return
|
|
|
- if (!formRule.value.length) return
|
|
|
- const schema = { rule: formRule.value }
|
|
|
- const bindings = listLeaveKitBindings(schema)
|
|
|
- if (!bindings.length) return
|
|
|
-
|
|
|
- const curr = { ...formData.value }
|
|
|
- for (const kit of bindings) {
|
|
|
- const prevDur = leaveKitPrevSnapshot[kit.durationField]
|
|
|
- const currDur = curr[kit.durationField]
|
|
|
- const startChanged =
|
|
|
- leaveKitPrevSnapshot[kit.startField] !== curr[kit.startField]
|
|
|
- const endChanged = leaveKitPrevSnapshot[kit.endField] !== curr[kit.endField]
|
|
|
- const durChanged = prevDur !== currDur
|
|
|
- if (durChanged && !startChanged && !endChanged && currDur !== undefined && currDur !== '') {
|
|
|
- Object.assign(curr, markLeaveDurationManual(curr, kit.durationField, true))
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- const { data, changed } = applyLeaveKitDurationsToFormData(schema, curr)
|
|
|
- leaveKitPrevSnapshot = { ...data }
|
|
|
- const manualKeysChanged = bindings.some(
|
|
|
- (k) =>
|
|
|
- !!data[LEAVE_MANUAL_PREFIX + k.durationField] !==
|
|
|
- !!formData.value[LEAVE_MANUAL_PREFIX + k.durationField]
|
|
|
- )
|
|
|
- const durationChanged = bindings.some(
|
|
|
- (k) => data[k.durationField] !== formData.value[k.durationField]
|
|
|
- )
|
|
|
- if (changed || manualKeysChanged || durationChanged) {
|
|
|
- leaveKitSyncing = true
|
|
|
- formData.value = data
|
|
|
- queueMicrotask(() => {
|
|
|
- leaveKitSyncing = false
|
|
|
- })
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- function syncTripKitDurations() {
|
|
|
- if (tripKitSyncing) return
|
|
|
- if (!formRule.value.length) return
|
|
|
- const schema = { rule: formRule.value }
|
|
|
- const kits = listTripKits(schema)
|
|
|
- if (!kits.length) return
|
|
|
-
|
|
|
- const curr = { ...formData.value }
|
|
|
- for (const kit of kits) {
|
|
|
- const prevDays = tripKitPrevSnapshot[kit.daysField]
|
|
|
- const currDays = curr[kit.daysField]
|
|
|
- const daysChanged = prevDays !== currDays
|
|
|
- const listChanged =
|
|
|
- JSON.stringify(tripKitPrevSnapshot[kit.listField]) !==
|
|
|
- JSON.stringify(curr[kit.listField])
|
|
|
- if (daysChanged && !listChanged && currDays !== undefined && currDays !== '') {
|
|
|
- curr[TRIP_MANUAL_PREFIX + kit.daysField] = true
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- const { data, changed } = applyTripKitDaysToFormData(schema, curr)
|
|
|
- tripKitPrevSnapshot = { ...data }
|
|
|
- const manualKeysChanged = kits.some(
|
|
|
- (k) =>
|
|
|
- !!data[TRIP_MANUAL_PREFIX + k.daysField] !==
|
|
|
- !!formData.value[TRIP_MANUAL_PREFIX + k.daysField]
|
|
|
- )
|
|
|
- const daysFieldChanged = kits.some(
|
|
|
- (k) => data[k.daysField] !== formData.value[k.daysField]
|
|
|
- )
|
|
|
- const listFieldChanged = kits.some(
|
|
|
- (k) =>
|
|
|
- JSON.stringify(data[k.listField]) !== JSON.stringify(formData.value[k.listField])
|
|
|
- )
|
|
|
- if (changed || manualKeysChanged || daysFieldChanged || listFieldChanged) {
|
|
|
- tripKitSyncing = true
|
|
|
- formData.value = data
|
|
|
- queueMicrotask(() => {
|
|
|
- tripKitSyncing = false
|
|
|
- })
|
|
|
- }
|
|
|
+ async function onPick(row: any) {
|
|
|
+ await startDialogRef.value?.openForApp(row)
|
|
|
}
|
|
|
|
|
|
- function syncConfirmationKitDates() {
|
|
|
- if (confirmationKitSyncing) return
|
|
|
- if (!formRule.value.length) return
|
|
|
- const schema = { rule: formRule.value }
|
|
|
- const kits = listConfirmationKitBindings(schema)
|
|
|
- if (!kits.length) return
|
|
|
-
|
|
|
- let curr = { ...formData.value }
|
|
|
- for (const kit of kits) {
|
|
|
- const confField = kit.confirmationDateField
|
|
|
- const hireField = kit.hireDateField
|
|
|
- const probField = kit.probationMonthsField
|
|
|
- if (!confField || !hireField || !probField) continue
|
|
|
- const confChanged =
|
|
|
- confirmationKitPrevSnapshot[confField] !== curr[confField]
|
|
|
- const hireChanged = confirmationKitPrevSnapshot[hireField] !== curr[hireField]
|
|
|
- const probChanged = confirmationKitPrevSnapshot[probField] !== curr[probField]
|
|
|
- if (
|
|
|
- confChanged &&
|
|
|
- !hireChanged &&
|
|
|
- !probChanged &&
|
|
|
- curr[confField] !== undefined &&
|
|
|
- curr[confField] !== ''
|
|
|
- ) {
|
|
|
- curr = markConfirmationDateManual(curr, confField, true)
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- const { data, changed } = applyConfirmationKitDateLinkage(schema, curr)
|
|
|
- confirmationKitPrevSnapshot = { ...data }
|
|
|
- const anyDiff =
|
|
|
- changed ||
|
|
|
- kits.some((k) => {
|
|
|
- const f = k.confirmationDateField
|
|
|
- if (!f) return false
|
|
|
- return (
|
|
|
- data[f] !== formData.value[f] ||
|
|
|
- !!data[CONFIRMATION_MANUAL_PREFIX + f] !==
|
|
|
- !!formData.value[CONFIRMATION_MANUAL_PREFIX + f]
|
|
|
- )
|
|
|
- })
|
|
|
- if (anyDiff) {
|
|
|
- confirmationKitSyncing = true
|
|
|
- formData.value = data
|
|
|
- queueMicrotask(() => {
|
|
|
- confirmationKitSyncing = false
|
|
|
- })
|
|
|
- }
|
|
|
+ function onDialogSaved() {
|
|
|
+ void refreshOaMenuBadges()
|
|
|
}
|
|
|
|
|
|
- function restoreConfirmationDateAuto() {
|
|
|
- const schema = { rule: formRule.value }
|
|
|
- let data = { ...formData.value }
|
|
|
- for (const field of listManualConfirmationDateFields(schema, data)) {
|
|
|
- data = clearConfirmationDateManualAndRelink(schema, data, field)
|
|
|
- }
|
|
|
- confirmationKitSyncing = true
|
|
|
- formData.value = data
|
|
|
- confirmationKitPrevSnapshot = { ...data }
|
|
|
- queueMicrotask(() => {
|
|
|
- confirmationKitSyncing = false
|
|
|
- })
|
|
|
- }
|
|
|
-
|
|
|
- watch(
|
|
|
- formData,
|
|
|
- () => {
|
|
|
- syncLeaveKitDurations()
|
|
|
- syncTripKitDurations()
|
|
|
- syncConfirmationKitDates()
|
|
|
- scheduleFlowPreview()
|
|
|
- },
|
|
|
- { deep: true }
|
|
|
- )
|
|
|
-
|
|
|
- async function submit() {
|
|
|
- if (!picked.value?.id) return
|
|
|
- for (const s of flowSteps.value) {
|
|
|
- if (s.type === 'approval') {
|
|
|
- const types =
|
|
|
- Array.isArray(s.assigneeTypes) && s.assigneeTypes.length
|
|
|
- ? s.assigneeTypes
|
|
|
- : s.assigneeType
|
|
|
- ? [s.assigneeType]
|
|
|
- : []
|
|
|
- if (types.includes('initiator_select')) {
|
|
|
- const ids = initiatorSelectByNode.value[s.id] || []
|
|
|
- if (!ids.length) {
|
|
|
- ElMessage.warning(`请为「${s.name || '审批人'}」选择审批人`)
|
|
|
- return
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- if (fapi.value?.validate) {
|
|
|
- try {
|
|
|
- await fapi.value.validate()
|
|
|
- } catch {
|
|
|
- ElMessage.warning('请完善表单必填项')
|
|
|
- return
|
|
|
- }
|
|
|
- }
|
|
|
- submitting.value = true
|
|
|
- try {
|
|
|
- const payload = {
|
|
|
- formData: { ...formData.value },
|
|
|
- initiatorSelectByNode: { ...initiatorSelectByNode.value }
|
|
|
- }
|
|
|
- let data: any
|
|
|
- if (editingDraftId.value) {
|
|
|
- data = await fetchSubmitOaInstanceDraft(editingDraftId.value, {
|
|
|
- ...payload,
|
|
|
- title: picked.value.appName || ''
|
|
|
- })
|
|
|
- } else {
|
|
|
- data = await fetchStartOaInstance({
|
|
|
- appId: picked.value.id,
|
|
|
- ...payload
|
|
|
- })
|
|
|
- }
|
|
|
- closeDialog()
|
|
|
- void refreshOaMenuBadges()
|
|
|
- if (data?.id) {
|
|
|
- router.push({ path: `/system-manage/oa-approval/instances/${data.id}` })
|
|
|
- }
|
|
|
- } finally {
|
|
|
- submitting.value = false
|
|
|
+ function onDialogSubmitted(data: any) {
|
|
|
+ void refreshOaMenuBadges()
|
|
|
+ if (data?.id) {
|
|
|
+ router.push({ path: `/system-manage/oa-approval/instances/${data.id}` })
|
|
|
}
|
|
|
}
|
|
|
|
|
|
@@ -724,30 +182,17 @@
|
|
|
const qCopyFrom = String(route.query.copyFromInstanceId || '').trim()
|
|
|
if (qDraftId) {
|
|
|
try {
|
|
|
- await openDraft(qDraftId)
|
|
|
+ await startDialogRef.value?.openForDraft(qDraftId, templates.value)
|
|
|
} catch {
|
|
|
ElMessage.error('无法打开草稿')
|
|
|
}
|
|
|
} else if (qAppId) {
|
|
|
const row = templates.value.find((t: any) => t.id === qAppId)
|
|
|
if (row) {
|
|
|
- await onPick(row)
|
|
|
if (qCopyFrom) {
|
|
|
- try {
|
|
|
- const old = await fetchOaInstanceDetail(qCopyFrom)
|
|
|
- formData.value = await applyOwnerFieldDefaults(
|
|
|
- formRule.value,
|
|
|
- { ...(old?.formDataJson || {}) },
|
|
|
- (userStore.info || userStore.getUserInfo) as any
|
|
|
- )
|
|
|
- formData.value = applyOvertimeKitDefaults(
|
|
|
- { rule: formRule.value },
|
|
|
- formData.value,
|
|
|
- (userStore.info || userStore.getUserInfo) as any
|
|
|
- )
|
|
|
- } catch {
|
|
|
- /* 预填失败仍可手工填 */
|
|
|
- }
|
|
|
+ await startDialogRef.value?.openForAppWithCopy(row, qCopyFrom)
|
|
|
+ } else {
|
|
|
+ await startDialogRef.value?.openForApp(row)
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
@@ -972,12 +417,6 @@
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- .oa-start__tip {
|
|
|
- margin: 8px 0 0;
|
|
|
- color: var(--mint-text-muted, #94a3b8);
|
|
|
- font-size: 13px;
|
|
|
- }
|
|
|
-
|
|
|
@media (max-width: 640px) {
|
|
|
.oa-app-card {
|
|
|
width: 100%;
|