修复重置功能
This commit is contained in:
parent
303d6d6185
commit
1a0e97011f
437
src/components/ht/HtContractSummary.vue
Normal file
437
src/components/ht/HtContractSummary.vue
Normal file
@ -0,0 +1,437 @@
|
||||
<script setup lang="ts">
|
||||
import { computed, defineComponent, h, onActivated, onMounted, ref, shallowRef, watch, type PropType } from 'vue'
|
||||
import { AgGridVue } from 'ag-grid-vue3'
|
||||
import type { ColDef, GridApi, GridOptions, GridReadyEvent, ICellRendererParams } from 'ag-grid-community'
|
||||
import { AG_GRID_LOCALE_CN } from '@ag-grid-community/locale'
|
||||
import { myTheme, gridOptions } from '@/lib/diyAgGridOptions'
|
||||
import { formatThousands, formatThousandsFlexible } from '@/lib/numberFormat'
|
||||
import { toFiniteNumberOrNull } from '@/lib/number'
|
||||
import { roundTo } from '@/lib/decimal'
|
||||
import { useZxFwPricingStore } from '@/pinia/zxFwPricing'
|
||||
import { additionalWorkList, reserveList } from '@/sql'
|
||||
|
||||
type SummaryRowType = 'service' | 'additional' | 'reserve' | 'total'
|
||||
|
||||
interface SummaryRow {
|
||||
id: string
|
||||
rowType: SummaryRowType
|
||||
code: string | { richText?: Array<{ text?: string; font?: { italic?: boolean; vertAlign?: string } }> }
|
||||
name: string
|
||||
investScale: number | null
|
||||
landScale: number | null
|
||||
workload: number | null
|
||||
hourly: number | null
|
||||
subtotal: number | null
|
||||
finalFee: number | null
|
||||
}
|
||||
|
||||
interface RateMethodStateLike {
|
||||
rate?: unknown
|
||||
budgetFee?: unknown
|
||||
}
|
||||
interface HourlyMethodRowLike {
|
||||
serviceBudget?: unknown
|
||||
adoptedBudgetUnitPrice?: unknown
|
||||
personnelCount?: unknown
|
||||
workdayCount?: unknown
|
||||
}
|
||||
interface HourlyMethodStateLike {
|
||||
detailRows?: HourlyMethodRowLike[]
|
||||
}
|
||||
interface QuantityMethodRowLike {
|
||||
id?: unknown
|
||||
budgetFee?: unknown
|
||||
quantity?: unknown
|
||||
unitPrice?: unknown
|
||||
}
|
||||
interface QuantityMethodStateLike {
|
||||
detailRows?: QuantityMethodRowLike[]
|
||||
}
|
||||
|
||||
const props = defineProps<{
|
||||
contractId: string
|
||||
}>()
|
||||
|
||||
const zxFwPricingStore = useZxFwPricingStore()
|
||||
const gridApi = shallowRef<GridApi<SummaryRow> | null>(null)
|
||||
const rowData = ref<SummaryRow[]>([])
|
||||
const explanationText = ref('')
|
||||
let reloadTimer: ReturnType<typeof setTimeout> | null = null
|
||||
|
||||
const toFinite = (value: unknown): number | null => toFiniteNumberOrNull(value)
|
||||
const sum3 = (values: Array<number | null | undefined>) => {
|
||||
const valid = values.filter((v): v is number => typeof v === 'number' && Number.isFinite(v))
|
||||
if (valid.length === 0) return null
|
||||
return roundTo(valid.reduce((a, b) => a + b, 0), 3)
|
||||
}
|
||||
|
||||
const sumHourlyMethodFee = (state: HourlyMethodStateLike | null): number | null => {
|
||||
const rows = Array.isArray(state?.detailRows) ? state.detailRows : []
|
||||
if (rows.length === 0) return null
|
||||
let total = 0
|
||||
let hasValid = false
|
||||
for (const row of rows) {
|
||||
const rowBudget = toFinite(row?.serviceBudget)
|
||||
if (rowBudget != null) {
|
||||
total += rowBudget
|
||||
hasValid = true
|
||||
continue
|
||||
}
|
||||
const adopted = toFinite(row?.adoptedBudgetUnitPrice)
|
||||
const personnel = toFinite(row?.personnelCount)
|
||||
const workday = toFinite(row?.workdayCount)
|
||||
if (adopted == null || personnel == null || workday == null) continue
|
||||
total += adopted * personnel * workday
|
||||
hasValid = true
|
||||
}
|
||||
return hasValid ? roundTo(total, 3) : null
|
||||
}
|
||||
|
||||
const sumQuantityMethodFee = (state: QuantityMethodStateLike | null): number | null => {
|
||||
const rows = Array.isArray(state?.detailRows) ? state.detailRows : []
|
||||
if (rows.length === 0) return null
|
||||
let total = 0
|
||||
let hasValid = false
|
||||
for (const row of rows) {
|
||||
if (String(row?.id || '') === 'fee-subtotal-fixed') continue
|
||||
const budget = toFinite(row?.budgetFee)
|
||||
if (budget != null) {
|
||||
total += budget
|
||||
hasValid = true
|
||||
continue
|
||||
}
|
||||
const quantity = toFinite(row?.quantity)
|
||||
const unitPrice = toFinite(row?.unitPrice)
|
||||
if (quantity == null || unitPrice == null) continue
|
||||
total += quantity * unitPrice
|
||||
hasValid = true
|
||||
}
|
||||
return hasValid ? roundTo(total, 3) : null
|
||||
}
|
||||
|
||||
const loadHtMethodSummaryByRow = async (mainStorageKey: string, rowId: string): Promise<{
|
||||
subtotal: number | null
|
||||
m0: { coe: string; fee: number } | null
|
||||
m4: { fee: number } | null
|
||||
m5: { fee: number } | null
|
||||
}> => {
|
||||
const [rateState, hourlyState, quantityState] = await Promise.all([
|
||||
zxFwPricingStore.loadHtFeeMethodState<RateMethodStateLike>(mainStorageKey, rowId, 'rate-fee'),
|
||||
zxFwPricingStore.loadHtFeeMethodState<HourlyMethodStateLike>(mainStorageKey, rowId, 'hourly-fee'),
|
||||
zxFwPricingStore.loadHtFeeMethodState<QuantityMethodStateLike>(mainStorageKey, rowId, 'quantity-unit-price-fee')
|
||||
])
|
||||
const rateFee = toFinite(rateState?.budgetFee)
|
||||
const rateValue = toFinite(rateState?.rate)
|
||||
const hourlyFee = sumHourlyMethodFee(hourlyState)
|
||||
const quantityFee = sumQuantityMethodFee(quantityState)
|
||||
const subtotal = sum3([rateFee, hourlyFee, quantityFee])
|
||||
return {
|
||||
subtotal,
|
||||
m0: rateFee != null
|
||||
? {
|
||||
coe: rateValue == null ? '--' : String(rateValue),
|
||||
fee: roundTo(rateFee, 2)
|
||||
}
|
||||
: null,
|
||||
m4: hourlyFee != null ? { fee: roundTo(hourlyFee, 2) } : null,
|
||||
m5: quantityFee != null ? { fee: roundTo(quantityFee, 2) } : null
|
||||
}
|
||||
}
|
||||
|
||||
const buildFeeRows = async (
|
||||
rowType: 'additional' | 'reserve',
|
||||
list: Array<{ id: string | number; name: string; code: unknown }>
|
||||
): Promise<{ rows: SummaryRow[]; explainLines: string[] }> => {
|
||||
const mainStorageKey = `htExtraFee-${props.contractId}-${rowType === 'additional' ? 'additional-work' : 'reserve'}`
|
||||
await zxFwPricingStore.loadHtFeeMainState(mainStorageKey)
|
||||
const tuples = await Promise.all(
|
||||
list.map(async item => {
|
||||
const summary = await loadHtMethodSummaryByRow(mainStorageKey, String(item.id))
|
||||
const lineParts: string[] = []
|
||||
if (summary.m0) {
|
||||
lineParts.push(`按费率${summary.m0.coe}%计得${summary.m0.fee}元`)
|
||||
}
|
||||
if (summary.m4) {
|
||||
lineParts.push(`按工时法计得${summary.m4.fee}元`)
|
||||
}
|
||||
if (summary.m5) {
|
||||
lineParts.push(`按数量单价计得${summary.m5.fee}元`)
|
||||
}
|
||||
const linePrefix = rowType === 'additional' ? '附加工作费' : '预备费'
|
||||
const explainLine = lineParts.length > 0 ? `${linePrefix}-${item.name}:${lineParts.join(';')}` : ''
|
||||
const row: SummaryRow = {
|
||||
id: `${rowType}-${item.id}`,
|
||||
rowType,
|
||||
code: item.code as SummaryRow['code'],
|
||||
name: item.name,
|
||||
investScale: null,
|
||||
landScale: null,
|
||||
workload: null,
|
||||
hourly: null,
|
||||
subtotal: summary.subtotal,
|
||||
finalFee: summary.subtotal
|
||||
}
|
||||
return { row, explainLine }
|
||||
})
|
||||
)
|
||||
const rows = tuples.map(item => item.row).filter(row => row.subtotal != null)
|
||||
const explainLines = tuples
|
||||
.filter(item => item.row.subtotal != null && item.explainLine)
|
||||
.map(item => item.explainLine)
|
||||
return { rows, explainLines }
|
||||
}
|
||||
|
||||
const buildServiceRows = (): SummaryRow[] => {
|
||||
const contractState = zxFwPricingStore.getContractState(props.contractId)
|
||||
const selectedSet = new Set((contractState?.selectedIds || []).map(id => String(id)))
|
||||
const rows = Array.isArray(contractState?.detailRows) ? contractState!.detailRows : []
|
||||
return rows
|
||||
.filter(row => String(row.id) !== 'fixed-budget-c' && selectedSet.has(String(row.id)))
|
||||
.map(row => ({
|
||||
id: `service-${row.id}`,
|
||||
rowType: 'service' as const,
|
||||
code: row.code || '',
|
||||
name: row.name || '',
|
||||
investScale: toFinite(row.investScale),
|
||||
landScale: toFinite(row.landScale),
|
||||
workload: toFinite(row.workload),
|
||||
hourly: toFinite(row.hourly),
|
||||
subtotal: toFinite(row.subtotal),
|
||||
finalFee: toFinite((row as { finalFee?: unknown }).finalFee) ?? toFinite(row.subtotal)
|
||||
}))
|
||||
}
|
||||
|
||||
const reloadRows = async () => {
|
||||
await zxFwPricingStore.loadContract(props.contractId)
|
||||
const [additionalResult, reserveResult] = await Promise.all([
|
||||
buildFeeRows(
|
||||
'additional',
|
||||
additionalWorkList.map(item => ({ id: item.id, name: item.name, code: item.code }))
|
||||
),
|
||||
buildFeeRows(
|
||||
'reserve',
|
||||
reserveList.map(item => ({ id: item.id, name: item.name, code: item.code }))
|
||||
)
|
||||
])
|
||||
rowData.value = [...buildServiceRows(), ...additionalResult.rows, ...reserveResult.rows]
|
||||
const lines = [...additionalResult.explainLines, ...reserveResult.explainLines]
|
||||
explanationText.value = lines.join('\n')
|
||||
}
|
||||
|
||||
const scheduleReload = () => {
|
||||
if (reloadTimer) clearTimeout(reloadTimer)
|
||||
reloadTimer = setTimeout(() => {
|
||||
void reloadRows()
|
||||
}, 80)
|
||||
}
|
||||
|
||||
const refreshSignature = computed(() => {
|
||||
const additionalKey = `htExtraFee-${props.contractId}-additional-work`
|
||||
const reserveKey = `htExtraFee-${props.contractId}-reserve`
|
||||
return JSON.stringify({
|
||||
contract: zxFwPricingStore.contracts[props.contractId] || null,
|
||||
addMain: zxFwPricingStore.htFeeMainStates[additionalKey] || null,
|
||||
reserveMain: zxFwPricingStore.htFeeMainStates[reserveKey] || null,
|
||||
addMethods: zxFwPricingStore.htFeeMethodStates[additionalKey] || null,
|
||||
reserveMethods: zxFwPricingStore.htFeeMethodStates[reserveKey] || null
|
||||
})
|
||||
})
|
||||
|
||||
const totalRow = computed<SummaryRow | null>(() => {
|
||||
if (rowData.value.length === 0) return null
|
||||
const sumField = (pick: (row: SummaryRow) => number | null | undefined) =>
|
||||
sum3(rowData.value.map(pick))
|
||||
return {
|
||||
id: 'summary-total-row',
|
||||
rowType: 'total',
|
||||
code: '',
|
||||
name: '合计',
|
||||
investScale: sumField(row => row.investScale),
|
||||
landScale: sumField(row => row.landScale),
|
||||
workload: sumField(row => row.workload),
|
||||
hourly: sumField(row => row.hourly),
|
||||
subtotal: sumField(row => row.subtotal),
|
||||
finalFee: sumField(row => row.finalFee)
|
||||
}
|
||||
})
|
||||
|
||||
const RichCodeRenderer = defineComponent({
|
||||
name: 'RichCodeRenderer',
|
||||
props: {
|
||||
params: {
|
||||
type: Object as PropType<ICellRendererParams<SummaryRow>>,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
setup(props) {
|
||||
return () => {
|
||||
const value = props.params.value as SummaryRow['code']
|
||||
if (!value || typeof value === 'string') {
|
||||
return h('span', value || '')
|
||||
}
|
||||
const runs = Array.isArray(value.richText) ? value.richText : []
|
||||
return h(
|
||||
'span',
|
||||
{ class: 'inline-flex items-baseline gap-[1px]' },
|
||||
runs.map((run, idx) =>
|
||||
h(
|
||||
'span',
|
||||
{
|
||||
key: `${idx}-${run.text || ''}`,
|
||||
style: {
|
||||
fontStyle: run?.font?.italic ? 'italic' : 'normal',
|
||||
verticalAlign: run?.font?.vertAlign === 'subscript' ? 'sub' : run?.font?.vertAlign === 'superscript' ? 'super' : 'baseline',
|
||||
fontSize: run?.font?.vertAlign ? '0.85em' : '1em'
|
||||
}
|
||||
},
|
||||
run?.text || ''
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
const columnDefs: ColDef<SummaryRow>[] = [
|
||||
{
|
||||
headerName: '编码',
|
||||
field: 'code',
|
||||
minWidth: 90,
|
||||
maxWidth: 140,
|
||||
cellRenderer: RichCodeRenderer
|
||||
},
|
||||
{
|
||||
headerName: '名称',
|
||||
field: 'name',
|
||||
minWidth: 220,
|
||||
flex: 2
|
||||
},
|
||||
{
|
||||
headerName: '投资规模法',
|
||||
field: 'investScale',
|
||||
minWidth: 120,
|
||||
flex: 1.2,
|
||||
headerClass: 'ag-right-aligned-header',
|
||||
cellClass: 'ag-right-aligned-cell',
|
||||
colSpan: params => (params.data && params.data.rowType !== 'service' ? 5 : 1),
|
||||
valueFormatter: params => (params.value == null ? '' : formatThousandsFlexible(params.value, 3))
|
||||
},
|
||||
{
|
||||
headerName: '用地规模法',
|
||||
field: 'landScale',
|
||||
minWidth: 120,
|
||||
flex: 1.2,
|
||||
headerClass: 'ag-right-aligned-header',
|
||||
cellClass: 'ag-right-aligned-cell',
|
||||
valueFormatter: params => (params.value == null ? '' : formatThousandsFlexible(params.value, 3))
|
||||
},
|
||||
{
|
||||
headerName: '工作量法',
|
||||
field: 'workload',
|
||||
minWidth: 110,
|
||||
flex: 1.2,
|
||||
headerClass: 'ag-right-aligned-header',
|
||||
cellClass: 'ag-right-aligned-cell',
|
||||
valueFormatter: params => (params.value == null ? '' : formatThousandsFlexible(params.value, 3))
|
||||
},
|
||||
{
|
||||
headerName: '工时法',
|
||||
field: 'hourly',
|
||||
minWidth: 110,
|
||||
flex: 1.2,
|
||||
headerClass: 'ag-right-aligned-header',
|
||||
cellClass: 'ag-right-aligned-cell',
|
||||
valueFormatter: params => (params.value == null ? '' : formatThousandsFlexible(params.value, 3))
|
||||
},
|
||||
{
|
||||
headerName: '小计',
|
||||
field: 'subtotal',
|
||||
minWidth: 120,
|
||||
flex: 1.2,
|
||||
headerClass: 'ag-right-aligned-header',
|
||||
cellClass: 'ag-right-aligned-cell',
|
||||
valueFormatter: params => (params.value == null ? '' : formatThousands(params.value, 2))
|
||||
},
|
||||
{
|
||||
headerName: '确认金额',
|
||||
field: 'finalFee',
|
||||
minWidth: 120,
|
||||
flex: 1.2,
|
||||
headerClass: 'ag-right-aligned-header',
|
||||
cellClass: 'ag-right-aligned-cell',
|
||||
valueFormatter: params => (params.value == null ? '' : formatThousands(params.value, 2))
|
||||
}
|
||||
]
|
||||
|
||||
const summaryGridOptions: GridOptions<SummaryRow> = {
|
||||
...gridOptions,
|
||||
treeData: false,
|
||||
getDataPath: undefined,
|
||||
domLayout: 'autoHeight',
|
||||
rowSelection: {
|
||||
mode: 'singleRow',
|
||||
checkboxes: false,
|
||||
enableClickSelection: false
|
||||
},
|
||||
getRowId: params => params.data.id,
|
||||
getRowClass: params => (params.data?.rowType === 'additional' || params.data?.rowType === 'reserve' ? 'ht-summary-fee-row' : '')
|
||||
}
|
||||
|
||||
const onGridReady = (event: GridReadyEvent<SummaryRow>) => {
|
||||
gridApi.value = event.api
|
||||
}
|
||||
|
||||
watch(refreshSignature, (next, prev) => {
|
||||
if (next === prev) return
|
||||
scheduleReload()
|
||||
})
|
||||
|
||||
onMounted(() => {
|
||||
void reloadRows()
|
||||
})
|
||||
|
||||
onActivated(() => {
|
||||
void reloadRows()
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="flex flex-col gap-3">
|
||||
<div class="rounded-lg border bg-card xmMx flex flex-col overflow-hidden">
|
||||
<div class="flex items-center justify-between border-b px-3 py-2">
|
||||
<h3 class="text-xs font-semibold text-foreground leading-none">
|
||||
合同段汇总
|
||||
</h3>
|
||||
</div>
|
||||
<div class="ag-theme-quartz w-full" :style="{ minHeight: '120px' }">
|
||||
<AgGridVue
|
||||
:style="{ width: '100%' }"
|
||||
:rowData="rowData"
|
||||
:pinnedBottomRowData="totalRow ? [totalRow] : []"
|
||||
:columnDefs="columnDefs"
|
||||
:gridOptions="summaryGridOptions"
|
||||
:theme="myTheme"
|
||||
:localeText="AG_GRID_LOCALE_CN"
|
||||
@grid-ready="onGridReady"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<form class="rounded-lg border bg-card p-3 space-y-2">
|
||||
<div class="text-xs font-semibold text-foreground">说明</div>
|
||||
<textarea
|
||||
:value="explanationText"
|
||||
rows="3"
|
||||
placeholder="自动生成说明"
|
||||
readonly
|
||||
class="w-full rounded-md border bg-muted/40 px-3 py-2 text-sm text-foreground outline-none"
|
||||
/>
|
||||
</form>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
:deep(.ht-summary-fee-row .ag-cell) {
|
||||
background: color-mix(in oklab, var(--muted) 45%, transparent);
|
||||
}
|
||||
</style>
|
||||
@ -54,7 +54,7 @@ const baseLabel = computed(() =>
|
||||
|
||||
const budgetFee = computed<number | null>(() => {
|
||||
if (baseValue.value == null || rate.value == null) return null
|
||||
return Number((baseValue.value * rate.value).toFixed(3))
|
||||
return Number((baseValue.value * rate.value/100).toFixed(3))
|
||||
})
|
||||
|
||||
const formatAmount = (value: number | null) =>
|
||||
|
||||
@ -317,6 +317,21 @@ const reserveFeeView = markRaw(
|
||||
})
|
||||
);
|
||||
|
||||
const summaryView = markRaw(
|
||||
defineComponent({
|
||||
name: 'HtContractSummaryWithProps',
|
||||
setup() {
|
||||
const AsyncSummary = defineAsyncComponent({
|
||||
loader: () => import('@/components/ht/HtContractSummary.vue'),
|
||||
onError: (err) => {
|
||||
console.error('加载 HtContractSummary 组件失败:', err)
|
||||
}
|
||||
})
|
||||
return () => h(AsyncSummary, { contractId: props.contractId })
|
||||
}
|
||||
})
|
||||
)
|
||||
|
||||
// 4. 给分类数组添加严格类型标注
|
||||
const xmCategories: XmCategoryItem[] = [
|
||||
{ key: 'base-info', label: '基础信息', component: htBaseInfoView },
|
||||
@ -326,7 +341,7 @@ const xmCategories: XmCategoryItem[] = [
|
||||
{ key: 'contract', label: '咨询服务', component: zxfwView },
|
||||
{ key: 'additional-work-fee', label: '附加工作费', component: additionalWorkFeeView },
|
||||
{ key: 'reserve-fee', label: '预备费', component: reserveFeeView },
|
||||
{ key: 'all', label: '汇总', component: reserveFeeView },
|
||||
{ key: 'all', label: '汇总', component: summaryView },
|
||||
|
||||
|
||||
];
|
||||
|
||||
@ -632,7 +632,6 @@ const columnDefs: ColDef<DetailRow>[] = [
|
||||
editable: params => !isFixedRow(params.data),
|
||||
valueGetter: params => {
|
||||
if (!params.data) return null
|
||||
console.log(detailRows.value)
|
||||
return params.data.finalFee
|
||||
},
|
||||
// valueSetter: params => {
|
||||
|
||||
@ -1732,20 +1732,51 @@ const confirmImportOverride = async () => {
|
||||
|
||||
const handleReset = async () => {
|
||||
try {
|
||||
dataMenuOpen.value = false
|
||||
|
||||
// 1) 先清运行时内存态,避免旧状态在清库过程被再次持久化
|
||||
tabStore.resetTabs()
|
||||
zxFwPricingStore.$patch({
|
||||
contracts: {},
|
||||
contractLoaded: {},
|
||||
servicePricingStates: {},
|
||||
htFeeMainStates: {},
|
||||
htFeeMethodStates: {},
|
||||
keyedStates: {}
|
||||
} as any)
|
||||
await kvStore.clear()
|
||||
|
||||
// 2) 清浏览器存储与默认 localforage 数据
|
||||
localStorage.clear()
|
||||
sessionStorage.clear()
|
||||
await localforage.clear()
|
||||
|
||||
// 3) 清 pinia 分库持久化
|
||||
await Promise.all(
|
||||
getPiniaPersistStores().map(async ({ store }) => {
|
||||
await store.clear()
|
||||
})
|
||||
)
|
||||
|
||||
// 4) 清插件按 store 维护的持久化 key(双保险)
|
||||
const clearTasks: Promise<void>[] = []
|
||||
if (tabStore.$clearPersisted) clearTasks.push(tabStore.$clearPersisted())
|
||||
if (zxFwPricingStore.$clearPersisted) clearTasks.push(zxFwPricingStore.$clearPersisted())
|
||||
if (kvStore.$clearPersisted) clearTasks.push(kvStore.$clearPersisted())
|
||||
await Promise.all(clearTasks)
|
||||
|
||||
// 5) 需要保留的引导标记恢复
|
||||
localStorage.setItem(USER_GUIDE_COMPLETED_KEY, '1')
|
||||
|
||||
// 6) 持久化当前“空状态”并刷新页面
|
||||
const persistTasks: Promise<void>[] = []
|
||||
if (tabStore.$persistNow) persistTasks.push(tabStore.$persistNow())
|
||||
if (zxFwPricingStore.$persistNow) persistTasks.push(zxFwPricingStore.$persistNow())
|
||||
if (kvStore.$persistNow) persistTasks.push(kvStore.$persistNow())
|
||||
await Promise.all(persistTasks)
|
||||
window.location.reload()
|
||||
} catch (error) {
|
||||
console.error('reset failed:', error)
|
||||
} finally {
|
||||
tabStore.resetTabs()
|
||||
await tabStore.$persistNow?.()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -10,7 +10,7 @@ import {
|
||||
RowAutoHeightModule,
|
||||
TextEditorModule,
|
||||
TooltipModule,
|
||||
UndoRedoEditModule,RenderApiModule ,ColumnApiModule ,CellSpanModule
|
||||
UndoRedoEditModule,RenderApiModule ,ColumnApiModule ,CellSpanModule ,RowStyleModule ,RowSelectionModule
|
||||
|
||||
} from 'ag-grid-community'
|
||||
import {
|
||||
@ -47,7 +47,7 @@ const AG_GRID_MODULES = [
|
||||
RowGroupingModule,
|
||||
CellSelectionModule,
|
||||
ClipboardModule,
|
||||
LocaleModule,ValidationModule ,CellSpanModule
|
||||
LocaleModule,ValidationModule ,CellSpanModule ,RowStyleModule ,RowSelectionModule
|
||||
]
|
||||
|
||||
const pinia = createPinia()
|
||||
|
||||
@ -635,7 +635,9 @@ export const useZxFwPricingStore = defineStore('zxFwPricing', () => {
|
||||
if (!changed) return false
|
||||
|
||||
const rowsWithSyncedFinalFee = updatedRows.map(row => {
|
||||
if (String(row.id || '') === FIXED_ROW_ID) return row
|
||||
const rowId = String(row.id || '')
|
||||
if (rowId === FIXED_ROW_ID) return row
|
||||
if (rowId !== targetServiceId) return row
|
||||
const rowSubtotal = sumNullableNumbers([
|
||||
toFiniteNumberOrNull(row.investScale),
|
||||
toFiniteNumberOrNull(row.landScale),
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user