fix all
This commit is contained in:
parent
badf131dde
commit
9849801e46
@ -5,7 +5,7 @@ import type { ColDef } from 'ag-grid-community'
|
||||
import localforage from 'localforage'
|
||||
import { serviceList, taskList } from '@/sql'
|
||||
import { myTheme, gridOptions } from '@/lib/diyAgGridOptions'
|
||||
import { decimalAggSum, sumByNumber } from '@/lib/decimal'
|
||||
import { decimalAggSum } from '@/lib/decimal'
|
||||
import { usePricingPaneReloadStore } from '@/pinia/pricingPaneReload'
|
||||
|
||||
import { AG_GRID_LOCALE_CN } from '@ag-grid-community/locale';
|
||||
@ -15,6 +15,7 @@ interface DetailRow {
|
||||
taskCode: string
|
||||
taskName: string
|
||||
unit: string
|
||||
conversion: number | null
|
||||
workload: number | null
|
||||
budgetBase: string
|
||||
budgetReferenceUnitPrice: string
|
||||
@ -68,9 +69,11 @@ type taskLite = {
|
||||
name: string
|
||||
basicParam: string
|
||||
unit: string
|
||||
conversion: number | null
|
||||
maxPrice: number | null
|
||||
minPrice: number | null
|
||||
defPrice: number | null
|
||||
desc: string | null
|
||||
}
|
||||
|
||||
const defaultConsultCategoryFactor = computed<number | null>(() => {
|
||||
@ -106,6 +109,7 @@ const buildDefaultRows = (): DetailRow[] => {
|
||||
taskCode: task.code,
|
||||
taskName: task.name,
|
||||
unit: task.unit || '',
|
||||
conversion: typeof task.conversion === 'number' && Number.isFinite(task.conversion) ? task.conversion : null,
|
||||
workload: null,
|
||||
budgetBase: task.basicParam || '',
|
||||
budgetReferenceUnitPrice: formatTaskReferenceUnitPrice(task),
|
||||
@ -113,7 +117,7 @@ const buildDefaultRows = (): DetailRow[] => {
|
||||
typeof task.defPrice === 'number' && Number.isFinite(task.defPrice) ? task.defPrice : null,
|
||||
consultCategoryFactor: defaultConsultCategoryFactor.value,
|
||||
serviceFee: null,
|
||||
remark: '',
|
||||
remark: task.desc|| '',
|
||||
path: [rowId]
|
||||
})
|
||||
}
|
||||
@ -125,6 +129,7 @@ const buildDefaultRows = (): DetailRow[] => {
|
||||
taskCode: '无',
|
||||
taskName: '无',
|
||||
unit: '',
|
||||
conversion: null,
|
||||
workload: null,
|
||||
budgetBase: '无',
|
||||
budgetReferenceUnitPrice: '无',
|
||||
@ -171,6 +176,27 @@ const parseNumberOrNull = (value: unknown) => {
|
||||
return Number.isFinite(v) ? v : null
|
||||
}
|
||||
|
||||
const calcServiceFee = (row: DetailRow | undefined) => {
|
||||
if (!row || isNoTaskRow(row)) return null
|
||||
const price = row.budgetAdoptedUnitPrice
|
||||
const conversion = row.conversion
|
||||
const workload = row.workload
|
||||
const factor = row.consultCategoryFactor
|
||||
if (
|
||||
typeof price !== 'number' ||
|
||||
!Number.isFinite(price) ||
|
||||
typeof conversion !== 'number' ||
|
||||
!Number.isFinite(conversion) ||
|
||||
typeof workload !== 'number' ||
|
||||
!Number.isFinite(workload) ||
|
||||
typeof factor !== 'number' ||
|
||||
!Number.isFinite(factor)
|
||||
) {
|
||||
return null
|
||||
}
|
||||
return price * conversion * workload * factor
|
||||
}
|
||||
|
||||
const formatEditableNumber = (params: any) => {
|
||||
if (isNoTaskRow(params.data)) return '无'
|
||||
if (!params.node?.group && !params.node?.rowPinned && (params.value == null || params.value === '')) {
|
||||
@ -180,52 +206,45 @@ const formatEditableNumber = (params: any) => {
|
||||
return Number(params.value).toFixed(2)
|
||||
}
|
||||
|
||||
const isRepeatedTaskNameRow = (params: any) => {
|
||||
const rowIndex = params.node?.rowIndex
|
||||
if (typeof rowIndex !== 'number' || rowIndex <= 0) return false
|
||||
const prevData = params.api.getDisplayedRowAtIndex(rowIndex - 1)?.data as DetailRow | undefined
|
||||
return prevData?.taskName === params.data?.taskName
|
||||
}
|
||||
const spanRowsByTaskName = (params: any) => {
|
||||
const rowA = params?.nodeA?.data as DetailRow | undefined
|
||||
const rowB = params?.nodeB?.data as DetailRow | undefined
|
||||
// debugger
|
||||
if (!rowA || !rowB) return false
|
||||
if (isNoTaskRow(rowA) || isNoTaskRow(rowB)) return false
|
||||
|
||||
const getTaskNameRowSpan = (params: any) => {
|
||||
if (params.node?.rowPinned) return 1
|
||||
if (isRepeatedTaskNameRow(params)) return 1
|
||||
const currentName = params.data?.taskName
|
||||
if (!currentName) return 1
|
||||
let span = 1
|
||||
let offset = 1
|
||||
while (true) {
|
||||
const nextData = params.api.getDisplayedRowAtIndex((params.node?.rowIndex ?? 0) + offset)?.data as DetailRow | undefined
|
||||
if (!nextData || nextData.taskName !== currentName) break
|
||||
span += 1
|
||||
offset += 1
|
||||
}
|
||||
return span
|
||||
return Boolean(rowA.taskName) && Boolean(rowA.budgetBase) && rowA.taskName === rowB.taskName && rowA.budgetBase === rowB.budgetBase
|
||||
}
|
||||
|
||||
const columnDefs: ColDef<DetailRow>[] = [
|
||||
{
|
||||
headerName: '编码',
|
||||
field: 'taskCode',
|
||||
minWidth: 150,
|
||||
width: 170,
|
||||
minWidth: 100,
|
||||
width: 120,
|
||||
pinned: 'left',
|
||||
valueFormatter: params => params.value || ''
|
||||
},
|
||||
{
|
||||
headerName: '名称',
|
||||
field: 'taskName',
|
||||
minWidth: 220,
|
||||
width: 260,
|
||||
minWidth: 150,
|
||||
width: 220,
|
||||
pinned: 'left',
|
||||
rowSpan: params => getTaskNameRowSpan(params),
|
||||
valueFormatter: params => (isRepeatedTaskNameRow(params) ? '' : params.value || '')
|
||||
autoHeight: true,
|
||||
|
||||
spanRows: true,
|
||||
valueFormatter: params => params.value || ''
|
||||
},
|
||||
{
|
||||
headerName: '预算基数',
|
||||
field: 'budgetBase',
|
||||
minWidth: 170,
|
||||
flex: 1,
|
||||
minWidth: 150,
|
||||
autoHeight: true,
|
||||
|
||||
width: 180,
|
||||
pinned: 'left',
|
||||
spanRows: spanRowsByTaskName,
|
||||
valueFormatter: params => params.value || ''
|
||||
},
|
||||
{
|
||||
@ -300,18 +319,10 @@ const columnDefs: ColDef<DetailRow>[] = [
|
||||
field: 'serviceFee',
|
||||
minWidth: 150,
|
||||
flex: 1,
|
||||
editable: params => !params.node?.group && !params.node?.rowPinned && !isNoTaskRow(params.data),
|
||||
cellClass: params => (!params.node?.group && !params.node?.rowPinned ? 'editable-cell-line' : ''),
|
||||
cellClassRules: {
|
||||
'editable-cell-empty': params =>
|
||||
!params.node?.group &&
|
||||
!params.node?.rowPinned &&
|
||||
!isNoTaskRow(params.data) &&
|
||||
(params.value == null || params.value === '')
|
||||
},
|
||||
editable: false,
|
||||
valueGetter: params => calcServiceFee(params.data),
|
||||
aggFunc: decimalAggSum,
|
||||
valueParser: params => parseNumberOrNull(params.newValue),
|
||||
valueFormatter: formatEditableNumber
|
||||
// valueFormatter: formatEditableNumber
|
||||
},
|
||||
{
|
||||
headerName: '说明',
|
||||
@ -323,10 +334,9 @@ const columnDefs: ColDef<DetailRow>[] = [
|
||||
autoHeight: true,
|
||||
cellStyle: { whiteSpace: 'normal', lineHeight: '1.4' },
|
||||
|
||||
editable: params => !params.node?.group && !params.node?.rowPinned && !isNoTaskRow(params.data),
|
||||
editable: false,
|
||||
valueFormatter: params => {
|
||||
if (isNoTaskRow(params.data)) return '无'
|
||||
if (!params.node?.group && !params.node?.rowPinned && !params.value) return '点击输入'
|
||||
|
||||
return params.value || ''
|
||||
},
|
||||
cellClass: params => (!params.node?.group && !params.node?.rowPinned ? 'editable-cell-line remark-wrap-cell' : ''),
|
||||
@ -340,26 +350,6 @@ const columnDefs: ColDef<DetailRow>[] = [
|
||||
}
|
||||
]
|
||||
|
||||
const totalWorkload = computed(() => sumByNumber(detailRows.value, row => row.workload))
|
||||
|
||||
const totalServiceFee = computed(() => sumByNumber(detailRows.value, row => row.serviceFee))
|
||||
const pinnedTopRowData = computed(() => [
|
||||
{
|
||||
id: 'pinned-total-row',
|
||||
taskCode: '',
|
||||
taskName: '',
|
||||
unit: '',
|
||||
workload: totalWorkload.value,
|
||||
budgetBase: '',
|
||||
budgetReferenceUnitPrice: '',
|
||||
budgetAdoptedUnitPrice: null,
|
||||
consultCategoryFactor: null,
|
||||
serviceFee: totalServiceFee.value,
|
||||
remark: '',
|
||||
path: ['TOTAL']
|
||||
}
|
||||
])
|
||||
|
||||
|
||||
|
||||
const saveToIndexedDB = async () => {
|
||||
@ -441,6 +431,18 @@ const processCellFromClipboard = (params: any) => {
|
||||
}
|
||||
return params.value;
|
||||
};
|
||||
const mydiyTheme = myTheme.withParams({
|
||||
rowBorder: {
|
||||
style: "solid",
|
||||
width: 0.8,
|
||||
color: "#d8d8dd"
|
||||
},
|
||||
columnBorder: {
|
||||
style: "solid",
|
||||
width: 0.8,
|
||||
color: "#d8d8dd"
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@ -454,11 +456,15 @@ const processCellFromClipboard = (params: any) => {
|
||||
</div>
|
||||
|
||||
<div class="ag-theme-quartz h-full min-h-0 w-full flex-1">
|
||||
<AgGridVue :style="{ height: '100%' }" :rowData="detailRows" :pinnedTopRowData="pinnedTopRowData"
|
||||
:columnDefs="columnDefs" :gridOptions="gridOptions" :theme="myTheme" :treeData="false"
|
||||
<AgGridVue :style="{ height: '100%' }" :rowData="detailRows"
|
||||
:columnDefs="columnDefs" :gridOptions="gridOptions" :theme="mydiyTheme" :treeData="false"
|
||||
:enableCellSpan="true"
|
||||
@cell-value-changed="handleCellValueChanged" :suppressColumnVirtualisation="true"
|
||||
:suppressRowVirtualisation="true" :suppressRowTransform="true"
|
||||
:cellSelection="{ handle: { mode: 'range' } }" :enableClipboard="true"
|
||||
:suppressRowVirtualisation="true"
|
||||
|
||||
|
||||
|
||||
:enableClipboard="true"
|
||||
:localeText="AG_GRID_LOCALE_CN" :tooltipShowDelay="500" :headerHeight="50"
|
||||
:processCellForClipboard="processCellForClipboard" :processCellFromClipboard="processCellFromClipboard"
|
||||
:undoRedoCellEditing="true" :undoRedoCellEditingLimit="20" />
|
||||
@ -466,3 +472,6 @@ const processCellFromClipboard = (params: any) => {
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<!-- :rowSelection="'multiple'"
|
||||
:enableClickSelection="false" -->
|
||||
<!-- :suppressRowTransform="true" -->
|
||||
|
||||
@ -15,7 +15,7 @@ export const myTheme = themeQuartz.withParams({
|
||||
wrapperBorder: false,
|
||||
|
||||
// 表头样式(柔和浅蓝,无加粗,更轻盈)
|
||||
headerBackgroundColor: "#f9fafb", // 极浅的背景色,替代深一点的 #e7f3fc
|
||||
headerBackgroundColor: "#f0f2f3", // 极浅的背景色,替代深一点的 #e7f3fc
|
||||
headerTextColor: "#374151", // 深灰色文字,比纯黑更柔和
|
||||
headerFontSize: 15, // 字体稍大一点,更易读
|
||||
headerFontWeight: "normal", // 取消加粗,降低视觉重量
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user