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

+25 -5
View File
@@ -460,12 +460,12 @@
"458": "Community 458",
"459": "Community 459",
"460": "Community 460",
"461": "modal.ts",
"461": "SettingActions.vue",
"462": "Community 462",
"463": "error-handle.ts",
"463": "loadData",
"464": "zh_CN.js",
"465": "index.vue",
"466": "v2.4.2.1 - 2025-06-16",
"466": "index.vue",
"467": "Community 467",
"468": "Community 468",
"469": "Community 469",
@@ -492,14 +492,22 @@
"490": "Community 490",
"491": "Community 491",
"492": "Community 492",
"493": "price-letter-template.ts",
"493": "crm-product-display.ts",
"494": "Community 494",
"495": "colors.ts",
"496": "Community 496",
"497": "saveNodes",
"498": "Community 498",
"499": "Community 499",
"500": "Community 500",
"501": "handleEdit",
"502": "loadTree",
"503": "Community 503",
"504": "fetchData",
"505": "highlight.ts",
"506": "fetchDeptTree",
"507": "Community 507",
"508": "canPreview",
"509": "Community 509",
"510": "Community 510",
"511": "Community 511",
@@ -507,10 +515,18 @@
"513": "Community 513",
"514": "Community 514",
"515": "Community 515",
"516": "ArtException.vue",
"517": "handleDataScope",
"518": "loading.ts",
"519": "expenseItemCode.ts",
"520": "detail.vue",
"521": "Community 521",
"522": "Community 522",
"523": "Community 523",
"524": "Community 524",
"525": "loadUserOptions",
"526": "loadUserOptions",
"527": "v2.4.2.1 - 2025-06-16",
"528": "Community 528",
"529": "Community 529",
"530": "Community 530",
@@ -521,13 +537,18 @@
"535": "Community 535",
"536": "Community 536",
"537": "Community 537",
"538": "fetchUpdateRoleMenus",
"539": "Community 539",
"540": "Community 540",
"541": "Community 541",
"542": "handleAdd",
"543": "Community 543",
"544": "Community 544",
"545": "handleEdit",
"546": "Community 546",
"547": "userOptionLabel",
"548": "Community 548",
"549": "zh_CN.js",
"550": "Community 550",
"551": "Community 551",
"552": "Community 552",
@@ -713,7 +734,6 @@
"764": "新增",
"766": "新增",
"767": "index.js",
"768": "index.ts",
"770": "移除",
"772": "重构",
"773": "重构",
@@ -460,12 +460,9 @@
"458": "Community 458",
"459": "Community 459",
"460": "Community 460",
"461": "modal.ts",
"462": "Community 462",
"463": "error-handle.ts",
"464": "zh_CN.js",
"465": "index.vue",
"466": "v2.4.2.1 - 2025-06-16",
"467": "Community 467",
"468": "Community 468",
"469": "Community 469",
@@ -492,16 +489,12 @@
"490": "Community 490",
"491": "Community 491",
"492": "Community 492",
"493": "price-letter-template.ts",
"494": "Community 494",
"496": "Community 496",
"498": "Community 498",
"499": "Community 499",
"500": "Community 500",
"501": "handleDisburse",
"502": "ViewKvTableCell.vue",
"503": "Community 503",
"506": "loadUserOptions",
"507": "Community 507",
"509": "Community 509",
"510": "Community 510",
@@ -510,7 +503,6 @@
"513": "Community 513",
"514": "Community 514",
"515": "Community 515",
"516": "zh_CN.js",
"521": "Community 521",
"522": "Community 522",
"523": "Community 523",
@@ -717,7 +709,6 @@
"764": "新增",
"766": "新增",
"767": "index.js",
"768": "index.ts",
"770": "移除",
"772": "重构",
"773": "重构",
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
+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 />