提交
This commit is contained in:
1 parent
80138c6388
commit
693e8a678e
682 files changed
+211375
-5306
No files matched your search
@@ -25,6 +25,12 @@
|
||||
恢复转正日期自动计算
|
||||
</el-button>
|
||||
</p>
|
||||
<p v-if="overtimeDurationManualFields.length" class="oa-start__tip">
|
||||
<el-button link type="primary" @click="restoreOvertimeAuto">
|
||||
<el-icon><RefreshRight /></el-icon>
|
||||
恢复加班时长自动计算
|
||||
</el-button>
|
||||
</p>
|
||||
<p v-else-if="!formRule.length && !detailLoading" class="oa-start__tip">
|
||||
该模板暂无表单字段,仍可直接提交。
|
||||
</p>
|
||||
@@ -58,9 +64,10 @@
|
||||
|
||||
<script setup lang="ts">
|
||||
import { computed, ref, watch } from 'vue'
|
||||
import { Check, Close, Document } from '@element-plus/icons-vue'
|
||||
import { Check, Close, Document, RefreshRight } from '@element-plus/icons-vue'
|
||||
import { ElMessage } from 'element-plus'
|
||||
import { fetchUserList } from '@/api/admin'
|
||||
import { fetchCnHolidayRange } from '@/api/cnHoliday'
|
||||
import {
|
||||
fetchCreateOaInstanceDraft,
|
||||
fetchOaFlowPreview,
|
||||
@@ -84,7 +91,11 @@
|
||||
} from '@/utils/oa-leave-kit-runtime'
|
||||
import {
|
||||
applyOvertimeKitDefaults,
|
||||
ensureOvertimeKitRuleProps
|
||||
applyOvertimeKitDurationsToFormData,
|
||||
ensureOvertimeKitRuleProps,
|
||||
listOvertimeKitBindings,
|
||||
markOvertimeDurationManual,
|
||||
OVERTIME_MANUAL_PREFIX
|
||||
} from '@/utils/oa-overtime-kit-runtime'
|
||||
import { applyResignationKitDefaults } from '@/utils/oa-resignation-kit-runtime'
|
||||
import {
|
||||
@@ -146,11 +157,24 @@
|
||||
let tripKitPrevSnapshot: Record<string, unknown> = {}
|
||||
let confirmationKitSyncing = false
|
||||
let confirmationKitPrevSnapshot: Record<string, unknown> = {}
|
||||
let overtimeKitSyncing = false
|
||||
let overtimeKitPrevSnapshot: Record<string, unknown> = {}
|
||||
const overtimeRestMap: Record<string, boolean> = {}
|
||||
|
||||
const confirmationDateManualFields = computed(() =>
|
||||
listManualConfirmationDateFields({ rule: formRule.value }, formData.value)
|
||||
)
|
||||
|
||||
const overtimeDurationManualFields = computed(() => {
|
||||
const fields: string[] = []
|
||||
for (const kit of listOvertimeKitBindings({ rule: formRule.value })) {
|
||||
if (formData.value[OVERTIME_MANUAL_PREFIX + kit.durationField]) {
|
||||
fields.push(kit.durationField)
|
||||
}
|
||||
}
|
||||
return fields
|
||||
})
|
||||
|
||||
function flowNeedsInitiatorSelect(node: any): boolean {
|
||||
if (!node || typeof node !== 'object') return false
|
||||
const cfg = node.approverConfig || {}
|
||||
@@ -219,6 +243,7 @@
|
||||
leaveKitPrevSnapshot = {}
|
||||
tripKitPrevSnapshot = {}
|
||||
confirmationKitPrevSnapshot = {}
|
||||
overtimeKitPrevSnapshot = {}
|
||||
needInitiatorSelect.value = false
|
||||
initiatorSelectByNode.value = {}
|
||||
flowSteps.value = []
|
||||
@@ -274,6 +299,8 @@
|
||||
const linked = applyConfirmationKitDateLinkage({ rule: formRule.value }, data)
|
||||
formData.value = linked.data
|
||||
confirmationKitPrevSnapshot = { ...linked.data }
|
||||
overtimeKitPrevSnapshot = { ...linked.data }
|
||||
void syncOvertimeKitDurations()
|
||||
const flow = detail?.flowTreeJson || {}
|
||||
const root = flow.root || flow
|
||||
needInitiatorSelect.value = flowNeedsInitiatorSelect(root)
|
||||
@@ -338,6 +365,8 @@
|
||||
confirmationKitPrevSnapshot = { ...linked.data }
|
||||
leaveKitPrevSnapshot = { ...formData.value }
|
||||
tripKitPrevSnapshot = { ...formData.value }
|
||||
overtimeKitPrevSnapshot = { ...formData.value }
|
||||
void syncOvertimeKitDurations()
|
||||
const sel = detail?.initiatorSelectByNode
|
||||
initiatorSelectByNode.value =
|
||||
sel && typeof sel === 'object' && !Array.isArray(sel) ? { ...sel } : {}
|
||||
@@ -360,6 +389,8 @@
|
||||
formData.value,
|
||||
(userStore.info || userStore.getUserInfo) as any
|
||||
)
|
||||
overtimeKitPrevSnapshot = { ...formData.value }
|
||||
void syncOvertimeKitDurations()
|
||||
} catch {
|
||||
/* 预填失败仍可手工填 */
|
||||
}
|
||||
@@ -530,12 +561,137 @@
|
||||
})
|
||||
}
|
||||
|
||||
async function ensureOvertimeHolidayRange(startYmd: string, endYmd: string) {
|
||||
const start = String(startYmd || '').trim().slice(0, 10)
|
||||
const end = String(endYmd || '').trim().slice(0, 10)
|
||||
if (!start || !end) return
|
||||
let lo = start
|
||||
let hi = end
|
||||
if (lo > hi) {
|
||||
const t = lo
|
||||
lo = hi
|
||||
hi = t
|
||||
}
|
||||
const begin = new Date(lo + 'T00:00:00')
|
||||
const finish = new Date(hi + 'T00:00:00')
|
||||
if (Number.isNaN(begin.getTime()) || Number.isNaN(finish.getTime())) return
|
||||
|
||||
let allPresent = true
|
||||
for (let d = new Date(begin); d <= finish; d.setDate(d.getDate() + 1)) {
|
||||
const y = d.getFullYear()
|
||||
const m = String(d.getMonth() + 1).padStart(2, '0')
|
||||
const day = String(d.getDate()).padStart(2, '0')
|
||||
const key = `${y}-${m}-${day}`
|
||||
if (!(key in overtimeRestMap)) {
|
||||
allPresent = false
|
||||
break
|
||||
}
|
||||
}
|
||||
if (allPresent) return
|
||||
|
||||
try {
|
||||
const res = await fetchCnHolidayRange(lo, hi)
|
||||
const days = res?.days || []
|
||||
for (const day of days) {
|
||||
const key = String(day?.dayDate || '').trim().slice(0, 10)
|
||||
if (!key) continue
|
||||
overtimeRestMap[key] = !!day.isRestDay
|
||||
}
|
||||
} catch {
|
||||
/* 失败保留已有 map,计算回退周末规则 */
|
||||
}
|
||||
}
|
||||
|
||||
function isRestDayResolver(ymd: string): boolean {
|
||||
if (ymd in overtimeRestMap) return overtimeRestMap[ymd]
|
||||
const d = new Date(ymd + 'T00:00:00')
|
||||
const w = d.getDay()
|
||||
return w === 0 || w === 6
|
||||
}
|
||||
|
||||
async function syncOvertimeKitDurations() {
|
||||
if (overtimeKitSyncing) return
|
||||
if (!formRule.value.length) return
|
||||
const schema = { rule: formRule.value }
|
||||
const bindings = listOvertimeKitBindings(schema)
|
||||
if (!bindings.length) return
|
||||
|
||||
overtimeKitSyncing = true
|
||||
try {
|
||||
let minYmd = ''
|
||||
let maxYmd = ''
|
||||
for (const kit of bindings) {
|
||||
for (const field of [kit.startField, kit.endField]) {
|
||||
const ymd = String(formData.value[field] || '')
|
||||
.trim()
|
||||
.slice(0, 10)
|
||||
if (ymd.length < 10) continue
|
||||
if (!minYmd || ymd < minYmd) minYmd = ymd
|
||||
if (!maxYmd || ymd > maxYmd) maxYmd = ymd
|
||||
}
|
||||
}
|
||||
if (minYmd && maxYmd) {
|
||||
await ensureOvertimeHolidayRange(minYmd, maxYmd)
|
||||
}
|
||||
|
||||
const curr = { ...formData.value }
|
||||
for (const kit of bindings) {
|
||||
const prevDur = overtimeKitPrevSnapshot[kit.durationField]
|
||||
const currDur = curr[kit.durationField]
|
||||
const startChanged = overtimeKitPrevSnapshot[kit.startField] !== curr[kit.startField]
|
||||
const endChanged = overtimeKitPrevSnapshot[kit.endField] !== curr[kit.endField]
|
||||
const durChanged = prevDur !== currDur
|
||||
if (
|
||||
durChanged &&
|
||||
!startChanged &&
|
||||
!endChanged &&
|
||||
currDur !== undefined &&
|
||||
currDur !== ''
|
||||
) {
|
||||
Object.assign(curr, markOvertimeDurationManual(curr, kit.durationField, true))
|
||||
}
|
||||
}
|
||||
|
||||
const { data, changed } = applyOvertimeKitDurationsToFormData(
|
||||
schema,
|
||||
curr,
|
||||
isRestDayResolver
|
||||
)
|
||||
overtimeKitPrevSnapshot = { ...data }
|
||||
const manualKeysChanged = bindings.some(
|
||||
(k) =>
|
||||
!!data[OVERTIME_MANUAL_PREFIX + k.durationField] !==
|
||||
!!formData.value[OVERTIME_MANUAL_PREFIX + k.durationField]
|
||||
)
|
||||
const durationChanged = bindings.some(
|
||||
(k) => data[k.durationField] !== formData.value[k.durationField]
|
||||
)
|
||||
if (changed || manualKeysChanged || durationChanged) {
|
||||
formData.value = data
|
||||
}
|
||||
} finally {
|
||||
queueMicrotask(() => {
|
||||
overtimeKitSyncing = false
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
function restoreOvertimeAuto() {
|
||||
let data = { ...formData.value }
|
||||
for (const kit of listOvertimeKitBindings({ rule: formRule.value })) {
|
||||
data = markOvertimeDurationManual(data, kit.durationField, false)
|
||||
}
|
||||
formData.value = data
|
||||
void syncOvertimeKitDurations()
|
||||
}
|
||||
|
||||
watch(
|
||||
formData,
|
||||
() => {
|
||||
syncLeaveKitDurations()
|
||||
syncTripKitDurations()
|
||||
syncConfirmationKitDates()
|
||||
void syncOvertimeKitDurations()
|
||||
scheduleFlowPreview()
|
||||
},
|
||||
{ deep: true }
|
||||
|
||||
Reference in new issue
Block a user