Compare commits
2 Commits
d68579b643
...
63ebc3f26a
| Author | SHA1 | Date | |
|---|---|---|---|
| 63ebc3f26a | |||
| 69e5f166e1 |
@ -9,7 +9,9 @@
|
|||||||
"Bash(rmdir views/pricingView common)",
|
"Bash(rmdir views/pricingView common)",
|
||||||
"Bash(cd:*)",
|
"Bash(cd:*)",
|
||||||
"Bash(bun run:*)",
|
"Bash(bun run:*)",
|
||||||
"Bash(grep:*)"
|
"Bash(grep:*)",
|
||||||
|
"mcp__context7__resolve-library-id",
|
||||||
|
"mcp__context7__query-docs"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -10,7 +10,7 @@ const props = defineProps<{
|
|||||||
|
|
||||||
const STORAGE_KEY = computed(() => `htExtraFee-${props.contractId}-additional-work`)
|
const STORAGE_KEY = computed(() => `htExtraFee-${props.contractId}-additional-work`)
|
||||||
const additionalWorkNames = computed(() =>
|
const additionalWorkNames = computed(() =>
|
||||||
additionalWorkList.map(item => String(item?.name || '').trim()).filter(Boolean)
|
additionalWorkList.map(item => ({id:item?.id,name:item?.name}))
|
||||||
)
|
)
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@ -10,7 +10,7 @@ const props = defineProps<{
|
|||||||
|
|
||||||
const STORAGE_KEY = computed(() => `htExtraFee-${props.contractId}-reserve`)
|
const STORAGE_KEY = computed(() => `htExtraFee-${props.contractId}-reserve`)
|
||||||
const reserveFeeNames = computed(() =>
|
const reserveFeeNames = computed(() =>
|
||||||
reserveList.map(item => String(item?.name || '').trim()).filter(Boolean)
|
reserveList.map(item => ({name:item.name,id:item.id}))
|
||||||
)
|
)
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@ -3,7 +3,7 @@ import { computed, defineComponent, h, nextTick, onActivated, onBeforeUnmount, o
|
|||||||
import type { ComponentPublicInstance, PropType } from 'vue'
|
import type { ComponentPublicInstance, PropType } from 'vue'
|
||||||
import { AgGridVue } from 'ag-grid-vue3'
|
import { AgGridVue } from 'ag-grid-vue3'
|
||||||
import type { ColDef, GridOptions, ICellRendererParams } from 'ag-grid-community'
|
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 { AG_GRID_LOCALE_CN } from '@ag-grid-community/locale'
|
||||||
import { addNumbers } from '@/lib/decimal'
|
import { addNumbers } from '@/lib/decimal'
|
||||||
import { parseNumberOrNull } from '@/lib/number'
|
import { parseNumberOrNull } from '@/lib/number'
|
||||||
@ -1150,8 +1150,8 @@ onBeforeUnmount(() => {
|
|||||||
<div class="text-[11px] text-muted-foreground leading-none">按服务词典生成</div>
|
<div class="text-[11px] text-muted-foreground leading-none">按服务词典生成</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="ag-theme-quartz w-full flex-1 min-h-0">
|
<div :class="agGridWrapClass">
|
||||||
<AgGridVue :style="{ height: '100%' }" :rowData="detailRows" :columnDefs="columnDefs"
|
<AgGridVue :style="agGridStyle" :rowData="detailRows" :columnDefs="columnDefs"
|
||||||
:gridOptions="detailGridOptions" :theme="myTheme" @cell-value-changed="handleCellValueChanged"
|
:gridOptions="detailGridOptions" :theme="myTheme" @cell-value-changed="handleCellValueChanged"
|
||||||
:enableClipboard="true" :localeText="AG_GRID_LOCALE_CN" :tooltipShowDelay="500" :headerHeight="30"
|
:enableClipboard="true" :localeText="AG_GRID_LOCALE_CN" :tooltipShowDelay="500" :headerHeight="30"
|
||||||
:undoRedoCellEditing="true" :undoRedoCellEditingLimit="20" />
|
:undoRedoCellEditing="true" :undoRedoCellEditingLimit="20" />
|
||||||
|
|||||||
@ -3,7 +3,7 @@ import { computed, onActivated, onBeforeUnmount, onMounted, ref } from 'vue'
|
|||||||
import { AgGridVue } from 'ag-grid-vue3'
|
import { AgGridVue } from 'ag-grid-vue3'
|
||||||
import type { ColDef, ColGroupDef } from 'ag-grid-community'
|
import type { ColDef, ColGroupDef } from 'ag-grid-community'
|
||||||
import { getMajorDictEntries, getServiceDictItemById, industryTypeList, isMajorIdInIndustryScope } from '@/sql'
|
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 { addNumbers, decimalAggSum, roundTo, sumByNumber } from '@/lib/decimal'
|
||||||
import { formatThousandsFlexible } from '@/lib/numberFormat'
|
import { formatThousandsFlexible } from '@/lib/numberFormat'
|
||||||
import { syncPricingTotalToZxFw } from '@/lib/zxFwPricingSync'
|
import { syncPricingTotalToZxFw } from '@/lib/zxFwPricingSync'
|
||||||
@ -1365,8 +1365,8 @@ const processCellFromClipboard = (params: any) => {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="ag-theme-quartz h-full min-h-0 w-full flex-1">
|
<div :class="agGridWrapClass">
|
||||||
<AgGridVue :style="{ height: '100%' }" :rowData="detailRows" :pinnedTopRowData="pinnedTopRowData"
|
<AgGridVue :style="agGridStyle" :rowData="detailRows" :pinnedTopRowData="pinnedTopRowData"
|
||||||
:columnDefs="columnDefs" :autoGroupColumnDef="autoGroupColumnDef" :gridOptions="gridOptions" :theme="myTheme"
|
:columnDefs="columnDefs" :autoGroupColumnDef="autoGroupColumnDef" :gridOptions="gridOptions" :theme="myTheme"
|
||||||
@cell-value-changed="handleCellValueChanged" :suppressColumnVirtualisation="true"
|
@cell-value-changed="handleCellValueChanged" :suppressColumnVirtualisation="true"
|
||||||
:suppressRowVirtualisation="true" :cellSelection="{ handle: { mode: 'range' } }" :enableClipboard="true"
|
:suppressRowVirtualisation="true" :cellSelection="{ handle: { mode: 'range' } }" :enableClipboard="true"
|
||||||
|
|||||||
@ -3,7 +3,7 @@ import { computed, onActivated, onBeforeUnmount, onMounted, ref } from 'vue'
|
|||||||
import { AgGridVue } from 'ag-grid-vue3'
|
import { AgGridVue } from 'ag-grid-vue3'
|
||||||
import type { ColDef, ColGroupDef } from 'ag-grid-community'
|
import type { ColDef, ColGroupDef } from 'ag-grid-community'
|
||||||
import { getMajorDictEntries, getServiceDictItemById, industryTypeList, isMajorIdInIndustryScope } from '@/sql'
|
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 { addNumbers, decimalAggSum, roundTo, sumByNumber } from '@/lib/decimal'
|
||||||
import { formatThousandsFlexible } from '@/lib/numberFormat'
|
import { formatThousandsFlexible } from '@/lib/numberFormat'
|
||||||
import { syncPricingTotalToZxFw } from '@/lib/zxFwPricingSync'
|
import { syncPricingTotalToZxFw } from '@/lib/zxFwPricingSync'
|
||||||
@ -1194,8 +1194,8 @@ const processCellFromClipboard = (params: any) => {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="ag-theme-quartz h-full min-h-0 w-full flex-1">
|
<div :class="agGridWrapClass">
|
||||||
<AgGridVue :style="{ height: '100%' }" :rowData="detailRows" :pinnedTopRowData="pinnedTopRowData"
|
<AgGridVue :style="agGridStyle" :rowData="detailRows" :pinnedTopRowData="pinnedTopRowData"
|
||||||
:columnDefs="columnDefs" :autoGroupColumnDef="autoGroupColumnDef" :gridOptions="gridOptions" :theme="myTheme"
|
:columnDefs="columnDefs" :autoGroupColumnDef="autoGroupColumnDef" :gridOptions="gridOptions" :theme="myTheme"
|
||||||
@cell-value-changed="handleCellValueChanged" :suppressColumnVirtualisation="true"
|
@cell-value-changed="handleCellValueChanged" :suppressColumnVirtualisation="true"
|
||||||
:suppressRowVirtualisation="true" :cellSelection="{ handle: { mode: 'range' } }" :enableClipboard="true"
|
:suppressRowVirtualisation="true" :cellSelection="{ handle: { mode: 'range' } }" :enableClipboard="true"
|
||||||
|
|||||||
@ -3,7 +3,7 @@ import { computed, onBeforeUnmount, onMounted, ref } from 'vue'
|
|||||||
import { AgGridVue } from 'ag-grid-vue3'
|
import { AgGridVue } from 'ag-grid-vue3'
|
||||||
import type { ColDef } from 'ag-grid-community'
|
import type { ColDef } from 'ag-grid-community'
|
||||||
import { taskList } from '@/sql'
|
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 { decimalAggSum, roundTo, sumByNumber, toDecimal } from '@/lib/decimal'
|
||||||
import { formatThousands, formatThousandsFlexible } from '@/lib/numberFormat'
|
import { formatThousands, formatThousandsFlexible } from '@/lib/numberFormat'
|
||||||
import { parseNumberOrNull } from '@/lib/number'
|
import { parseNumberOrNull } from '@/lib/number'
|
||||||
@ -537,8 +537,8 @@ const mydiyTheme = myTheme.withParams({
|
|||||||
<div class="text-xs text-muted-foreground"></div>
|
<div class="text-xs text-muted-foreground"></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div v-if="isWorkloadMethodApplicable" class="ag-theme-quartz h-full min-h-0 w-full flex-1">
|
<div v-if="isWorkloadMethodApplicable" :class="agGridWrapClass">
|
||||||
<AgGridVue :style="{ height: '100%' }" :rowData="detailRows" :pinnedTopRowData="pinnedTopRowData"
|
<AgGridVue :style="agGridStyle" :rowData="detailRows" :pinnedTopRowData="pinnedTopRowData"
|
||||||
:columnDefs="columnDefs" :gridOptions="gridOptions" :theme="mydiyTheme" :treeData="false"
|
:columnDefs="columnDefs" :gridOptions="gridOptions" :theme="mydiyTheme" :treeData="false"
|
||||||
:enableCellSpan="true"
|
:enableCellSpan="true"
|
||||||
@cell-value-changed="handleCellValueChanged" :suppressColumnVirtualisation="true"
|
@cell-value-changed="handleCellValueChanged" :suppressColumnVirtualisation="true"
|
||||||
|
|||||||
@ -3,7 +3,7 @@ import { computed, onActivated, onBeforeUnmount, onDeactivated, onMounted, ref,
|
|||||||
import { AgGridVue } from 'ag-grid-vue3'
|
import { AgGridVue } from 'ag-grid-vue3'
|
||||||
import type { ColDef, ColGroupDef, GridApi, GridReadyEvent } from 'ag-grid-community'
|
import type { ColDef, ColGroupDef, GridApi, GridReadyEvent } from 'ag-grid-community'
|
||||||
import { expertList } from '@/sql'
|
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 { decimalAggSum, roundTo, sumByNumber, toDecimal } from '@/lib/decimal'
|
||||||
import { formatThousandsFlexible } from '@/lib/numberFormat'
|
import { formatThousandsFlexible } from '@/lib/numberFormat'
|
||||||
import { parseNumberOrNull } from '@/lib/number'
|
import { parseNumberOrNull } from '@/lib/number'
|
||||||
@ -576,9 +576,9 @@ onBeforeUnmount(() => {
|
|||||||
<div class="text-xs text-muted-foreground"></div>
|
<div class="text-xs text-muted-foreground"></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="ag-theme-quartz h-full min-h-0 w-full flex-1">
|
<div :class="agGridWrapClass">
|
||||||
<AgGridVue
|
<AgGridVue
|
||||||
:style="{ height: '100%' }"
|
:style="agGridStyle"
|
||||||
:rowData="detailRows"
|
:rowData="detailRows"
|
||||||
:pinnedTopRowData="pinnedTopRowData"
|
:pinnedTopRowData="pinnedTopRowData"
|
||||||
:columnDefs="columnDefs"
|
:columnDefs="columnDefs"
|
||||||
|
|||||||
@ -3,7 +3,7 @@ import { computed, defineComponent, h, onActivated, onBeforeUnmount, onMounted,
|
|||||||
import { AgGridVue } from 'ag-grid-vue3'
|
import { AgGridVue } from 'ag-grid-vue3'
|
||||||
import type { ColDef, GridApi, GridOptions, GridReadyEvent, ICellRendererParams } from 'ag-grid-community'
|
import type { ColDef, GridApi, GridOptions, GridReadyEvent, ICellRendererParams } from 'ag-grid-community'
|
||||||
import { AG_GRID_LOCALE_CN } from '@ag-grid-community/locale'
|
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 { parseNumberOrNull } from '@/lib/number'
|
||||||
import { formatThousandsFlexible } from '@/lib/numberFormat'
|
import { formatThousandsFlexible } from '@/lib/numberFormat'
|
||||||
import { roundTo, toDecimal } from '@/lib/decimal'
|
import { roundTo, toDecimal } from '@/lib/decimal'
|
||||||
@ -443,9 +443,9 @@ onBeforeUnmount(() => {
|
|||||||
<Button type="button" variant="outline" size="sm" @click="addRow">添加行</Button>
|
<Button type="button" variant="outline" size="sm" @click="addRow">添加行</Button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="ag-theme-quartz h-full min-h-0 w-full flex-1">
|
<div :class="agGridWrapClass">
|
||||||
<AgGridVue
|
<AgGridVue
|
||||||
:style="{ height: '100%' }"
|
:style="agGridStyle"
|
||||||
:rowData="detailRows"
|
:rowData="detailRows"
|
||||||
:columnDefs="columnDefs"
|
:columnDefs="columnDefs"
|
||||||
:gridOptions="detailGridOptions"
|
:gridOptions="detailGridOptions"
|
||||||
|
|||||||
@ -3,7 +3,7 @@ import { computed, defineComponent, h, nextTick, onActivated, onBeforeUnmount, o
|
|||||||
import { AgGridVue } from 'ag-grid-vue3'
|
import { AgGridVue } from 'ag-grid-vue3'
|
||||||
import type { CellValueChangedEvent, ColDef, GridApi, GridOptions, GridReadyEvent, ICellRendererParams } from 'ag-grid-community'
|
import type { CellValueChangedEvent, ColDef, GridApi, GridOptions, GridReadyEvent, ICellRendererParams } from 'ag-grid-community'
|
||||||
import { AG_GRID_LOCALE_CN } from '@ag-grid-community/locale'
|
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 { parseNumberOrNull } from '@/lib/number'
|
||||||
import { formatThousandsFlexible } from '@/lib/numberFormat'
|
import { formatThousandsFlexible } from '@/lib/numberFormat'
|
||||||
import { Pencil, Eraser } from 'lucide-vue-next'
|
import { Pencil, Eraser } from 'lucide-vue-next'
|
||||||
@ -75,11 +75,10 @@ const props = defineProps<{
|
|||||||
storageKey: string
|
storageKey: string
|
||||||
contractId?: string
|
contractId?: string
|
||||||
contractName?: string
|
contractName?: string
|
||||||
fixedNames?: string[]
|
fixedNames?: any[]
|
||||||
}>()
|
}>()
|
||||||
const tabStore = useTabStore()
|
const tabStore = useTabStore()
|
||||||
const zxFwPricingStore = useZxFwPricingStore()
|
const zxFwPricingStore = useZxFwPricingStore()
|
||||||
|
|
||||||
const createRowId = () => `fee-method-${Date.now()}-${Math.random().toString(16).slice(2, 8)}`
|
const createRowId = () => `fee-method-${Date.now()}-${Math.random().toString(16).slice(2, 8)}`
|
||||||
const createDefaultRow = (name = ''): FeeMethodRow => ({
|
const createDefaultRow = (name = ''): FeeMethodRow => ({
|
||||||
id: createRowId(),
|
id: createRowId(),
|
||||||
@ -89,6 +88,7 @@ const createDefaultRow = (name = ''): FeeMethodRow => ({
|
|||||||
quantityUnitPriceFee: null
|
quantityUnitPriceFee: null
|
||||||
})
|
})
|
||||||
const SUMMARY_ROW_ID = 'fee-method-summary'
|
const SUMMARY_ROW_ID = 'fee-method-summary'
|
||||||
|
|
||||||
const isSummaryRow = (row: FeeMethodRow | null | undefined) => row?.id === SUMMARY_ROW_ID
|
const isSummaryRow = (row: FeeMethodRow | null | undefined) => row?.id === SUMMARY_ROW_ID
|
||||||
const toFinite = (value: number | null | undefined) =>
|
const toFinite = (value: number | null | undefined) =>
|
||||||
typeof value === 'number' && Number.isFinite(value) ? value : 0
|
typeof value === 'number' && Number.isFinite(value) ? value : 0
|
||||||
@ -240,7 +240,7 @@ const hydrateRowsFromMethodStores = async (rows: FeeMethodRow[]): Promise<FeeMet
|
|||||||
|
|
||||||
const fixedNames = computed(() =>
|
const fixedNames = computed(() =>
|
||||||
Array.isArray(props.fixedNames)
|
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)
|
const hasFixedNames = computed(() => fixedNames.value.length > 0)
|
||||||
@ -328,12 +328,12 @@ const toLegacyQuantityUnitPriceFee = (row: LegacyFeeRow) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const mergeWithStoredRows = (rowsFromDb: unknown): FeeMethodRow[] => {
|
const mergeWithStoredRows = (rowsFromDb: unknown): FeeMethodRow[] => {
|
||||||
|
|
||||||
const sourceRows = (Array.isArray(rowsFromDb) ? rowsFromDb : []).filter(
|
const sourceRows = (Array.isArray(rowsFromDb) ? rowsFromDb : []).filter(
|
||||||
item => (item as Partial<FeeMethodRow>)?.id !== SUMMARY_ROW_ID
|
item => (item as Partial<FeeMethodRow>)?.id !== SUMMARY_ROW_ID
|
||||||
)
|
)
|
||||||
const rows = sourceRows.map(item => {
|
const rows = sourceRows.map(item => {
|
||||||
const row = item as Partial<FeeMethodRow> & LegacyFeeRow
|
const row = item as Partial<FeeMethodRow> & LegacyFeeRow
|
||||||
|
|
||||||
return {
|
return {
|
||||||
id: typeof row.id === 'string' && row.id ? row.id : createRowId(),
|
id: typeof row.id === 'string' && row.id ? row.id : createRowId(),
|
||||||
name:
|
name:
|
||||||
@ -349,13 +349,15 @@ const mergeWithStoredRows = (rowsFromDb: unknown): FeeMethodRow[] => {
|
|||||||
: toLegacyQuantityUnitPriceFee(row)
|
: toLegacyQuantityUnitPriceFee(row)
|
||||||
} as FeeMethodRow
|
} as FeeMethodRow
|
||||||
})
|
})
|
||||||
|
|
||||||
if (hasFixedNames.value) {
|
if (hasFixedNames.value) {
|
||||||
|
|
||||||
const byName = new Map(rows.map(row => [row.name, row]))
|
const byName = new Map(rows.map(row => [row.name, row]))
|
||||||
return fixedNames.value.map((name, index) => {
|
return fixedNames.value.map((item, index) => {
|
||||||
const fromDb = byName.get(name)
|
const fromDb = byName.get(item.name)
|
||||||
return {
|
return {
|
||||||
id: fromDb?.id || `fee-method-fixed-${index}`,
|
id: item?.id || `fee-method-fixed-${index}`,
|
||||||
name,
|
name:item.name,
|
||||||
rateFee: fromDb?.rateFee ?? null,
|
rateFee: fromDb?.rateFee ?? null,
|
||||||
hourlyFee: fromDb?.hourlyFee ?? null,
|
hourlyFee: fromDb?.hourlyFee ?? null,
|
||||||
quantityUnitPriceFee: fromDb?.quantityUnitPriceFee ?? null
|
quantityUnitPriceFee: fromDb?.quantityUnitPriceFee ?? null
|
||||||
@ -384,7 +386,6 @@ const saveToIndexedDB = async (force = false) => {
|
|||||||
const loadFromIndexedDB = async () => {
|
const loadFromIndexedDB = async () => {
|
||||||
try {
|
try {
|
||||||
const data = await zxFwPricingStore.loadHtFeeMainState<FeeMethodRow>(props.storageKey)
|
const data = await zxFwPricingStore.loadHtFeeMainState<FeeMethodRow>(props.storageKey)
|
||||||
|
|
||||||
const mergedRows = mergeWithStoredRows(data?.detailRows)
|
const mergedRows = mergeWithStoredRows(data?.detailRows)
|
||||||
detailRows.value = await hydrateRowsFromMethodStores(mergedRows)
|
detailRows.value = await hydrateRowsFromMethodStores(mergedRows)
|
||||||
await saveToIndexedDB(true)
|
await saveToIndexedDB(true)
|
||||||
@ -423,6 +424,7 @@ const clearRow = async (id: string) => {
|
|||||||
const editRow = (id: string) => {
|
const editRow = (id: string) => {
|
||||||
const row = detailRows.value.find(item => item.id === id)
|
const row = detailRows.value.find(item => item.id === id)
|
||||||
if (!row) return
|
if (!row) return
|
||||||
|
console.log(id)
|
||||||
tabStore.openTab({
|
tabStore.openTab({
|
||||||
id: `ht-fee-edit-${props.storageKey}-${id}`,
|
id: `ht-fee-edit-${props.storageKey}-${id}`,
|
||||||
title: `费用编辑-${row.name || '未命名'}`,
|
title: `费用编辑-${row.name || '未命名'}`,
|
||||||
@ -694,9 +696,9 @@ onBeforeUnmount(() => {
|
|||||||
<Button v-if="!hasFixedNames" type="button" variant="outline" size="sm" @click="addRow">新增</Button>
|
<Button v-if="!hasFixedNames" type="button" variant="outline" size="sm" @click="addRow">新增</Button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="ag-theme-quartz h-full min-h-0 w-full flex-1">
|
<div :class="agGridWrapClass">
|
||||||
<AgGridVue
|
<AgGridVue
|
||||||
:style="{ height: '100%' }"
|
:style="agGridStyle"
|
||||||
:rowData="displayRows"
|
:rowData="displayRows"
|
||||||
:columnDefs="columnDefs"
|
:columnDefs="columnDefs"
|
||||||
:gridOptions="detailGridOptions"
|
:gridOptions="detailGridOptions"
|
||||||
|
|||||||
@ -11,7 +11,7 @@ import type {
|
|||||||
} from 'ag-grid-community'
|
} from 'ag-grid-community'
|
||||||
import { AG_GRID_LOCALE_CN } from '@ag-grid-community/locale'
|
import { AG_GRID_LOCALE_CN } from '@ag-grid-community/locale'
|
||||||
import { Button } from '@/components/ui/button'
|
import { Button } from '@/components/ui/button'
|
||||||
import { myTheme } from '@/lib/diyAgGridOptions'
|
import { myTheme, agGridStyle } from '@/lib/diyAgGridOptions'
|
||||||
import { workList } from '@/sql'
|
import { workList } from '@/sql'
|
||||||
import type { WorkType } from '@/sql'
|
import type { WorkType } from '@/sql'
|
||||||
import { useZxFwPricingStore } from '@/pinia/zxFwPricing'
|
import { useZxFwPricingStore } from '@/pinia/zxFwPricing'
|
||||||
@ -66,7 +66,7 @@ const buildDefaultRowsFromDict = (): WorkContentRow[] => {
|
|||||||
const sid = Number(props.serviceId)
|
const sid = Number(props.serviceId)
|
||||||
filtered = entries.filter(e => e.serviceid === sid)
|
filtered = entries.filter(e => e.serviceid === sid)
|
||||||
} else if (props.dictMode === 'additional') {
|
} 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 {
|
} else {
|
||||||
return []
|
return []
|
||||||
}
|
}
|
||||||
@ -188,7 +188,13 @@ const columnDefs: ColDef<WorkContentRow>[] = [
|
|||||||
flex: 2,
|
flex: 2,
|
||||||
editable: params => Boolean(params.data?.custom),
|
editable: params => Boolean(params.data?.custom),
|
||||||
cellClass: params => (params.data?.custom ? 'editable-cell-line' : ''),
|
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(),
|
valueParser: params => String(params.newValue || '').trim(),
|
||||||
|
wrapText: true,
|
||||||
|
autoHeight: true,
|
||||||
|
cellStyle: { whiteSpace: 'normal', lineHeight: '1.5' },
|
||||||
cellRenderer: contentCellRenderer
|
cellRenderer: contentCellRenderer
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -267,7 +273,7 @@ onBeforeUnmount(() => {
|
|||||||
</div>
|
</div>
|
||||||
<div class="ag-theme-quartz h-[calc(100%-56px)] min-h-0 w-full">
|
<div class="ag-theme-quartz h-[calc(100%-56px)] min-h-0 w-full">
|
||||||
<AgGridVue
|
<AgGridVue
|
||||||
:style="{ height: '100%' }"
|
:style="agGridStyle"
|
||||||
:rowData="rowData"
|
:rowData="rowData"
|
||||||
:columnDefs="columnDefs"
|
:columnDefs="columnDefs"
|
||||||
:theme="myTheme"
|
:theme="myTheme"
|
||||||
@ -300,16 +306,15 @@ onBeforeUnmount(() => {
|
|||||||
display: flex;
|
display: flex;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: space-between;
|
|
||||||
gap: 8px;
|
gap: 8px;
|
||||||
}
|
}
|
||||||
|
|
||||||
:deep(.work-content-text) {
|
:deep(.work-content-text) {
|
||||||
min-width: 0;
|
min-width: 0;
|
||||||
flex: 1;
|
flex: 1;
|
||||||
overflow: hidden;
|
white-space: normal;
|
||||||
text-overflow: ellipsis;
|
word-break: break-word;
|
||||||
white-space: nowrap;
|
line-height: 1.5;
|
||||||
}
|
}
|
||||||
|
|
||||||
:deep(.work-content-check) {
|
:deep(.work-content-check) {
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
import { onBeforeUnmount, onMounted, ref, watch } from 'vue'
|
import { onBeforeUnmount, onMounted, ref, watch } from 'vue'
|
||||||
import { AgGridVue } from 'ag-grid-vue3'
|
import { AgGridVue } from 'ag-grid-vue3'
|
||||||
import type { ColDef, FirstDataRenderedEvent, GridApi, GridReadyEvent, GridSizeChangedEvent } from 'ag-grid-community'
|
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 { parseNumberOrNull } from '@/lib/number'
|
||||||
import { AG_GRID_LOCALE_CN } from '@ag-grid-community/locale'
|
import { AG_GRID_LOCALE_CN } from '@ag-grid-community/locale'
|
||||||
import { useKvStore } from '@/pinia/kv'
|
import { useKvStore } from '@/pinia/kv'
|
||||||
@ -325,9 +325,9 @@ onBeforeUnmount(() => {
|
|||||||
<div class="text-xs text-muted-foreground"></div>
|
<div class="text-xs text-muted-foreground"></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="ag-theme-quartz h-full min-h-0 w-full flex-1">
|
<div :class="agGridWrapClass">
|
||||||
<AgGridVue
|
<AgGridVue
|
||||||
:style="{ height: '100%' }"
|
:style="agGridStyle"
|
||||||
:rowData="detailRows"
|
:rowData="detailRows"
|
||||||
:columnDefs="columnDefs"
|
:columnDefs="columnDefs"
|
||||||
:autoGroupColumnDef="autoGroupColumnDef"
|
:autoGroupColumnDef="autoGroupColumnDef"
|
||||||
|
|||||||
@ -3,7 +3,7 @@ import { computed, onActivated, onBeforeUnmount, onMounted, ref, watch } from 'v
|
|||||||
import { AgGridVue } from 'ag-grid-vue3'
|
import { AgGridVue } from 'ag-grid-vue3'
|
||||||
import type { CellValueChangedEvent, ColDef, GridApi, GridReadyEvent } from 'ag-grid-community'
|
import type { CellValueChangedEvent, ColDef, GridApi, GridReadyEvent } from 'ag-grid-community'
|
||||||
import { AG_GRID_LOCALE_CN } from '@ag-grid-community/locale'
|
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 { decimalAggSum, roundTo, sumByNumber } from '@/lib/decimal'
|
||||||
import { formatThousandsFlexible } from '@/lib/numberFormat'
|
import { formatThousandsFlexible } from '@/lib/numberFormat'
|
||||||
import { industryTypeList, getMajorDictEntries, isMajorIdInIndustryScope } from '@/sql'
|
import { industryTypeList, getMajorDictEntries, isMajorIdInIndustryScope } from '@/sql'
|
||||||
@ -626,8 +626,8 @@ onMounted(() => {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="ag-theme-quartz w-full flex-1 min-h-0 h-full">
|
<div :class="agGridWrapClass">
|
||||||
<AgGridVue :style="{ height: '100%' }" :rowData="visibleRowData" :pinnedTopRowData="pinnedTopRowData"
|
<AgGridVue :style="agGridStyle" :rowData="visibleRowData" :pinnedTopRowData="pinnedTopRowData"
|
||||||
:columnDefs="columnDefs" :autoGroupColumnDef="autoGroupColumnDef" :gridOptions="gridOptions" :theme="myTheme"
|
:columnDefs="columnDefs" :autoGroupColumnDef="autoGroupColumnDef" :gridOptions="gridOptions" :theme="myTheme"
|
||||||
@grid-ready="onGridReady" @cell-value-changed="onCellValueChanged" :suppressColumnVirtualisation="true"
|
@grid-ready="onGridReady" @cell-value-changed="onCellValueChanged" :suppressColumnVirtualisation="true"
|
||||||
:suppressRowVirtualisation="true" :cellSelection="{ handle: { mode: 'range' } }" :enableClipboard="true"
|
:suppressRowVirtualisation="true" :cellSelection="{ handle: { mode: 'range' } }" :enableClipboard="true"
|
||||||
|
|||||||
@ -31,7 +31,6 @@ const props = defineProps<{
|
|||||||
contractId?: string
|
contractId?: string
|
||||||
contractName?: string
|
contractName?: string
|
||||||
}>()
|
}>()
|
||||||
|
|
||||||
const sourceTitleText = computed(() => props.sourceTitle || '费用明细')
|
const sourceTitleText = computed(() => props.sourceTitle || '费用明细')
|
||||||
const rowNameText = computed(() => props.rowName || '未命名')
|
const rowNameText = computed(() => props.rowName || '未命名')
|
||||||
const contractIdText = computed(() => String(props.contractId || '').trim())
|
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 isReserveFee = computed(() => props.sourceTitle === '预备费')
|
||||||
const showWorkContent = computed(() => {
|
const showWorkContent = computed(() => {
|
||||||
if (isReserveFee.value) return false
|
if (isReserveFee.value) return false
|
||||||
if (isAdditionalWork.value) return props.rowName === '咨询服务协调工作'
|
|
||||||
return true
|
return true
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -110,11 +107,10 @@ const workContentPane = markRaw(
|
|||||||
console.error('加载 WorkContentGrid 组件失败:', err)
|
console.error('加载 WorkContentGrid 组件失败:', err)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
return () => h(AsyncWorkContentGrid, {
|
return () => h(AsyncWorkContentGrid, {
|
||||||
title: '工作内容',
|
title: '工作内容',
|
||||||
storageKey: `work-content-${props.storageKey}-${props.rowId}`,
|
storageKey: `work-content-${props.storageKey}-${props.rowId}`,
|
||||||
dictMode: isAdditionalWork.value ? 'additional' : 'none'
|
dictMode: 'additional'
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
@ -23,7 +23,7 @@ import {
|
|||||||
} from 'reka-ui'
|
} from 'reka-ui'
|
||||||
import { decodeZwArchive, encodeZwArchive, ZW_FILE_EXTENSION } from '@/lib/zwArchive'
|
import { decodeZwArchive, encodeZwArchive, ZW_FILE_EXTENSION } from '@/lib/zwArchive'
|
||||||
import { addNumbers, roundTo } from '@/lib/decimal'
|
import { addNumbers, roundTo } from '@/lib/decimal'
|
||||||
import { exportFile, serviceList, additionalWorkList } from '@/sql'
|
import { exportFile, serviceList } from '@/sql'
|
||||||
|
|
||||||
interface DataEntry {
|
interface DataEntry {
|
||||||
key: string
|
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 buildAdditionalExport = async (contractId: string): Promise<ExportAdditional | null> => {
|
||||||
const storageKey = `htExtraFee-${contractId}-additional-work`
|
const storageKey = `htExtraFee-${contractId}-additional-work`
|
||||||
|
|||||||
@ -75,10 +75,7 @@ const activeComponent = computed(() => {
|
|||||||
|
|
||||||
const copyBtnText = ref('复制')
|
const copyBtnText = ref('复制')
|
||||||
const sheetOpen = ref(false)
|
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 copyBtnTimer: ReturnType<typeof setTimeout> | null = null
|
||||||
let titleOverflowRafId: number | null = null
|
let titleOverflowRafId: number | null = null
|
||||||
|
|
||||||
|
|||||||
@ -20,6 +20,12 @@ export const myTheme = themeQuartz.withParams({
|
|||||||
dataBackgroundColor: '#fefefe'
|
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 = {
|
export const gridOptions: GridOptions = {
|
||||||
treeData: true,
|
treeData: true,
|
||||||
animateRows: true,
|
animateRows: true,
|
||||||
|
|||||||
@ -152,7 +152,7 @@ export const expertList = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const additionalWorkList = [
|
export const additionalWorkList = [
|
||||||
{
|
{ id:'1',
|
||||||
code: {
|
code: {
|
||||||
richText: [
|
richText: [
|
||||||
{ font: { charset: 134, color: { theme: 1 }, italic: true, name: '宋体', size: 10 }, text: 'C' },
|
{ font: { charset: 134, color: { theme: 1 }, italic: true, name: '宋体', size: 10 }, text: 'C' },
|
||||||
@ -161,7 +161,7 @@ export const additionalWorkList = [
|
|||||||
},
|
},
|
||||||
name: '人员驻场服务及其他附加工作'
|
name: '人员驻场服务及其他附加工作'
|
||||||
},
|
},
|
||||||
{
|
{id:'2',
|
||||||
code: {
|
code: {
|
||||||
richText: [
|
richText: [
|
||||||
{ font: { charset: 134, color: { theme: 1 }, italic: true, name: '宋体', size: 10 }, text: 'C' },
|
{ font: { charset: 134, color: { theme: 1 }, italic: true, name: '宋体', size: 10 }, text: 'C' },
|
||||||
@ -174,6 +174,7 @@ export const additionalWorkList = [
|
|||||||
|
|
||||||
export const reserveList = [
|
export const reserveList = [
|
||||||
{
|
{
|
||||||
|
id:1,
|
||||||
code: {
|
code: {
|
||||||
richText: [
|
richText: [
|
||||||
{ font: { charset: 134, color: { theme: 1 }, italic: true, name: '宋体', size: 10 }, text: 'Y' },
|
{ font: { charset: 134, color: { theme: 1 }, italic: true, name: '宋体', size: 10 }, text: 'Y' },
|
||||||
|
|||||||
@ -295,6 +295,7 @@ html {
|
|||||||
color: #94a3b8 !important;
|
color: #94a3b8 !important;
|
||||||
font-style: italic;
|
font-style: italic;
|
||||||
opacity: 1 !important;
|
opacity: 1 !important;
|
||||||
|
border-bottom: none !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.xmMx .ag-cell.editable-cell-empty,
|
.xmMx .ag-cell.editable-cell-empty,
|
||||||
|
|||||||
@ -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"}
|
||||||
Loading…
x
Reference in New Issue
Block a user