This commit is contained in:
wintsa 2026-03-17 16:24:25 +08:00
parent 2b18fe9991
commit 69e5f166e1
20 changed files with 70 additions and 65 deletions

View File

@ -9,7 +9,9 @@
"Bash(rmdir views/pricingView common)",
"Bash(cd:*)",
"Bash(bun run:*)",
"Bash(grep:*)"
"Bash(grep:*)",
"mcp__context7__resolve-library-id",
"mcp__context7__query-docs"
]
}
}

View File

@ -10,7 +10,7 @@ const props = defineProps<{
const STORAGE_KEY = computed(() => `htExtraFee-${props.contractId}-additional-work`)
const additionalWorkNames = computed(() =>
additionalWorkList.map(item => String(item?.name || '').trim()).filter(Boolean)
additionalWorkList.map(item => ({id:item?.id,name:item?.name}))
)
</script>

View File

@ -10,7 +10,7 @@ const props = defineProps<{
const STORAGE_KEY = computed(() => `htExtraFee-${props.contractId}-reserve`)
const reserveFeeNames = computed(() =>
reserveList.map(item => String(item?.name || '').trim()).filter(Boolean)
reserveList.map(item => ({name:item.name,id:item.id}))
)
</script>

View File

@ -3,7 +3,7 @@ import { computed, defineComponent, h, nextTick, onActivated, onBeforeUnmount, o
import type { ComponentPublicInstance, PropType } from 'vue'
import { AgGridVue } from 'ag-grid-vue3'
import type { ColDef, GridOptions, ICellRendererParams } from 'ag-grid-community'
import { myTheme, gridOptions } from '@/lib/diyAgGridOptions'
import { myTheme, gridOptions, agGridWrapClass, agGridStyle } from '@/lib/diyAgGridOptions'
import { AG_GRID_LOCALE_CN } from '@ag-grid-community/locale'
import { addNumbers } from '@/lib/decimal'
import { parseNumberOrNull } from '@/lib/number'
@ -1150,8 +1150,8 @@ onBeforeUnmount(() => {
<div class="text-[11px] text-muted-foreground leading-none">按服务词典生成</div>
</div>
<div class="ag-theme-quartz w-full flex-1 min-h-0">
<AgGridVue :style="{ height: '100%' }" :rowData="detailRows" :columnDefs="columnDefs"
<div :class="agGridWrapClass">
<AgGridVue :style="agGridStyle" :rowData="detailRows" :columnDefs="columnDefs"
:gridOptions="detailGridOptions" :theme="myTheme" @cell-value-changed="handleCellValueChanged"
:enableClipboard="true" :localeText="AG_GRID_LOCALE_CN" :tooltipShowDelay="500" :headerHeight="30"
:undoRedoCellEditing="true" :undoRedoCellEditingLimit="20" />

View File

@ -3,7 +3,7 @@ import { computed, onActivated, onBeforeUnmount, onMounted, ref } from 'vue'
import { AgGridVue } from 'ag-grid-vue3'
import type { ColDef, ColGroupDef } from 'ag-grid-community'
import { getMajorDictEntries, getServiceDictItemById, industryTypeList, isMajorIdInIndustryScope } from '@/sql'
import { myTheme, gridOptions } from '@/lib/diyAgGridOptions'
import { myTheme, gridOptions, agGridWrapClass, agGridStyle } from '@/lib/diyAgGridOptions'
import { addNumbers, decimalAggSum, roundTo, sumByNumber } from '@/lib/decimal'
import { formatThousandsFlexible } from '@/lib/numberFormat'
import { syncPricingTotalToZxFw } from '@/lib/zxFwPricingSync'
@ -1365,8 +1365,8 @@ const processCellFromClipboard = (params: any) => {
</div>
</div>
<div class="ag-theme-quartz h-full min-h-0 w-full flex-1">
<AgGridVue :style="{ height: '100%' }" :rowData="detailRows" :pinnedTopRowData="pinnedTopRowData"
<div :class="agGridWrapClass">
<AgGridVue :style="agGridStyle" :rowData="detailRows" :pinnedTopRowData="pinnedTopRowData"
:columnDefs="columnDefs" :autoGroupColumnDef="autoGroupColumnDef" :gridOptions="gridOptions" :theme="myTheme"
@cell-value-changed="handleCellValueChanged" :suppressColumnVirtualisation="true"
:suppressRowVirtualisation="true" :cellSelection="{ handle: { mode: 'range' } }" :enableClipboard="true"

View File

@ -3,7 +3,7 @@ import { computed, onActivated, onBeforeUnmount, onMounted, ref } from 'vue'
import { AgGridVue } from 'ag-grid-vue3'
import type { ColDef, ColGroupDef } from 'ag-grid-community'
import { getMajorDictEntries, getServiceDictItemById, industryTypeList, isMajorIdInIndustryScope } from '@/sql'
import { myTheme, gridOptions } from '@/lib/diyAgGridOptions'
import { myTheme, gridOptions, agGridWrapClass, agGridStyle } from '@/lib/diyAgGridOptions'
import { addNumbers, decimalAggSum, roundTo, sumByNumber } from '@/lib/decimal'
import { formatThousandsFlexible } from '@/lib/numberFormat'
import { syncPricingTotalToZxFw } from '@/lib/zxFwPricingSync'
@ -1194,8 +1194,8 @@ const processCellFromClipboard = (params: any) => {
</div>
</div>
<div class="ag-theme-quartz h-full min-h-0 w-full flex-1">
<AgGridVue :style="{ height: '100%' }" :rowData="detailRows" :pinnedTopRowData="pinnedTopRowData"
<div :class="agGridWrapClass">
<AgGridVue :style="agGridStyle" :rowData="detailRows" :pinnedTopRowData="pinnedTopRowData"
:columnDefs="columnDefs" :autoGroupColumnDef="autoGroupColumnDef" :gridOptions="gridOptions" :theme="myTheme"
@cell-value-changed="handleCellValueChanged" :suppressColumnVirtualisation="true"
:suppressRowVirtualisation="true" :cellSelection="{ handle: { mode: 'range' } }" :enableClipboard="true"

View File

@ -3,7 +3,7 @@ import { computed, onBeforeUnmount, onMounted, ref } from 'vue'
import { AgGridVue } from 'ag-grid-vue3'
import type { ColDef } from 'ag-grid-community'
import { taskList } from '@/sql'
import { myTheme, gridOptions } from '@/lib/diyAgGridOptions'
import { myTheme, gridOptions, agGridWrapClass, agGridStyle } from '@/lib/diyAgGridOptions'
import { decimalAggSum, roundTo, sumByNumber, toDecimal } from '@/lib/decimal'
import { formatThousands, formatThousandsFlexible } from '@/lib/numberFormat'
import { parseNumberOrNull } from '@/lib/number'
@ -537,8 +537,8 @@ const mydiyTheme = myTheme.withParams({
<div class="text-xs text-muted-foreground"></div>
</div>
<div v-if="isWorkloadMethodApplicable" class="ag-theme-quartz h-full min-h-0 w-full flex-1">
<AgGridVue :style="{ height: '100%' }" :rowData="detailRows" :pinnedTopRowData="pinnedTopRowData"
<div v-if="isWorkloadMethodApplicable" :class="agGridWrapClass">
<AgGridVue :style="agGridStyle" :rowData="detailRows" :pinnedTopRowData="pinnedTopRowData"
:columnDefs="columnDefs" :gridOptions="gridOptions" :theme="mydiyTheme" :treeData="false"
:enableCellSpan="true"
@cell-value-changed="handleCellValueChanged" :suppressColumnVirtualisation="true"

View File

@ -3,7 +3,7 @@ import { computed, onActivated, onBeforeUnmount, onDeactivated, onMounted, ref,
import { AgGridVue } from 'ag-grid-vue3'
import type { ColDef, ColGroupDef, GridApi, GridReadyEvent } from 'ag-grid-community'
import { expertList } from '@/sql'
import { myTheme, gridOptions } from '@/lib/diyAgGridOptions'
import { myTheme, gridOptions, agGridWrapClass, agGridStyle } from '@/lib/diyAgGridOptions'
import { decimalAggSum, roundTo, sumByNumber, toDecimal } from '@/lib/decimal'
import { formatThousandsFlexible } from '@/lib/numberFormat'
import { parseNumberOrNull } from '@/lib/number'
@ -576,9 +576,9 @@ onBeforeUnmount(() => {
<div class="text-xs text-muted-foreground"></div>
</div>
<div class="ag-theme-quartz h-full min-h-0 w-full flex-1">
<div :class="agGridWrapClass">
<AgGridVue
:style="{ height: '100%' }"
:style="agGridStyle"
:rowData="detailRows"
:pinnedTopRowData="pinnedTopRowData"
:columnDefs="columnDefs"

View File

@ -3,7 +3,7 @@ import { computed, defineComponent, h, onActivated, onBeforeUnmount, onMounted,
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 { myTheme, gridOptions, agGridWrapClass, agGridStyle } from '@/lib/diyAgGridOptions'
import { parseNumberOrNull } from '@/lib/number'
import { formatThousandsFlexible } from '@/lib/numberFormat'
import { roundTo, toDecimal } from '@/lib/decimal'
@ -443,9 +443,9 @@ onBeforeUnmount(() => {
<Button type="button" variant="outline" size="sm" @click="addRow">添加行</Button>
</div>
<div class="ag-theme-quartz h-full min-h-0 w-full flex-1">
<div :class="agGridWrapClass">
<AgGridVue
:style="{ height: '100%' }"
:style="agGridStyle"
:rowData="detailRows"
:columnDefs="columnDefs"
:gridOptions="detailGridOptions"

View File

@ -3,7 +3,7 @@ import { computed, defineComponent, h, nextTick, onActivated, onBeforeUnmount, o
import { AgGridVue } from 'ag-grid-vue3'
import type { CellValueChangedEvent, 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 { myTheme, gridOptions, agGridWrapClass, agGridStyle } from '@/lib/diyAgGridOptions'
import { parseNumberOrNull } from '@/lib/number'
import { formatThousandsFlexible } from '@/lib/numberFormat'
import { Pencil, Eraser } from 'lucide-vue-next'
@ -75,11 +75,10 @@ const props = defineProps<{
storageKey: string
contractId?: string
contractName?: string
fixedNames?: string[]
fixedNames?: any[]
}>()
const tabStore = useTabStore()
const zxFwPricingStore = useZxFwPricingStore()
const createRowId = () => `fee-method-${Date.now()}-${Math.random().toString(16).slice(2, 8)}`
const createDefaultRow = (name = ''): FeeMethodRow => ({
id: createRowId(),
@ -89,6 +88,7 @@ const createDefaultRow = (name = ''): FeeMethodRow => ({
quantityUnitPriceFee: null
})
const SUMMARY_ROW_ID = 'fee-method-summary'
const isSummaryRow = (row: FeeMethodRow | null | undefined) => row?.id === SUMMARY_ROW_ID
const toFinite = (value: number | null | undefined) =>
typeof value === 'number' && Number.isFinite(value) ? value : 0
@ -240,7 +240,7 @@ const hydrateRowsFromMethodStores = async (rows: FeeMethodRow[]): Promise<FeeMet
const fixedNames = computed(() =>
Array.isArray(props.fixedNames)
? props.fixedNames.map(item => String(item || '').trim()).filter(Boolean)
? props.fixedNames.map(item => ({name:item.name,id:item.id}))
: []
)
const hasFixedNames = computed(() => fixedNames.value.length > 0)
@ -328,12 +328,12 @@ const toLegacyQuantityUnitPriceFee = (row: LegacyFeeRow) => {
}
const mergeWithStoredRows = (rowsFromDb: unknown): FeeMethodRow[] => {
const sourceRows = (Array.isArray(rowsFromDb) ? rowsFromDb : []).filter(
item => (item as Partial<FeeMethodRow>)?.id !== SUMMARY_ROW_ID
)
const rows = sourceRows.map(item => {
const row = item as Partial<FeeMethodRow> & LegacyFeeRow
return {
id: typeof row.id === 'string' && row.id ? row.id : createRowId(),
name:
@ -349,13 +349,15 @@ const mergeWithStoredRows = (rowsFromDb: unknown): FeeMethodRow[] => {
: toLegacyQuantityUnitPriceFee(row)
} as FeeMethodRow
})
if (hasFixedNames.value) {
const byName = new Map(rows.map(row => [row.name, row]))
return fixedNames.value.map((name, index) => {
const fromDb = byName.get(name)
return fixedNames.value.map((item, index) => {
const fromDb = byName.get(item.name)
return {
id: fromDb?.id || `fee-method-fixed-${index}`,
name,
id: item?.id || `fee-method-fixed-${index}`,
name:item.name,
rateFee: fromDb?.rateFee ?? null,
hourlyFee: fromDb?.hourlyFee ?? null,
quantityUnitPriceFee: fromDb?.quantityUnitPriceFee ?? null
@ -384,7 +386,6 @@ const saveToIndexedDB = async (force = false) => {
const loadFromIndexedDB = async () => {
try {
const data = await zxFwPricingStore.loadHtFeeMainState<FeeMethodRow>(props.storageKey)
const mergedRows = mergeWithStoredRows(data?.detailRows)
detailRows.value = await hydrateRowsFromMethodStores(mergedRows)
await saveToIndexedDB(true)
@ -423,6 +424,7 @@ const clearRow = async (id: string) => {
const editRow = (id: string) => {
const row = detailRows.value.find(item => item.id === id)
if (!row) return
console.log(id)
tabStore.openTab({
id: `ht-fee-edit-${props.storageKey}-${id}`,
title: `费用编辑-${row.name || '未命名'}`,
@ -694,9 +696,9 @@ onBeforeUnmount(() => {
<Button v-if="!hasFixedNames" type="button" variant="outline" size="sm" @click="addRow">新增</Button>
</div>
<div class="ag-theme-quartz h-full min-h-0 w-full flex-1">
<div :class="agGridWrapClass">
<AgGridVue
:style="{ height: '100%' }"
:style="agGridStyle"
:rowData="displayRows"
:columnDefs="columnDefs"
:gridOptions="detailGridOptions"

View File

@ -11,7 +11,7 @@ import type {
} from 'ag-grid-community'
import { AG_GRID_LOCALE_CN } from '@ag-grid-community/locale'
import { Button } from '@/components/ui/button'
import { myTheme } from '@/lib/diyAgGridOptions'
import { myTheme, agGridStyle } from '@/lib/diyAgGridOptions'
import { workList } from '@/sql'
import type { WorkType } from '@/sql'
import { useZxFwPricingStore } from '@/pinia/zxFwPricing'
@ -66,7 +66,7 @@ const buildDefaultRowsFromDict = (): WorkContentRow[] => {
const sid = Number(props.serviceId)
filtered = entries.filter(e => e.serviceid === sid)
} else if (props.dictMode === 'additional') {
filtered = entries.filter(e => e.serviceid === -1)
filtered = entries.filter(e => e.serviceid === -1 && props.storageKey.split('-').at(-1) =='2')
} else {
return []
}
@ -188,7 +188,13 @@ const columnDefs: ColDef<WorkContentRow>[] = [
flex: 2,
editable: params => Boolean(params.data?.custom),
cellClass: params => (params.data?.custom ? 'editable-cell-line' : ''),
cellClassRules: {
'editable-cell-empty': params => Boolean(params.data?.custom) && (params.value == null || params.value === '')
},
valueParser: params => String(params.newValue || '').trim(),
wrapText: true,
autoHeight: true,
cellStyle: { whiteSpace: 'normal', lineHeight: '1.5' },
cellRenderer: contentCellRenderer
},
{
@ -267,7 +273,7 @@ onBeforeUnmount(() => {
</div>
<div class="ag-theme-quartz h-[calc(100%-56px)] min-h-0 w-full">
<AgGridVue
:style="{ height: '100%' }"
:style="agGridStyle"
:rowData="rowData"
:columnDefs="columnDefs"
:theme="myTheme"
@ -300,16 +306,15 @@ onBeforeUnmount(() => {
display: flex;
width: 100%;
align-items: center;
justify-content: space-between;
gap: 8px;
}
:deep(.work-content-text) {
min-width: 0;
flex: 1;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
white-space: normal;
word-break: break-word;
line-height: 1.5;
}
:deep(.work-content-check) {

View File

@ -2,7 +2,7 @@
import { onBeforeUnmount, onMounted, ref, watch } from 'vue'
import { AgGridVue } from 'ag-grid-vue3'
import type { ColDef, FirstDataRenderedEvent, GridApi, GridReadyEvent, GridSizeChangedEvent } from 'ag-grid-community'
import { myTheme, gridOptions } from '@/lib/diyAgGridOptions'
import { myTheme, gridOptions, agGridWrapClass, agGridStyle } from '@/lib/diyAgGridOptions'
import { parseNumberOrNull } from '@/lib/number'
import { AG_GRID_LOCALE_CN } from '@ag-grid-community/locale'
import { useKvStore } from '@/pinia/kv'
@ -325,9 +325,9 @@ onBeforeUnmount(() => {
<div class="text-xs text-muted-foreground"></div>
</div>
<div class="ag-theme-quartz h-full min-h-0 w-full flex-1">
<div :class="agGridWrapClass">
<AgGridVue
:style="{ height: '100%' }"
:style="agGridStyle"
:rowData="detailRows"
:columnDefs="columnDefs"
:autoGroupColumnDef="autoGroupColumnDef"

View File

@ -3,7 +3,7 @@ import { computed, onActivated, onBeforeUnmount, onMounted, ref, watch } from 'v
import { AgGridVue } from 'ag-grid-vue3'
import type { CellValueChangedEvent, ColDef, GridApi, GridReadyEvent } from 'ag-grid-community'
import { AG_GRID_LOCALE_CN } from '@ag-grid-community/locale'
import { myTheme, gridOptions } from '@/lib/diyAgGridOptions'
import { myTheme, gridOptions, agGridWrapClass, agGridStyle } from '@/lib/diyAgGridOptions'
import { decimalAggSum, roundTo, sumByNumber } from '@/lib/decimal'
import { formatThousandsFlexible } from '@/lib/numberFormat'
import { industryTypeList, getMajorDictEntries, isMajorIdInIndustryScope } from '@/sql'
@ -626,8 +626,8 @@ onMounted(() => {
</div>
</div>
<div class="ag-theme-quartz w-full flex-1 min-h-0 h-full">
<AgGridVue :style="{ height: '100%' }" :rowData="visibleRowData" :pinnedTopRowData="pinnedTopRowData"
<div :class="agGridWrapClass">
<AgGridVue :style="agGridStyle" :rowData="visibleRowData" :pinnedTopRowData="pinnedTopRowData"
:columnDefs="columnDefs" :autoGroupColumnDef="autoGroupColumnDef" :gridOptions="gridOptions" :theme="myTheme"
@grid-ready="onGridReady" @cell-value-changed="onCellValueChanged" :suppressColumnVirtualisation="true"
:suppressRowVirtualisation="true" :cellSelection="{ handle: { mode: 'range' } }" :enableClipboard="true"

View File

@ -31,7 +31,6 @@ const props = defineProps<{
contractId?: string
contractName?: string
}>()
const sourceTitleText = computed(() => props.sourceTitle || '费用明细')
const rowNameText = computed(() => props.rowName || '未命名')
const contractIdText = computed(() => String(props.contractId || '').trim())
@ -92,11 +91,9 @@ const hourlyFeePane = markRaw(
})
)
const isAdditionalWork = computed(() => props.sourceTitle === '附加工作费')
const isReserveFee = computed(() => props.sourceTitle === '预备费')
const showWorkContent = computed(() => {
if (isReserveFee.value) return false
if (isAdditionalWork.value) return props.rowName === '咨询服务协调工作'
return true
})
@ -110,11 +107,10 @@ const workContentPane = markRaw(
console.error('加载 WorkContentGrid 组件失败:', err)
}
})
return () => h(AsyncWorkContentGrid, {
title: '工作内容',
storageKey: `work-content-${props.storageKey}-${props.rowId}`,
dictMode: isAdditionalWork.value ? 'additional' : 'none'
dictMode: 'additional'
})
}
})

View File

@ -23,7 +23,7 @@ import {
} from 'reka-ui'
import { decodeZwArchive, encodeZwArchive, ZW_FILE_EXTENSION } from '@/lib/zwArchive'
import { addNumbers, roundTo } from '@/lib/decimal'
import { exportFile, serviceList, additionalWorkList } from '@/sql'
import { exportFile, serviceList } from '@/sql'
interface DataEntry {
key: string
@ -1290,12 +1290,7 @@ const loadHtFeeMethodsByRow = async (mainStorageKey: string, rowId: string) => {
}
}
const buildAdditionalDetailCode = (index: number, name: string): unknown => {
const dictionaryIndex = additionalWorkList.findIndex((item:any) => item === name)
const useIndex = dictionaryIndex >= 0 ? dictionaryIndex : index
const suffix = useIndex === 0 ? 'F' : useIndex === 1 ? 'X' : String(useIndex + 1)
return createRichTextCode('C', suffix)
}
const buildAdditionalExport = async (contractId: string): Promise<ExportAdditional | null> => {
const storageKey = `htExtraFee-${contractId}-additional-work`

View File

@ -75,10 +75,7 @@ const activeComponent = computed(() => {
const copyBtnText = ref('复制')
const sheetOpen = ref(false)
const titleRef = ref<HTMLElement | null>(null)
const isTitleOverflow = ref(false)
const subtitleRef = ref<HTMLElement | null>(null)
const isSubtitleOverflow = ref(false)
let copyBtnTimer: ReturnType<typeof setTimeout> | null = null
let titleOverflowRafId: number | null = null

View File

@ -20,6 +20,12 @@ export const myTheme = themeQuartz.withParams({
dataBackgroundColor: '#fefefe'
})
// AG Grid 容器通用 class占满父容器配合父元素为 flex/grid 且有明确高度使用)
export const agGridWrapClass = 'ag-theme-quartz h-full min-h-0 w-full flex-1'
// AG Grid 组件通用 style撑满容器 div
export const agGridStyle = { height: '100%' }
export const gridOptions: GridOptions = {
treeData: true,
animateRows: true,

View File

@ -152,7 +152,7 @@ export const expertList = {
};
export const additionalWorkList = [
{
{ id:'1',
code: {
richText: [
{ font: { charset: 134, color: { theme: 1 }, italic: true, name: '宋体', size: 10 }, text: 'C' },
@ -161,7 +161,7 @@ export const additionalWorkList = [
},
name: '人员驻场服务及其他附加工作'
},
{
{id:'2',
code: {
richText: [
{ font: { charset: 134, color: { theme: 1 }, italic: true, name: '宋体', size: 10 }, text: 'C' },
@ -174,6 +174,7 @@ export const additionalWorkList = [
export const reserveList = [
{
id:1,
code: {
richText: [
{ font: { charset: 134, color: { theme: 1 }, italic: true, name: '宋体', size: 10 }, text: 'Y' },

View File

@ -295,6 +295,7 @@ html {
color: #94a3b8 !important;
font-style: italic;
opacity: 1 !important;
border-bottom: none !important;
}
.xmMx .ag-cell.editable-cell-empty,

View File

@ -1 +1 @@
{"root":["./src/main.ts","./src/sql.ts","./src/components/ui/button/index.ts","./src/components/ui/card/index.ts","./src/components/ui/scroll-area/index.ts","./src/components/ui/tooltip/index.ts","./src/lib/decimal.ts","./src/lib/diyaggridoptions.ts","./src/lib/number.ts","./src/lib/numberformat.ts","./src/lib/pricingmethodtotals.ts","./src/lib/pricingscalefee.ts","./src/lib/projectworkspace.ts","./src/lib/utils.ts","./src/lib/workspace.ts","./src/lib/xmfactordefaults.ts","./src/lib/zwarchive.ts","./src/lib/zxfwpricingsync.ts","./src/pinia/kv.ts","./src/pinia/tab.ts","./src/pinia/zxfwpricing.ts","./src/pinia/plugin/indexdb.ts","./src/pinia/plugin/types.d.ts","./src/app.vue","./src/components/common/hourlyfeegrid.vue","./src/components/common/htfeegrid.vue","./src/components/common/htfeemethodgrid.vue","./src/components/common/methodunavailablenotice.vue","./src/components/common/xmfactorgrid.vue","./src/components/common/xmcommonaggrid.vue","./src/components/ui/button/button.vue","./src/components/ui/card/card.vue","./src/components/ui/card/cardaction.vue","./src/components/ui/card/cardcontent.vue","./src/components/ui/card/carddescription.vue","./src/components/ui/card/cardfooter.vue","./src/components/ui/card/cardheader.vue","./src/components/ui/card/cardtitle.vue","./src/components/ui/scroll-area/scrollarea.vue","./src/components/ui/scroll-area/scrollbar.vue","./src/components/ui/tooltip/tooltipcontent.vue","./src/components/views/homeentryview.vue","./src/components/views/ht.vue","./src/components/views/htadditionalworkfee.vue","./src/components/views/htconsultcategoryfactor.vue","./src/components/views/htfeemethodtypelineview.vue","./src/components/views/htfeeratemethodform.vue","./src/components/views/htmajorfactor.vue","./src/components/views/htreservefee.vue","./src/components/views/projectworkspaceview.vue","./src/components/views/quickcalcview.vue","./src/components/views/servicecheckboxselector.vue","./src/components/views/workcontentgrid.vue","./src/components/views/xmconsultcategoryfactor.vue","./src/components/views/xmmajorfactor.vue","./src/components/views/zxfwview.vue","./src/components/views/htcard.vue","./src/components/views/htinfo.vue","./src/components/views/info.vue","./src/components/views/xmcard.vue","./src/components/views/xminfo.vue","./src/components/views/zxfw.vue","./src/components/views/pricingview/hourlypricingpane.vue","./src/components/views/pricingview/investmentscalepricingpane.vue","./src/components/views/pricingview/landscalepricingpane.vue","./src/components/views/pricingview/workloadpricingpane.vue","./src/layout/tab.vue","./src/layout/typeline.vue"],"version":"5.9.3"}
{"root":["./src/main.ts","./src/sql.ts","./src/components/ui/button/index.ts","./src/components/ui/card/index.ts","./src/components/ui/scroll-area/index.ts","./src/components/ui/tooltip/index.ts","./src/lib/decimal.ts","./src/lib/diyaggridoptions.ts","./src/lib/number.ts","./src/lib/numberformat.ts","./src/lib/pricingmethodtotals.ts","./src/lib/pricingscalefee.ts","./src/lib/projectworkspace.ts","./src/lib/utils.ts","./src/lib/workspace.ts","./src/lib/xmfactordefaults.ts","./src/lib/zwarchive.ts","./src/lib/zxfwpricingsync.ts","./src/pinia/kv.ts","./src/pinia/tab.ts","./src/pinia/zxfwpricing.ts","./src/pinia/plugin/indexdb.ts","./src/pinia/plugin/types.d.ts","./src/app.vue","./src/components/ht/ht.vue","./src/components/ht/htadditionalworkfee.vue","./src/components/ht/htconsultcategoryfactor.vue","./src/components/ht/htfeeratemethodform.vue","./src/components/ht/htmajorfactor.vue","./src/components/ht/htreservefee.vue","./src/components/ht/htcard.vue","./src/components/ht/htinfo.vue","./src/components/ht/zxfw.vue","./src/components/pricing/hourlypricingpane.vue","./src/components/pricing/investmentscalepricingpane.vue","./src/components/pricing/landscalepricingpane.vue","./src/components/pricing/workloadpricingpane.vue","./src/components/shared/hourlyfeegrid.vue","./src/components/shared/htfeegrid.vue","./src/components/shared/htfeemethodgrid.vue","./src/components/shared/methodunavailablenotice.vue","./src/components/shared/servicecheckboxselector.vue","./src/components/shared/workcontentgrid.vue","./src/components/shared/xmfactorgrid.vue","./src/components/shared/xmcommonaggrid.vue","./src/components/ui/button/button.vue","./src/components/ui/card/card.vue","./src/components/ui/card/cardaction.vue","./src/components/ui/card/cardcontent.vue","./src/components/ui/card/carddescription.vue","./src/components/ui/card/cardfooter.vue","./src/components/ui/card/cardheader.vue","./src/components/ui/card/cardtitle.vue","./src/components/ui/scroll-area/scrollarea.vue","./src/components/ui/scroll-area/scrollbar.vue","./src/components/ui/tooltip/tooltipcontent.vue","./src/components/views/homeentryview.vue","./src/components/views/htfeemethodtypelineview.vue","./src/components/views/projectworkspaceview.vue","./src/components/views/quickcalcview.vue","./src/components/views/zxfwview.vue","./src/components/xm/xmconsultcategoryfactor.vue","./src/components/xm/xmmajorfactor.vue","./src/components/xm/info.vue","./src/components/xm/xmcard.vue","./src/components/xm/xminfo.vue","./src/layout/tab.vue","./src/layout/typeline.vue"],"version":"5.9.3"}