feat: 完善审批退回流程与报销申请关联
后端优化报销单访问策略和常量定义,增强退回原因和审批状态 流转,前端完善退回对话框和审批交互组件,新增报销申请关联 模型,优化文档中心行数据和审批收件箱工具函数,增强引导 流程和会话模型,补充单元测试覆盖。
This commit is contained in:
@@ -240,7 +240,6 @@
|
||||
|
||||
<script setup>
|
||||
import { computed, onMounted, ref, watch } from 'vue'
|
||||
|
||||
import EnterpriseSelect from '../components/shared/EnterpriseSelect.vue'
|
||||
import TableEmptyState from '../components/shared/TableEmptyState.vue'
|
||||
import TableLoadingState from '../components/shared/TableLoadingState.vue'
|
||||
@@ -248,9 +247,8 @@ import { mapExpenseClaimToRequest } from '../composables/useRequests.js'
|
||||
import { fetchApprovalExpenseClaims, fetchArchivedExpenseClaims } from '../services/reimbursements.js'
|
||||
import { countNewDocuments, isNewDocument, markDocumentViewed, readDocumentScope, readViewedDocumentKeys, writeDocumentScope } from '../utils/documentCenterNewState.js'
|
||||
import { extractDateText, formatDocumentListTime, resolveDocumentSortTime, resolveDocumentStayTimeDisplay } from '../utils/documentCenterTime.js'
|
||||
import { excludeArchivedDocumentRows, isArchivedDocumentRow } from '../utils/documentCenterRows.js'
|
||||
import { excludeArchivedDocumentRows, filterApplicationScopeNewRows, isArchivedDocumentRow, prepareApplicationScopeRows } from '../utils/documentCenterRows.js'
|
||||
import { normalizeRequestForUi } from '../utils/requestViewModel.js'
|
||||
|
||||
const DOCUMENT_TYPE_ALL = 'all'
|
||||
const DOCUMENT_TYPE_APPLICATION = 'application'
|
||||
const DOCUMENT_TYPE_REIMBURSEMENT = 'reimbursement'
|
||||
@@ -260,7 +258,6 @@ const DOCUMENT_SCOPE_APPLICATION = '申请单'
|
||||
const DOCUMENT_SCOPE_REIMBURSEMENT = '报销单'
|
||||
const DOCUMENT_SCOPE_REVIEW = '审核单'
|
||||
const DOCUMENT_SCOPE_ARCHIVE = '归档'
|
||||
|
||||
const scopeTabs = [DOCUMENT_SCOPE_ALL, DOCUMENT_SCOPE_APPLICATION, DOCUMENT_SCOPE_REIMBURSEMENT, DOCUMENT_SCOPE_REVIEW, DOCUMENT_SCOPE_ARCHIVE]
|
||||
const statusTabs = ['全部', '草稿', '待提交', '审批中', '待补充', '已完成']
|
||||
const FILTER_CONFIG_BY_SCOPE = {
|
||||
@@ -311,14 +308,12 @@ const documentTypeOptions = [
|
||||
{ value: DOCUMENT_TYPE_APPLICATION, label: '申请单' },
|
||||
{ value: DOCUMENT_TYPE_REIMBURSEMENT, label: '报销单' }
|
||||
]
|
||||
|
||||
const props = defineProps({
|
||||
filteredRequests: { type: Array, required: true },
|
||||
hasData: { type: Boolean, default: false },
|
||||
loading: { type: Boolean, default: false },
|
||||
error: { type: String, default: '' }
|
||||
})
|
||||
|
||||
const emit = defineEmits([
|
||||
'open-document',
|
||||
'create-request',
|
||||
@@ -326,7 +321,6 @@ const emit = defineEmits([
|
||||
'reload',
|
||||
'summary-change'
|
||||
])
|
||||
|
||||
const activeScopeTab = ref(readDocumentScope(DOCUMENT_SCOPE_ALL, scopeTabs))
|
||||
const activeStatusTab = ref('全部')
|
||||
const activeDocumentType = ref(DOCUMENT_TYPE_ALL)
|
||||
@@ -345,17 +339,13 @@ const approvalRows = ref([])
|
||||
const supportingLoading = ref(false)
|
||||
const supportingError = ref('')
|
||||
const viewedDocumentKeys = ref(readViewedDocumentKeys())
|
||||
|
||||
const activeFilterConfig = computed(() =>
|
||||
FILTER_CONFIG_BY_SCOPE[activeScopeTab.value] || FILTER_CONFIG_BY_SCOPE[DOCUMENT_SCOPE_APPLICATION]
|
||||
)
|
||||
|
||||
const showDocumentTypeFilter = computed(() => Boolean(activeFilterConfig.value.showDocumentType))
|
||||
|
||||
const documentTypeFilterLabel = computed(() =>
|
||||
documentTypeOptions.find((item) => item.value === activeDocumentType.value)?.label || '单据类型'
|
||||
)
|
||||
|
||||
const statusFilterOptions = computed(() =>
|
||||
activeFilterConfig.value.statusTabs.map((tab) => ({
|
||||
value: tab,
|
||||
@@ -380,10 +370,11 @@ const ownedRows = computed(() =>
|
||||
)
|
||||
|
||||
const nonArchivedRows = computed(() => mergeDocumentRows([...ownedRows.value, ...approvalRows.value]))
|
||||
const applicationScopeRows = computed(() => prepareApplicationScopeRows(ownedRows.value))
|
||||
|
||||
const scopeNewCountMap = computed(() => ({
|
||||
[DOCUMENT_SCOPE_ALL]: countNewDocuments(nonArchivedRows.value, viewedDocumentKeys.value),
|
||||
[DOCUMENT_SCOPE_APPLICATION]: countNewDocuments(nonArchivedRows.value.filter((row) => row.documentTypeCode === DOCUMENT_TYPE_APPLICATION), viewedDocumentKeys.value),
|
||||
[DOCUMENT_SCOPE_APPLICATION]: countNewDocuments(filterApplicationScopeNewRows(applicationScopeRows.value), viewedDocumentKeys.value),
|
||||
[DOCUMENT_SCOPE_REIMBURSEMENT]: countNewDocuments(ownedRows.value.filter((row) => row.documentTypeCode === DOCUMENT_TYPE_REIMBURSEMENT), viewedDocumentKeys.value),
|
||||
[DOCUMENT_SCOPE_REVIEW]: countNewDocuments(approvalRows.value, viewedDocumentKeys.value),
|
||||
[DOCUMENT_SCOPE_ARCHIVE]: countNewDocuments(archiveRows.value, viewedDocumentKeys.value)
|
||||
@@ -401,7 +392,7 @@ const activeScopeRows = computed(() => {
|
||||
if (activeScopeTab.value === DOCUMENT_SCOPE_ALL) return nonArchivedRows.value
|
||||
|
||||
if (activeScopeTab.value === DOCUMENT_SCOPE_APPLICATION) {
|
||||
return nonArchivedRows.value.filter((row) => row.documentTypeCode === DOCUMENT_TYPE_APPLICATION)
|
||||
return applicationScopeRows.value
|
||||
}
|
||||
|
||||
if (activeScopeTab.value === DOCUMENT_SCOPE_REIMBURSEMENT) {
|
||||
|
||||
Reference in New Issue
Block a user