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