This commit is contained in:
zlwu committed 2026-08-01 22:49:11 +08:00
1 parent e59b2aa6cb
commit eccefc6650
63 files changed
+13267 -11330

No files matched your search

+9 -2
View File
@@ -1246,8 +1246,15 @@ body {
overflow: visible;
}
/* 无分页条时列表区为 panel 末段:裁剪底圆角,避免表格白底盖住 panel 圆角 */
.panel > .list-body.list-wrap:not(:has(+ .pagination.list-pager-bar)):not(:has(+ .list-footer)) {
/*
* 无分页条时列表区为 panel 末段:裁剪底圆角,避免表格白底盖住 panel 圆角。
* 须同时排除「分页在 list-body 内部」的常见结构,否则 overflow:hidden 会裁切
* 表格横向滚到最右侧时的末列右缘。
*/
.panel
> .list-body.list-wrap:not(:has(+ .pagination.list-pager-bar)):not(:has(+ .list-footer)):not(
:has(.pagination.list-pager-bar)
):not(:has(.list-footer)) {
overflow: hidden;
}
+19 -3
View File
@@ -600,13 +600,16 @@ body .el-table thead {
color: inherit;
}
// 表格默认占满整个宽度
// 表格默认占满容器;允许在列宽总和更大时由内部横向滚动撑开,避免末列被裁切
.el-table {
width: 100% !important;
max-width: 100%;
// 修复固定列时表格宽度问题
// 占满容器,但不禁止内部 table 按列宽超出(横向滚动由 body-wrapper/scrollbar 承担)
.el-table__inner-wrapper {
width: 100% !important;
width: 100%;
min-width: 100%;
max-width: 100%;
}
}
@@ -614,6 +617,7 @@ body .el-table thead {
.page-container {
.el-table {
width: 100% !important;
max-width: 100%;
}
}
@@ -814,6 +818,18 @@ body .el-table thead {
border-right: 1px solid var(--mint-border) !important;
}
}
/*
* 横向滚到最右侧时末列完整可见:
* 给表头/表体 table 右侧留出空隙,增大可滚动宽度,避免末列被 overflow 或
* 叠加滚动条裁切。不要给末列 .cell 加 padding,否则会挤占「创建时间」等定宽文案。
*/
&.el-table--scrollable-x {
.el-table__header-wrapper table,
.el-table__body-wrapper table {
margin-right: 12px;
}
}
}
.page-container .el-table th.el-table__cell,
@@ -4,7 +4,15 @@
/*滚动条整体部分,必须要设置*/
::-webkit-scrollbar {
width: 8px !important;
/* 原先 height:0 会让原生横向滚动条不可用,窄屏多列表格滚到最右时末列易被裁切 */
height: 8px !important;
}
/* 表格内部由 Element Plus 自定义滚动条接管时,继续隐藏原生条,避免双条 */
.el-table .el-scrollbar__wrap--hidden-default::-webkit-scrollbar {
width: 0 !important;
height: 0 !important;
display: none;
}
/*滚动条的轨道*/
@@ -78,6 +78,15 @@
>
<el-icon :size="12"><Delete /></el-icon>
</button>
<button
v-if="compact && disabled && file.fileUrl"
type="button"
class="attachment-compact-download"
title="下载"
@click.stop="handleDownloadAttachment(file)"
>
<el-icon :size="12"><Download /></el-icon>
</button>
<div class="attachment-footer">
<span class="attachment-name" :title="file.fileName">{{ file.fileName }}</span>
<div v-if="!disabled" class="attachment-actions">
@@ -836,7 +845,7 @@ defineExpose({ hasUploading })
}
}
/* 只读紧凑:更小缩略图(查看弹窗等) */
/* 只读紧凑:更小缩略图(查看弹窗等),保留角标下载 */
.attachment-upload--compact.attachment-upload--readonly {
.attachment-list {
gap: 4px;
@@ -850,6 +859,7 @@ defineExpose({ hasUploading })
}
.attachment-item {
position: relative;
width: 40px;
border-radius: 6px;
@@ -867,5 +877,28 @@ defineExpose({ hasUploading })
min-height: 24px;
border-radius: 6px;
}
.attachment-compact-download {
position: absolute;
top: 2px;
right: 2px;
z-index: 2;
display: flex;
align-items: center;
justify-content: center;
width: 18px;
height: 18px;
padding: 0;
border: none;
border-radius: 999px;
background: rgba(15, 23, 42, 0.72);
color: #fff;
cursor: pointer;
transition: background 0.15s ease;
&:hover {
background: #1ca851;
}
}
}
</style>
@@ -124,10 +124,6 @@ withDefaults(
:deep(.attachment-preview) {
height: 96px;
}
:deep(.attachment-footer) {
display: none;
}
}
.pl-plan-hazard-cert-view-table__missing {
@@ -115,7 +115,6 @@
v-if="feedbackImageCsv"
:model-value="feedbackImageCsv"
disabled
compact
/>
<span v-else class="pl-plan-feedback-table__empty-cell">—</span>
</div>
@@ -229,7 +228,6 @@
v-if="ioOrderImageCsv"
:model-value="ioOrderImageCsv"
disabled
compact
/>
<span v-else class="pl-plan-feedback-table__empty-cell">—</span>
</div>
+6 -3
View File
@@ -49,18 +49,21 @@ export function parseCrmAttachmentField(
.map((ossId) => ({ ossId, category: 'other' }))
}
/** 从 ossId/url 推导展示文件名 */
/** 从 ossId/url 推导展示文件名(完整 URL 与相对路径均取最后一段) */
export function crmAttachmentDisplayName(ossId: string, index = 0): string {
const id = (ossId || '').trim()
if (!id) return `附件${index + 1}`
if (/^https?:\/\//i.test(id)) {
const seg = id.split('/').pop() || ''
// 含路径分隔符时取末段(兼容 http(s) URL 与 MinIO 相对键如 crm/contract/.../uuid.pdf)
if (id.includes('/')) {
const seg = (id.split('/').pop() || '').split('?')[0]
try {
return decodeURIComponent(seg) || `附件${index + 1}`
} catch {
return seg || `附件${index + 1}`
}
}
if (id.length > 12) return `附件_${id.substring(0, 8)}`
return id
}
+49 -1
View File
@@ -250,6 +250,27 @@
<h4 class="dlg-view-section-title">关联发票</h4>
<BxAttachmentReadonly :files="viewLinkedInvoiceFiles" />
</div>
<div
v-if="currentRow?.bizType === '报销单' && viewAttachments.length"
class="dlg-view-section"
>
<h4 class="dlg-view-section-title">历史附件</h4>
<BxAttachmentReadonly :files="viewAttachments" />
</div>
<div
v-if="currentRow?.bizType === '报销单' && viewPayAttachments.length"
class="dlg-view-section"
>
<h4 class="dlg-view-section-title">发放附件</h4>
<BxAttachmentReadonly :files="viewPayAttachments" />
</div>
<div
v-if="currentRow?.bizType === '报销单' && viewOffsetAttachments.length"
class="dlg-view-section"
>
<h4 class="dlg-view-section-title">冲抵附件</h4>
<BxAttachmentReadonly :files="viewOffsetAttachments" />
</div>
<BxApprovalFlowTabs
:nodes="viewFlowNodes"
:history="viewApprovalHistory"
@@ -285,7 +306,7 @@ import BxViewKvTable from '@/components/bx/base/BxViewKvTable.vue'
import BxAttachmentReadonly from '@/components/bx/base/BxAttachmentReadonly.vue'
import type { ViewField } from '@/components/business/system-view-dialog/types'
import { bxViewKv, bxViewKvMoney } from '@/utils/bx/view-kv'
import type { BxAttachmentItem } from '@/utils/bx/attachment'
import { type BxAttachmentItem, loadBxAttachments } from '@/utils/bx/attachment'
import { invoicesToLinkedAttachmentFiles } from '@/utils/bx/invoice-link-files'
import { matchesApplyDateRange, type ApplyDateRange } from '@/utils/bx/apply-date-filter'
import { usePagedTable } from '@/hooks/bx/usePagedTable'
@@ -429,6 +450,9 @@ const viewFlowNodes = ref<any[]>([])
const viewApprovalHistory = ref<any[]>([])
const viewFlowLoading = ref(false)
const viewLinkedInvoiceFiles = ref<BxAttachmentItem[]>([])
const viewAttachments = ref<BxAttachmentItem[]>([])
const viewPayAttachments = ref<BxAttachmentItem[]>([])
const viewOffsetAttachments = ref<BxAttachmentItem[]>([])
const bizTypeOptions = ['全部', '报销单', '备用金']
const statusOptions = ['全部', '待提交', '审批中', '审批通过', '审批驳回', '已发放']
@@ -535,6 +559,9 @@ async function openViewDetail(row: any) {
viewFlowNodes.value = []
viewApprovalHistory.value = []
viewLinkedInvoiceFiles.value = []
viewAttachments.value = []
viewPayAttachments.value = []
viewOffsetAttachments.value = []
viewFlowLoading.value = true
dialogs.viewDetail = true
try {
@@ -553,6 +580,27 @@ async function openViewDetail(row: any) {
})
.catch(() => {
viewLinkedInvoiceFiles.value = []
}),
loadBxAttachments('reimburse_apply', row.id)
.then((files) => {
viewAttachments.value = files
})
.catch(() => {
viewAttachments.value = []
}),
loadBxAttachments('reimburse_pay', row.id)
.then((files) => {
viewPayAttachments.value = files
})
.catch(() => {
viewPayAttachments.value = []
}),
loadBxAttachments('reimburse_offset', row.id)
.then((files) => {
viewOffsetAttachments.value = files
})
.catch(() => {
viewOffsetAttachments.value = []
})
)
}
+49 -1
View File
@@ -234,6 +234,27 @@
<h4 class="dlg-view-section-title">关联发票</h4>
<BxAttachmentReadonly :files="viewLinkedInvoiceFiles" />
</div>
<div
v-if="currentRow?.bizType === '报销单' && viewAttachments.length"
class="dlg-view-section"
>
<h4 class="dlg-view-section-title">历史附件</h4>
<BxAttachmentReadonly :files="viewAttachments" />
</div>
<div
v-if="currentRow?.bizType === '报销单' && viewPayAttachments.length"
class="dlg-view-section"
>
<h4 class="dlg-view-section-title">发放附件</h4>
<BxAttachmentReadonly :files="viewPayAttachments" />
</div>
<div
v-if="currentRow?.bizType === '报销单' && viewOffsetAttachments.length"
class="dlg-view-section"
>
<h4 class="dlg-view-section-title">冲抵附件</h4>
<BxAttachmentReadonly :files="viewOffsetAttachments" />
</div>
<BxApprovalFlowTabs
:nodes="viewFlowNodes"
:history="viewApprovalHistory"
@@ -269,7 +290,7 @@ import BxViewKvTable from '@/components/bx/base/BxViewKvTable.vue'
import BxAttachmentReadonly from '@/components/bx/base/BxAttachmentReadonly.vue'
import type { ViewField } from '@/components/business/system-view-dialog/types'
import { bxViewKv, bxViewKvMoney } from '@/utils/bx/view-kv'
import type { BxAttachmentItem } from '@/utils/bx/attachment'
import { type BxAttachmentItem, loadBxAttachments } from '@/utils/bx/attachment'
import { invoicesToLinkedAttachmentFiles } from '@/utils/bx/invoice-link-files'
import { buildApplyDateRangeQuery, matchesApplyDateRange, type ApplyDateRange } from '@/utils/bx/apply-date-filter'
import { usePagedTable } from '@/hooks/bx/usePagedTable'
@@ -379,6 +400,9 @@ const viewFlowNodes = ref<any[]>([])
const viewApprovalHistory = ref<any[]>([])
const viewFlowLoading = ref(false)
const viewLinkedInvoiceFiles = ref<BxAttachmentItem[]>([])
const viewAttachments = ref<BxAttachmentItem[]>([])
const viewPayAttachments = ref<BxAttachmentItem[]>([])
const viewOffsetAttachments = ref<BxAttachmentItem[]>([])
function buildApiQuery() {
const q: Record<string, string> = {}
@@ -493,6 +517,9 @@ async function openViewDetail(row: any) {
viewFlowNodes.value = []
viewApprovalHistory.value = []
viewLinkedInvoiceFiles.value = []
viewAttachments.value = []
viewPayAttachments.value = []
viewOffsetAttachments.value = []
viewFlowLoading.value = true
dialogs.viewDetail = true
try {
@@ -511,6 +538,27 @@ async function openViewDetail(row: any) {
})
.catch(() => {
viewLinkedInvoiceFiles.value = []
}),
loadBxAttachments('reimburse_apply', row.id)
.then((files) => {
viewAttachments.value = files
})
.catch(() => {
viewAttachments.value = []
}),
loadBxAttachments('reimburse_pay', row.id)
.then((files) => {
viewPayAttachments.value = files
})
.catch(() => {
viewPayAttachments.value = []
}),
loadBxAttachments('reimburse_offset', row.id)
.then((files) => {
viewOffsetAttachments.value = files
})
.catch(() => {
viewOffsetAttachments.value = []
})
)
}
+4 -4
View File
@@ -362,7 +362,7 @@
label="付款方式"
align="center"
prop="paymentMethod"
width="120"
min-width="120"
show-overflow-tooltip
/>
<el-table-column v-if="isColumnVisible('partyA')" label="甲方" align="center" prop="partyA" min-width="150" show-overflow-tooltip />
@@ -402,11 +402,11 @@
label="创建部门"
align="center"
prop="createDeptName"
width="120"
min-width="120"
show-overflow-tooltip
/>
<el-table-column v-if="isColumnVisible('createByName')" label="创建人" align="center" prop="createByName" min-width="100" />
<el-table-column v-if="isColumnVisible('createTime')" label="创建时间" align="center" prop="createTime" min-width="140" show-overflow-tooltip>
<el-table-column v-if="isColumnVisible('createTime')" label="创建时间" align="center" prop="createTime" min-width="180" show-overflow-tooltip>
<template #default="scope">
<span>{{ parseTime(scope.row.createTime) }}</span>
</template>
@@ -417,7 +417,7 @@
label="更新时间"
align="center"
prop="updateTime"
min-width="160"
min-width="180"
show-overflow-tooltip
/>
<el-table-column v-if="isColumnVisible('remark')" label="备注" align="center" prop="remark" min-width="200" show-overflow-tooltip />