1
This commit is contained in:
parent
42fd6e48c4
commit
e4a2b5373f
49
src/components/common/CommonAgGrid.vue
Normal file
49
src/components/common/CommonAgGrid.vue
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
import { AgGridVue } from 'ag-grid-vue3'
|
||||||
|
import type { CellValueChangedEvent, ColDef } from 'ag-grid-community'
|
||||||
|
import { AG_GRID_LOCALE_CN } from '@ag-grid-community/locale'
|
||||||
|
import { myTheme, gridOptions } from '@/lib/diyAgGridOptions'
|
||||||
|
|
||||||
|
const props = defineProps<{
|
||||||
|
rowData: unknown[]
|
||||||
|
pinnedTopRowData?: unknown[]
|
||||||
|
columnDefs: ColDef[]
|
||||||
|
autoGroupColumnDef: ColDef
|
||||||
|
processCellForClipboard?: (params: any) => unknown
|
||||||
|
processCellFromClipboard?: (params: any) => unknown
|
||||||
|
headerHeight?: number
|
||||||
|
}>()
|
||||||
|
|
||||||
|
const emit = defineEmits<{
|
||||||
|
(event: 'cell-value-changed', payload: CellValueChangedEvent): void
|
||||||
|
}>()
|
||||||
|
|
||||||
|
const onCellValueChanged = (event: CellValueChangedEvent) => {
|
||||||
|
emit('cell-value-changed', event)
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<AgGridVue
|
||||||
|
:style="{ height: '100%' }"
|
||||||
|
:rowData="props.rowData"
|
||||||
|
:pinnedTopRowData="props.pinnedTopRowData"
|
||||||
|
:columnDefs="props.columnDefs"
|
||||||
|
:autoGroupColumnDef="props.autoGroupColumnDef"
|
||||||
|
:gridOptions="gridOptions"
|
||||||
|
:theme="myTheme"
|
||||||
|
@cell-value-changed="onCellValueChanged"
|
||||||
|
:suppressColumnVirtualisation="true"
|
||||||
|
:suppressRowVirtualisation="true"
|
||||||
|
:cellSelection="{ handle: { mode: 'range' } }"
|
||||||
|
:enableClipboard="true"
|
||||||
|
:localeText="AG_GRID_LOCALE_CN"
|
||||||
|
:tooltipShowDelay="500"
|
||||||
|
:headerHeight="props.headerHeight ?? 50"
|
||||||
|
:suppressHorizontalScroll="true"
|
||||||
|
:processCellForClipboard="props.processCellForClipboard"
|
||||||
|
:processCellFromClipboard="props.processCellFromClipboard"
|
||||||
|
:undoRedoCellEditing="true"
|
||||||
|
:undoRedoCellEditingLimit="20"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
@ -31,31 +31,32 @@ const clearAll = () => {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="rounded-lg border bg-card p-4 shadow-sm shrink-0">
|
<div class="rounded-lg border bg-card p-2.5 shadow-sm">
|
||||||
<div class="mb-2 flex items-center justify-between gap-3">
|
<div class="mb-1 flex items-center justify-between gap-2">
|
||||||
<label class="block text-sm font-medium text-foreground">选择服务</label>
|
<label class="block text-[11px] font-medium text-foreground leading-none">选择服务</label>
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
class="h-8 rounded-md border px-3 text-xs text-muted-foreground transition hover:bg-accent"
|
class="h-6 rounded-md border px-2 text-[11px] text-muted-foreground transition hover:bg-accent"
|
||||||
@click="clearAll"
|
@click="clearAll"
|
||||||
>
|
>
|
||||||
清空
|
清空
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="max-h-52 overflow-auto rounded-md border p-2">
|
<div class="rounded-md border p-1.5">
|
||||||
<div class="flex flex-wrap gap-2">
|
<div class="flex flex-wrap items-start gap-1">
|
||||||
<label
|
<label
|
||||||
v-for="item in props.services"
|
v-for="item in props.services"
|
||||||
:key="item.id"
|
:key="item.id"
|
||||||
class="inline-flex cursor-pointer items-center gap-2 rounded-md border px-2.5 py-1.5 text-sm hover:bg-muted/60"
|
class="inline-flex w-fit max-w-full cursor-pointer items-start gap-1.5 rounded-md border px-2 py-1 text-[11px] leading-4 hover:bg-muted/60"
|
||||||
>
|
>
|
||||||
<input
|
<input
|
||||||
type="checkbox"
|
type="checkbox"
|
||||||
|
class="mt-0.5"
|
||||||
:checked="selectedSet.has(item.id)"
|
:checked="selectedSet.has(item.id)"
|
||||||
@change="toggleService(item.id, ($event.target as HTMLInputElement).checked)"
|
@change="toggleService(item.id, ($event.target as HTMLInputElement).checked)"
|
||||||
/>
|
/>
|
||||||
<span class="text-muted-foreground">{{ item.code }}</span>
|
<span class="text-muted-foreground shrink-0">{{ item.code }}</span>
|
||||||
<span class="text-foreground">{{ item.name }}</span>
|
<span class="text-foreground break-words">{{ item.name }}</span>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="props.services.length === 0" class="px-2 py-4 text-center text-xs text-muted-foreground">
|
<div v-if="props.services.length === 0" class="px-2 py-4 text-center text-xs text-muted-foreground">
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { serviceList } from '@/sql'
|
import { serviceList } from '@/sql'
|
||||||
import XmFactorGrid from '@/components/views/XmFactorGrid.vue'
|
import XmFactorGrid from '@/components/common/XmFactorGrid.vue'
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
|||||||
@ -1,9 +1,9 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { computed, onActivated, onMounted, ref } from 'vue'
|
import { computed, onActivated, onMounted, ref } from 'vue'
|
||||||
import localforage from 'localforage'
|
import localforage from 'localforage'
|
||||||
import { majorList } from '@/sql'
|
import { isMajorCodeInIndustryScope, majorList } from '@/sql'
|
||||||
import XmFactorGrid from '@/components/views/XmFactorGrid.vue'
|
import XmFactorGrid from '@/components/common/XmFactorGrid.vue'
|
||||||
import MethodUnavailableNotice from '@/components/views/pricingView/MethodUnavailableNotice.vue'
|
import MethodUnavailableNotice from '@/components/common/MethodUnavailableNotice.vue'
|
||||||
|
|
||||||
interface XmBaseInfoState {
|
interface XmBaseInfoState {
|
||||||
projectIndustry?: string
|
projectIndustry?: string
|
||||||
@ -37,9 +37,7 @@ const loadProjectIndustry = async () => {
|
|||||||
const filteredMajorDict = computed<Record<string, MajorItem>>(() => {
|
const filteredMajorDict = computed<Record<string, MajorItem>>(() => {
|
||||||
const industry = projectIndustry.value
|
const industry = projectIndustry.value
|
||||||
if (!industry) return {}
|
if (!industry) return {}
|
||||||
const entries = Object.entries(majorList as Record<string, MajorItem>).filter(([, item]) =>
|
const entries = Object.entries(majorList as Record<string, MajorItem>).filter(([, item]) => isMajorCodeInIndustryScope(item.code, industry))
|
||||||
item.code === industry || item.code.startsWith(`${industry}-`)
|
|
||||||
)
|
|
||||||
return Object.fromEntries(entries)
|
return Object.fromEntries(entries)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
@ -1,14 +1,11 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { computed, onActivated, onBeforeUnmount, onMounted, ref } from 'vue'
|
import { computed, onActivated, onBeforeUnmount, onMounted, ref } from 'vue'
|
||||||
import { AgGridVue } from 'ag-grid-vue3'
|
import type { ColDef } from 'ag-grid-community'
|
||||||
import type { ColDef, FirstDataRenderedEvent, GridApi, GridReadyEvent, GridSizeChangedEvent } from 'ag-grid-community'
|
|
||||||
import localforage from 'localforage'
|
import localforage from 'localforage'
|
||||||
import { majorList } from '@/sql'
|
import { isMajorCodeInIndustryScope, majorList } from '@/sql'
|
||||||
import { myTheme ,gridOptions} from '@/lib/diyAgGridOptions'
|
|
||||||
import { decimalAggSum, roundTo, sumByNumber } from '@/lib/decimal'
|
import { decimalAggSum, roundTo, sumByNumber } from '@/lib/decimal'
|
||||||
import { formatThousands } from '@/lib/numberFormat'
|
import { formatThousands } from '@/lib/numberFormat'
|
||||||
|
import CommonAgGrid from '@/components/common/CommonAgGrid.vue'
|
||||||
import { AG_GRID_LOCALE_CN } from '@ag-grid-community/locale';
|
|
||||||
// 精简的边框配置(细线条+浅灰色,弱化分割线视觉)
|
// 精简的边框配置(细线条+浅灰色,弱化分割线视觉)
|
||||||
|
|
||||||
interface DictLeaf {
|
interface DictLeaf {
|
||||||
@ -114,7 +111,7 @@ const buildDefaultRows = (): DetailRow[] => {
|
|||||||
if (!activeIndustryCode.value) return []
|
if (!activeIndustryCode.value) return []
|
||||||
const rows: DetailRow[] = []
|
const rows: DetailRow[] = []
|
||||||
for (const group of detailDict) {
|
for (const group of detailDict) {
|
||||||
if (activeIndustryCode.value && group.code !== activeIndustryCode.value) continue
|
if (activeIndustryCode.value && !isMajorCodeInIndustryScope(group.code, activeIndustryCode.value)) continue
|
||||||
for (const child of group.children) {
|
for (const child of group.children) {
|
||||||
rows.push({
|
rows.push({
|
||||||
id: child.id,
|
id: child.id,
|
||||||
@ -348,30 +345,15 @@ const processCellFromClipboard = (params:any) => {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="ag-theme-quartz h-full min-h-0 min-w-0 w-full flex-1 overflow-hidden">
|
<div class="ag-theme-quartz h-full min-h-0 min-w-0 w-full flex-1 overflow-hidden">
|
||||||
<AgGridVue
|
<CommonAgGrid
|
||||||
:style="{ height: '100%' }"
|
:rowData="detailRows"
|
||||||
:rowData="detailRows"
|
:pinnedTopRowData="pinnedTopRowData"
|
||||||
:pinnedTopRowData="pinnedTopRowData"
|
:columnDefs="columnDefs"
|
||||||
:columnDefs="columnDefs"
|
:autoGroupColumnDef="autoGroupColumnDef"
|
||||||
:autoGroupColumnDef="autoGroupColumnDef"
|
:processCellForClipboard="processCellForClipboard"
|
||||||
:gridOptions="gridOptions"
|
:processCellFromClipboard="processCellFromClipboard"
|
||||||
:theme="myTheme"
|
@cell-value-changed="handleCellValueChanged"
|
||||||
@cell-value-changed="handleCellValueChanged"
|
/>
|
||||||
:suppressColumnVirtualisation="true"
|
|
||||||
:suppressRowVirtualisation="true"
|
|
||||||
:cellSelection="{ handle: { mode: 'range' } }"
|
|
||||||
:enableClipboard="true"
|
|
||||||
:localeText="AG_GRID_LOCALE_CN"
|
|
||||||
:tooltipShowDelay="500"
|
|
||||||
:headerHeight="50"
|
|
||||||
:suppressHorizontalScroll="true"
|
|
||||||
:processCellForClipboard="processCellForClipboard"
|
|
||||||
:processCellFromClipboard="processCellFromClipboard"
|
|
||||||
:undoRedoCellEditing="true"
|
|
||||||
:undoRedoCellEditingLimit="20"
|
|
||||||
|
|
||||||
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { onMounted, ref, watch } from 'vue'
|
import { onMounted, ref, watch } from 'vue'
|
||||||
import localforage from 'localforage'
|
import localforage from 'localforage'
|
||||||
import { majorList } from '@/sql'
|
import { isMajorIndustrySelectable, majorList } from '@/sql'
|
||||||
import { CircleHelp } from 'lucide-vue-next'
|
import { CircleHelp } from 'lucide-vue-next'
|
||||||
import { TooltipContent, TooltipProvider, TooltipRoot, TooltipTrigger } from '@/components/ui/tooltip'
|
import { TooltipContent, TooltipProvider, TooltipRoot, TooltipTrigger } from '@/components/ui/tooltip'
|
||||||
|
|
||||||
@ -14,7 +14,7 @@ interface XmInfoState {
|
|||||||
preparedDate?: string
|
preparedDate?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
type MajorLite = { code: string; name: string }
|
type MajorLite = { code: string; name: string; hideInIndustrySelector?: boolean }
|
||||||
type MajorParentNode = { id: string; code: string; name: string }
|
type MajorParentNode = { id: string; code: string; name: string }
|
||||||
|
|
||||||
const DB_KEY = 'xm-base-info-v1'
|
const DB_KEY = 'xm-base-info-v1'
|
||||||
@ -41,7 +41,7 @@ const majorEntries = Object.entries(majorList as Record<string, MajorLite>)
|
|||||||
|
|
||||||
const getMajorParentNodes = (entries: Array<[string, MajorLite]>): MajorParentNode[] =>
|
const getMajorParentNodes = (entries: Array<[string, MajorLite]>): MajorParentNode[] =>
|
||||||
entries
|
entries
|
||||||
.filter(([, item]) => !item.code.includes('-'))
|
.filter(([, item]) => isMajorIndustrySelectable(item))
|
||||||
.map(([id, item]) => ({
|
.map(([id, item]) => ({
|
||||||
id,
|
id,
|
||||||
code: item.code,
|
code: item.code,
|
||||||
|
|||||||
@ -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 { ColDef, ColGroupDef } from 'ag-grid-community'
|
import type { ColDef, ColGroupDef } from 'ag-grid-community'
|
||||||
import localforage from 'localforage'
|
import localforage from 'localforage'
|
||||||
import { majorList } from '@/sql'
|
import { isMajorCodeInIndustryScope, majorList } from '@/sql'
|
||||||
import { myTheme, gridOptions } from '@/lib/diyAgGridOptions'
|
import { myTheme, gridOptions } from '@/lib/diyAgGridOptions'
|
||||||
import { decimalAggSum, roundTo, sumByNumber } from '@/lib/decimal'
|
import { decimalAggSum, roundTo, sumByNumber } from '@/lib/decimal'
|
||||||
import { formatThousands } from '@/lib/numberFormat'
|
import { formatThousands } from '@/lib/numberFormat'
|
||||||
@ -200,7 +200,7 @@ const buildDefaultRows = (): DetailRow[] => {
|
|||||||
if (!activeIndustryCode.value) return []
|
if (!activeIndustryCode.value) return []
|
||||||
const rows: DetailRow[] = []
|
const rows: DetailRow[] = []
|
||||||
for (const group of detailDict) {
|
for (const group of detailDict) {
|
||||||
if (activeIndustryCode.value && group.code !== activeIndustryCode.value) continue
|
if (activeIndustryCode.value && !isMajorCodeInIndustryScope(group.code, activeIndustryCode.value)) continue
|
||||||
for (const child of group.children) {
|
for (const child of group.children) {
|
||||||
rows.push({
|
rows.push({
|
||||||
id: child.id,
|
id: child.id,
|
||||||
|
|||||||
@ -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 { ColDef, ColGroupDef } from 'ag-grid-community'
|
import type { ColDef, ColGroupDef } from 'ag-grid-community'
|
||||||
import localforage from 'localforage'
|
import localforage from 'localforage'
|
||||||
import { majorList } from '@/sql'
|
import { isMajorCodeInIndustryScope, majorList } from '@/sql'
|
||||||
import { myTheme, gridOptions } from '@/lib/diyAgGridOptions'
|
import { myTheme, gridOptions } from '@/lib/diyAgGridOptions'
|
||||||
import { decimalAggSum, roundTo, sumByNumber } from '@/lib/decimal'
|
import { decimalAggSum, roundTo, sumByNumber } from '@/lib/decimal'
|
||||||
import { formatThousands } from '@/lib/numberFormat'
|
import { formatThousands } from '@/lib/numberFormat'
|
||||||
@ -201,7 +201,7 @@ const buildDefaultRows = (): DetailRow[] => {
|
|||||||
if (!activeIndustryCode.value) return []
|
if (!activeIndustryCode.value) return []
|
||||||
const rows: DetailRow[] = []
|
const rows: DetailRow[] = []
|
||||||
for (const group of detailDict) {
|
for (const group of detailDict) {
|
||||||
if (activeIndustryCode.value && group.code !== activeIndustryCode.value) continue
|
if (activeIndustryCode.value && !isMajorCodeInIndustryScope(group.code, activeIndustryCode.value)) continue
|
||||||
for (const child of group.children) {
|
for (const child of group.children) {
|
||||||
rows.push({
|
rows.push({
|
||||||
id: child.id,
|
id: child.id,
|
||||||
|
|||||||
@ -11,7 +11,7 @@ import { parseNumberOrNull } from '@/lib/number'
|
|||||||
import { syncPricingTotalToZxFw, ZXFW_RELOAD_SERVICE_KEY } from '@/lib/zxFwPricingSync'
|
import { syncPricingTotalToZxFw, ZXFW_RELOAD_SERVICE_KEY } from '@/lib/zxFwPricingSync'
|
||||||
import { usePricingPaneReloadStore } from '@/pinia/pricingPaneReload'
|
import { usePricingPaneReloadStore } from '@/pinia/pricingPaneReload'
|
||||||
import { loadConsultCategoryFactorMap } from '@/lib/xmFactorDefaults'
|
import { loadConsultCategoryFactorMap } from '@/lib/xmFactorDefaults'
|
||||||
import MethodUnavailableNotice from '@/components/views/pricingView/MethodUnavailableNotice.vue'
|
import MethodUnavailableNotice from '@/components/common/MethodUnavailableNotice.vue'
|
||||||
|
|
||||||
import { AG_GRID_LOCALE_CN } from '@ag-grid-community/locale';
|
import { AG_GRID_LOCALE_CN } from '@ag-grid-community/locale';
|
||||||
|
|
||||||
|
|||||||
@ -1,14 +1,12 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { computed, onActivated, onBeforeUnmount, onMounted, ref } from 'vue'
|
import { computed, onActivated, onBeforeUnmount, onMounted, ref } from 'vue'
|
||||||
import { AgGridVue } from 'ag-grid-vue3'
|
import type { ColDef } from 'ag-grid-community'
|
||||||
import type { ColDef, GridApi } from 'ag-grid-community'
|
|
||||||
import localforage from 'localforage'
|
import localforage from 'localforage'
|
||||||
import { majorList } from '@/sql'
|
import { isMajorCodeInIndustryScope, majorList } from '@/sql'
|
||||||
import { myTheme, gridOptions } from '@/lib/diyAgGridOptions'
|
|
||||||
import { decimalAggSum, roundTo, sumByNumber } from '@/lib/decimal'
|
import { decimalAggSum, roundTo, sumByNumber } from '@/lib/decimal'
|
||||||
import { formatThousands } from '@/lib/numberFormat'
|
import { formatThousands } from '@/lib/numberFormat'
|
||||||
import { AG_GRID_LOCALE_CN } from '@ag-grid-community/locale'
|
import CommonAgGrid from '@/components/common/CommonAgGrid.vue'
|
||||||
import MethodUnavailableNotice from '@/components/views/pricingView/MethodUnavailableNotice.vue'
|
import MethodUnavailableNotice from '@/components/common/MethodUnavailableNotice.vue'
|
||||||
|
|
||||||
interface DictLeaf {
|
interface DictLeaf {
|
||||||
id: string
|
id: string
|
||||||
@ -171,9 +169,7 @@ const rebuildDictByIndustry = (industryCode: string) => {
|
|||||||
idLabelMap.value = new Map()
|
idLabelMap.value = new Map()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
const filteredEntries = majorEntries.filter(([, item]) =>
|
const filteredEntries = majorEntries.filter(([, item]) => isMajorCodeInIndustryScope(item.code, industryCode))
|
||||||
item.code === industryCode || item.code.startsWith(`${industryCode}-`)
|
|
||||||
)
|
|
||||||
const nextDict = buildDetailDict(filteredEntries)
|
const nextDict = buildDetailDict(filteredEntries)
|
||||||
const nextLabelMap = new Map<string, string>()
|
const nextLabelMap = new Map<string, string>()
|
||||||
for (const group of nextDict) {
|
for (const group of nextDict) {
|
||||||
@ -423,27 +419,14 @@ const processCellFromClipboard = (params: any) => {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div ref="agGridRef" class="ag-theme-quartz w-full flex-1 min-h-0 h-full">
|
<div ref="agGridRef" class="ag-theme-quartz w-full flex-1 min-h-0 h-full">
|
||||||
<AgGridVue
|
<CommonAgGrid
|
||||||
:style="{ height: '100%' }"
|
|
||||||
:rowData="detailRows"
|
:rowData="detailRows"
|
||||||
:pinnedTopRowData="pinnedTopRowData"
|
:pinnedTopRowData="pinnedTopRowData"
|
||||||
:columnDefs="columnDefs"
|
:columnDefs="columnDefs"
|
||||||
:autoGroupColumnDef="autoGroupColumnDef"
|
:autoGroupColumnDef="autoGroupColumnDef"
|
||||||
:gridOptions="gridOptions"
|
|
||||||
:theme="myTheme"
|
|
||||||
@cell-value-changed="handleCellValueChanged"
|
|
||||||
:suppressColumnVirtualisation="true"
|
|
||||||
:suppressRowVirtualisation="true"
|
|
||||||
:cellSelection="{ handle: { mode: 'range' } }"
|
|
||||||
:enableClipboard="true"
|
|
||||||
:localeText="AG_GRID_LOCALE_CN"
|
|
||||||
:tooltipShowDelay="500"
|
|
||||||
:headerHeight="50"
|
|
||||||
:suppressHorizontalScroll="true"
|
|
||||||
:processCellForClipboard="processCellForClipboard"
|
:processCellForClipboard="processCellForClipboard"
|
||||||
:processCellFromClipboard="processCellFromClipboard"
|
:processCellFromClipboard="processCellFromClipboard"
|
||||||
:undoRedoCellEditing="true"
|
@cell-value-changed="handleCellValueChanged"
|
||||||
:undoRedoCellEditingLimit="20"
|
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -11,7 +11,7 @@ import { parseNumberOrNull } from '@/lib/number'
|
|||||||
import { formatThousands, formatThousandsFlexible } from '@/lib/numberFormat'
|
import { formatThousands, formatThousandsFlexible } from '@/lib/numberFormat'
|
||||||
import { getPricingMethodTotalsForServices } from '@/lib/pricingMethodTotals'
|
import { getPricingMethodTotalsForServices } from '@/lib/pricingMethodTotals'
|
||||||
import { ZXFW_RELOAD_SERVICE_KEY } from '@/lib/zxFwPricingSync'
|
import { ZXFW_RELOAD_SERVICE_KEY } from '@/lib/zxFwPricingSync'
|
||||||
import { Search } from 'lucide-vue-next'
|
import { Pencil, Eraser, Trash2 } from 'lucide-vue-next'
|
||||||
import {
|
import {
|
||||||
AlertDialogAction,
|
AlertDialogAction,
|
||||||
AlertDialogCancel,
|
AlertDialogCancel,
|
||||||
@ -31,7 +31,7 @@ import {
|
|||||||
DialogTrigger
|
DialogTrigger
|
||||||
} from 'reka-ui'
|
} from 'reka-ui'
|
||||||
import { Button } from '@/components/ui/button'
|
import { Button } from '@/components/ui/button'
|
||||||
import { TooltipContent, TooltipProvider, TooltipRoot, TooltipTrigger } from '@/components/ui/tooltip'
|
import { TooltipProvider } from '@/components/ui/tooltip'
|
||||||
import { serviceList } from '@/sql'
|
import { serviceList } from '@/sql'
|
||||||
import { useTabStore } from '@/pinia/tab'
|
import { useTabStore } from '@/pinia/tab'
|
||||||
import { usePricingPaneReloadStore } from '@/pinia/pricingPaneReload'
|
import { usePricingPaneReloadStore } from '@/pinia/pricingPaneReload'
|
||||||
@ -93,74 +93,6 @@ const isFixedRow = (row?: DetailRow | null) => row?.id === fixedBudgetRow.id
|
|||||||
|
|
||||||
const selectedIds = ref<string[]>([])
|
const selectedIds = ref<string[]>([])
|
||||||
const detailRows = ref<DetailRow[]>([])
|
const detailRows = ref<DetailRow[]>([])
|
||||||
const rootRef = ref<HTMLElement | null>(null)
|
|
||||||
const gridSectionRef = ref<HTMLElement | null>(null)
|
|
||||||
const agGridRef = ref<HTMLElement | null>(null)
|
|
||||||
const agGridHeight = ref(580)
|
|
||||||
let snapScrollHost: HTMLElement | null = null
|
|
||||||
let snapTimer: ReturnType<typeof setTimeout> | null = null
|
|
||||||
let snapLockTimer: ReturnType<typeof setTimeout> | null = null
|
|
||||||
let isSnapping = false
|
|
||||||
let hostResizeObserver: ResizeObserver | null = null
|
|
||||||
|
|
||||||
const updateGridCardHeight = () => {
|
|
||||||
if (!snapScrollHost || !rootRef.value) return
|
|
||||||
const contentWrap = rootRef.value.parentElement
|
|
||||||
const style = contentWrap ? window.getComputedStyle(contentWrap) : null
|
|
||||||
const paddingTop = style ? Number.parseFloat(style.paddingTop || '0') || 0 : 0
|
|
||||||
const paddingBottom = style ? Number.parseFloat(style.paddingBottom || '0') || 0 : 0
|
|
||||||
const nextHeight = Math.max(360, Math.floor(snapScrollHost.clientHeight - paddingTop - paddingBottom))
|
|
||||||
agGridHeight.value = nextHeight-40
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
const bindSnapScrollHost = () => {
|
|
||||||
snapScrollHost = rootRef.value?.closest('[data-slot="scroll-area-viewport"]') as HTMLElement | null
|
|
||||||
if (!snapScrollHost) return
|
|
||||||
snapScrollHost.addEventListener('scroll', handleSnapHostScroll, { passive: true })
|
|
||||||
hostResizeObserver?.disconnect()
|
|
||||||
hostResizeObserver = new ResizeObserver(() => {
|
|
||||||
updateGridCardHeight()
|
|
||||||
})
|
|
||||||
hostResizeObserver.observe(snapScrollHost)
|
|
||||||
updateGridCardHeight()
|
|
||||||
}
|
|
||||||
|
|
||||||
const unbindSnapScrollHost = () => {
|
|
||||||
if (snapScrollHost) {
|
|
||||||
snapScrollHost.removeEventListener('scroll', handleSnapHostScroll)
|
|
||||||
}
|
|
||||||
hostResizeObserver?.disconnect()
|
|
||||||
hostResizeObserver = null
|
|
||||||
snapScrollHost = null
|
|
||||||
}
|
|
||||||
|
|
||||||
const trySnapToGrid = () => {
|
|
||||||
if (isSnapping || !snapScrollHost || !agGridRef.value) return
|
|
||||||
|
|
||||||
const hostRect = snapScrollHost.getBoundingClientRect()
|
|
||||||
const gridRect = agGridRef.value.getBoundingClientRect()
|
|
||||||
const offsetTop = gridRect.top - hostRect.top
|
|
||||||
const inVisibleBand = gridRect.bottom > hostRect.top + 40 && gridRect.top < hostRect.bottom - 40
|
|
||||||
const inSnapRange = offsetTop > -120 && offsetTop < 180
|
|
||||||
|
|
||||||
if (!inVisibleBand || !inSnapRange) return
|
|
||||||
|
|
||||||
isSnapping = true
|
|
||||||
agGridRef.value.scrollIntoView({ behavior: 'smooth', block: 'start' })
|
|
||||||
if (snapLockTimer) clearTimeout(snapLockTimer)
|
|
||||||
snapLockTimer = setTimeout(() => {
|
|
||||||
isSnapping = false
|
|
||||||
}, 420)
|
|
||||||
}
|
|
||||||
|
|
||||||
function handleSnapHostScroll() {
|
|
||||||
if (isSnapping) return
|
|
||||||
if (snapTimer) clearTimeout(snapTimer)
|
|
||||||
snapTimer = setTimeout(() => {
|
|
||||||
trySnapToGrid()
|
|
||||||
}, 90)
|
|
||||||
}
|
|
||||||
|
|
||||||
const pickerOpen = ref(false)
|
const pickerOpen = ref(false)
|
||||||
const pickerTempIds = ref<string[]>([])
|
const pickerTempIds = ref<string[]>([])
|
||||||
@ -168,6 +100,8 @@ const pickerSearch = ref('')
|
|||||||
const pickerListScrollRef = ref<HTMLElement | null>(null)
|
const pickerListScrollRef = ref<HTMLElement | null>(null)
|
||||||
const clearConfirmOpen = ref(false)
|
const clearConfirmOpen = ref(false)
|
||||||
const pendingClearServiceId = ref<string | null>(null)
|
const pendingClearServiceId = ref<string | null>(null)
|
||||||
|
const deleteConfirmOpen = ref(false)
|
||||||
|
const pendingDeleteServiceId = ref<string | null>(null)
|
||||||
const dragSelecting = ref(false)
|
const dragSelecting = ref(false)
|
||||||
const dragMoved = ref(false)
|
const dragMoved = ref(false)
|
||||||
let dragSelectChecked = false
|
let dragSelectChecked = false
|
||||||
@ -249,10 +183,23 @@ const pendingClearServiceName = computed(() => {
|
|||||||
return pendingClearServiceId.value
|
return pendingClearServiceId.value
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const pendingDeleteServiceName = computed(() => {
|
||||||
|
if (!pendingDeleteServiceId.value) return ''
|
||||||
|
const row = detailRows.value.find(item => item.id === pendingDeleteServiceId.value)
|
||||||
|
if (row) return `${row.code}${row.name}`
|
||||||
|
const dict = serviceById.get(pendingDeleteServiceId.value)
|
||||||
|
if (dict) return `${dict.code}${dict.name}`
|
||||||
|
return pendingDeleteServiceId.value
|
||||||
|
})
|
||||||
|
|
||||||
const handleClearConfirmOpenChange = (open: boolean) => {
|
const handleClearConfirmOpenChange = (open: boolean) => {
|
||||||
clearConfirmOpen.value = open
|
clearConfirmOpen.value = open
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const handleDeleteConfirmOpenChange = (open: boolean) => {
|
||||||
|
deleteConfirmOpen.value = open
|
||||||
|
}
|
||||||
|
|
||||||
const requestClearRow = (row: DetailRow) => {
|
const requestClearRow = (row: DetailRow) => {
|
||||||
if (isFixedRow(row)) return
|
if (isFixedRow(row)) return
|
||||||
pendingClearServiceId.value = row.id
|
pendingClearServiceId.value = row.id
|
||||||
@ -273,6 +220,26 @@ const confirmClearRow = async () => {
|
|||||||
pendingClearServiceId.value = null
|
pendingClearServiceId.value = null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const requestDeleteRow = (row: DetailRow) => {
|
||||||
|
if (isFixedRow(row)) return
|
||||||
|
pendingDeleteServiceId.value = row.id
|
||||||
|
deleteConfirmOpen.value = true
|
||||||
|
}
|
||||||
|
|
||||||
|
const confirmDeleteRow = async () => {
|
||||||
|
const id = pendingDeleteServiceId.value
|
||||||
|
if (!id) return
|
||||||
|
const row = detailRows.value.find(item => item.id === id)
|
||||||
|
if (!row || isFixedRow(row)) {
|
||||||
|
deleteConfirmOpen.value = false
|
||||||
|
pendingDeleteServiceId.value = null
|
||||||
|
return
|
||||||
|
}
|
||||||
|
await removeRow(row)
|
||||||
|
deleteConfirmOpen.value = false
|
||||||
|
pendingDeleteServiceId.value = null
|
||||||
|
}
|
||||||
|
|
||||||
const filteredServiceDict = computed(() => {
|
const filteredServiceDict = computed(() => {
|
||||||
const keyword = pickerSearch.value.trim()
|
const keyword = pickerSearch.value.trim()
|
||||||
if (!keyword) return serviceDict
|
if (!keyword) return serviceDict
|
||||||
@ -393,6 +360,12 @@ const openEditTab = (row: DetailRow) => {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const removeRow = async (row: DetailRow) => {
|
||||||
|
if (isFixedRow(row)) return
|
||||||
|
const nextIds = selectedIds.value.filter(id => id !== row.id)
|
||||||
|
await handleServiceSelectionChange(nextIds)
|
||||||
|
}
|
||||||
|
|
||||||
const ActionCellRenderer = defineComponent({
|
const ActionCellRenderer = defineComponent({
|
||||||
name: 'ActionCellRenderer',
|
name: 'ActionCellRenderer',
|
||||||
props: {
|
props: {
|
||||||
@ -405,24 +378,20 @@ const ActionCellRenderer = defineComponent({
|
|||||||
return () => {
|
return () => {
|
||||||
if (isFixedRow(props.params.data)) return null
|
if (isFixedRow(props.params.data)) return null
|
||||||
return h('div', { class: 'zxfw-action-wrap' }, [
|
return h('div', { class: 'zxfw-action-wrap' }, [
|
||||||
h(TooltipRoot, null, {
|
h('div', { class: 'zxfw-action-group' }, [
|
||||||
default: () => [
|
h('button', { class: 'zxfw-action-btn', 'data-action': 'edit', type: 'button' }, [
|
||||||
h(TooltipTrigger, { asChild: true }, {
|
h(Pencil, { size: 13, 'aria-hidden': 'true' }),
|
||||||
default: () =>
|
h('span', '编辑')
|
||||||
h('button', { class: 'zxfw-action-btn', 'data-action': 'edit' }, '✏️')
|
]),
|
||||||
}),
|
h('button', { class: 'zxfw-action-btn', 'data-action': 'clear', type: 'button' }, [
|
||||||
h(TooltipContent, { side: 'top' }, { default: () => '编辑' })
|
h(Eraser, { size: 13, 'aria-hidden': 'true' }),
|
||||||
]
|
h('span', '清空')
|
||||||
}),
|
]),
|
||||||
h(TooltipRoot, null, {
|
h('button', { class: 'zxfw-action-btn zxfw-action-btn--danger', 'data-action': 'delete', type: 'button' }, [
|
||||||
default: () => [
|
h(Trash2, { size: 13, 'aria-hidden': 'true' }),
|
||||||
h(TooltipTrigger, { asChild: true }, {
|
h('span', '删除')
|
||||||
default: () =>
|
])
|
||||||
h('button', { class: 'zxfw-action-btn', 'data-action': 'clear' }, '🧹')
|
])
|
||||||
}),
|
|
||||||
h(TooltipContent, { side: 'top' }, { default: () => '清空' })
|
|
||||||
]
|
|
||||||
})
|
|
||||||
])
|
])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -525,9 +494,9 @@ const columnDefs: ColDef<DetailRow>[] = [
|
|||||||
{
|
{
|
||||||
headerName: '操作',
|
headerName: '操作',
|
||||||
field: 'actions',
|
field: 'actions',
|
||||||
minWidth: 50,
|
minWidth: 220,
|
||||||
flex: 1,
|
flex: 2,
|
||||||
maxWidth: 120,
|
maxWidth: 260,
|
||||||
editable: false,
|
editable: false,
|
||||||
sortable: false,
|
sortable: false,
|
||||||
filter: false,
|
filter: false,
|
||||||
@ -551,6 +520,10 @@ const detailGridOptions: GridOptions<DetailRow> = {
|
|||||||
}
|
}
|
||||||
if (action === 'edit') {
|
if (action === 'edit') {
|
||||||
openEditTab(params.data)
|
openEditTab(params.data)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (action === 'delete') {
|
||||||
|
requestDeleteRow(params.data)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -833,32 +806,20 @@ const handleCellValueChanged = () => {
|
|||||||
}, 1000)
|
}, 1000)
|
||||||
}
|
}
|
||||||
|
|
||||||
const scrollToGridSection = () => {
|
|
||||||
const target = gridSectionRef.value || agGridRef.value
|
|
||||||
target?.scrollIntoView({ behavior: 'smooth', block: 'start' })
|
|
||||||
}
|
|
||||||
|
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
await loadFromIndexedDB()
|
await loadFromIndexedDB()
|
||||||
bindSnapScrollHost()
|
|
||||||
requestAnimationFrame(() => {
|
|
||||||
updateGridCardHeight()
|
|
||||||
})
|
|
||||||
})
|
})
|
||||||
|
|
||||||
onBeforeUnmount(() => {
|
onBeforeUnmount(() => {
|
||||||
unbindSnapScrollHost()
|
|
||||||
stopDragSelect()
|
stopDragSelect()
|
||||||
if (gridPersistTimer) clearTimeout(gridPersistTimer)
|
if (gridPersistTimer) clearTimeout(gridPersistTimer)
|
||||||
if (snapTimer) clearTimeout(snapTimer)
|
|
||||||
if (snapLockTimer) clearTimeout(snapLockTimer)
|
|
||||||
void saveToIndexedDB()
|
void saveToIndexedDB()
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<TooltipProvider>
|
<TooltipProvider>
|
||||||
<div ref="rootRef" class="space-y-6">
|
<div class="h-full min-h-0 flex flex-col gap-2">
|
||||||
<!-- 原“浏览框选择服务”实现已抽离并停用,改为直接复选框勾选 -->
|
<!-- 原“浏览框选择服务”实现已抽离并停用,改为直接复选框勾选 -->
|
||||||
<!-- <DialogRoot v-model:open="pickerOpen" @update:open="handlePickerOpenChange" /> -->
|
<!-- <DialogRoot v-model:open="pickerOpen" @update:open="handlePickerOpenChange" /> -->
|
||||||
<ServiceCheckboxSelector
|
<ServiceCheckboxSelector
|
||||||
@ -868,23 +829,19 @@ onBeforeUnmount(() => {
|
|||||||
/>
|
/>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
ref="gridSectionRef"
|
class="rounded-lg border bg-card xmMx flex min-h-0 flex-1 flex-col overflow-hidden"
|
||||||
class="rounded-lg border bg-card xmMx scroll-mt-3" :style="{ height: `${agGridHeight}px` }"
|
|
||||||
>
|
>
|
||||||
<div class="flex items-center justify-between border-b px-4 py-3">
|
<div class="flex items-center justify-between border-b px-3 py-2">
|
||||||
<h3
|
<h3 class="text-xs font-semibold text-foreground leading-none">
|
||||||
class="text-sm font-semibold text-foreground cursor-pointer select-none transition-colors hover:text-primary"
|
|
||||||
@click="scrollToGridSection"
|
|
||||||
>
|
|
||||||
咨询服务明细
|
咨询服务明细
|
||||||
</h3>
|
</h3>
|
||||||
<div class="text-xs text-muted-foreground">按服务词典生成</div>
|
<div class="text-[11px] text-muted-foreground leading-none">按服务词典生成</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div ref="agGridRef" class="ag-theme-quartz w-full h-full" >
|
<div class="ag-theme-quartz w-full flex-1 min-h-0" >
|
||||||
<AgGridVue :style="{ height: '100%' }" :rowData="detailRows" :columnDefs="columnDefs" :gridOptions="detailGridOptions"
|
<AgGridVue :style="{ height: '100%' }" :rowData="detailRows" :columnDefs="columnDefs" :gridOptions="detailGridOptions"
|
||||||
:theme="myTheme" @cell-value-changed="handleCellValueChanged" :enableClipboard="true"
|
:theme="myTheme" @cell-value-changed="handleCellValueChanged" :enableClipboard="true"
|
||||||
:localeText="AG_GRID_LOCALE_CN" :tooltipShowDelay="500" :headerHeight="50" :undoRedoCellEditing="true"
|
:localeText="AG_GRID_LOCALE_CN" :tooltipShowDelay="500" :headerHeight="30" :undoRedoCellEditing="true"
|
||||||
:undoRedoCellEditingLimit="20" />
|
:undoRedoCellEditingLimit="20" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -909,6 +866,26 @@ onBeforeUnmount(() => {
|
|||||||
</AlertDialogPortal>
|
</AlertDialogPortal>
|
||||||
</AlertDialogRoot>
|
</AlertDialogRoot>
|
||||||
|
|
||||||
|
<AlertDialogRoot :open="deleteConfirmOpen" @update:open="handleDeleteConfirmOpenChange">
|
||||||
|
<AlertDialogPortal>
|
||||||
|
<AlertDialogOverlay class="fixed inset-0 z-50 bg-black/45" />
|
||||||
|
<AlertDialogContent class="fixed left-1/2 top-1/2 z-[70] w-[92vw] max-w-md -translate-x-1/2 -translate-y-1/2 rounded-lg border bg-background p-5 shadow-xl">
|
||||||
|
<AlertDialogTitle class="text-base font-semibold">确认删除服务</AlertDialogTitle>
|
||||||
|
<AlertDialogDescription class="mt-2 text-sm text-muted-foreground">
|
||||||
|
将删除“{{ pendingDeleteServiceName }}”是否继续?
|
||||||
|
</AlertDialogDescription>
|
||||||
|
<div class="mt-4 flex items-center justify-end gap-2">
|
||||||
|
<AlertDialogCancel as-child>
|
||||||
|
<Button variant="outline">取消</Button>
|
||||||
|
</AlertDialogCancel>
|
||||||
|
<AlertDialogAction as-child>
|
||||||
|
<Button variant="destructive" @click="confirmDeleteRow">确认删除</Button>
|
||||||
|
</AlertDialogAction>
|
||||||
|
</div>
|
||||||
|
</AlertDialogContent>
|
||||||
|
</AlertDialogPortal>
|
||||||
|
</AlertDialogRoot>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</TooltipProvider>
|
</TooltipProvider>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
291
src/sql.ts
291
src/sql.ts
@ -1,7 +1,7 @@
|
|||||||
// @ts-nocheck
|
// @ts-nocheck
|
||||||
import { addNumbers, roundTo, toDecimal } from '@/lib/decimal'
|
import { addNumbers, roundTo, toDecimal } from '@/lib/decimal'
|
||||||
import { formatThousands } from '@/lib/numberFormat'
|
import { formatThousands } from '@/lib/numberFormat'
|
||||||
|
import ExcelJS from "ExcelJS";
|
||||||
const numberFormatter = (value: unknown, fractionDigits = 2) =>
|
const numberFormatter = (value: unknown, fractionDigits = 2) =>
|
||||||
formatThousands(value, fractionDigits)
|
formatThousands(value, fractionDigits)
|
||||||
|
|
||||||
@ -9,120 +9,127 @@ const toFiniteNumber = (value: unknown) => {
|
|||||||
const num = Number(value)
|
const num = Number(value)
|
||||||
return Number.isFinite(num) ? num : 0
|
return Number.isFinite(num) ? num : 0
|
||||||
}
|
}
|
||||||
|
hideInIndustrySelector: true
|
||||||
export const majorList = {
|
export const majorList = {
|
||||||
0: { code: 'E1', name: '交通运输工程通用专业', maxCoe: null, minCoe: null, defCoe: 1, desc: '' },
|
0: { code: 'E1', name: '交通运输工程通用专业',hideInIndustrySelector: true , maxCoe: null, minCoe: null, defCoe: null, desc: '', isRoad: true, isRailway: true, isWaterway: true, order: 1, hasCost: false, hasArea: false },
|
||||||
1: { code: 'E1-1', name: '征地(用海)补偿', maxCoe: null, minCoe: null, defCoe: 1, desc: '适用于交通建设项目征地(用海)补偿的施工图预算、招标工程量清单及清单预算(或最高投标限价)、清理概算(仅限铁路工程)、合同(工程)结算和造价鉴定、计算工程量、工程变更费用咨询、工程成本测(核)算' },
|
1: { code: 'E1-1', name: '征地(用海)补偿', maxCoe: null, minCoe: null, defCoe: 1, desc: '适用于交通建设项目征地(用海)补偿的施工图预算、招标工程量清单及清单预算(或最高投标限价)、清理概算(仅限铁路工程)、合同(工程)结算和造价鉴定、计算工程量、工程变更费用咨询、工程成本测(核)算', isRoad: true, isRailway: true, isWaterway: true, order: 2, hasCost: true, hasArea: true },
|
||||||
2: { code: 'E1-2', name: '拆迁补偿', maxCoe: null, minCoe: null, defCoe: 2.5, desc: '适用于交通建设项目拆迁补偿的施工图预算、招标工程量清单及清单预算(或最高投标限价)、清理概算(仅限铁路工程)、合同(工程)结算和造价鉴定、计算工程量、工程变更费用咨询、工程成本测(核)算' },
|
2: { code: 'E1-2', name: '拆迁补偿', maxCoe: null, minCoe: null, defCoe: 2.5, desc: '适用于交通建设项目拆迁补偿的施工图预算、招标工程量清单及清单预算(或最高投标限价)、清理概算(仅限铁路工程)、合同(工程)结算和造价鉴定、计算工程量、工程变更费用咨询、工程成本测(核)算', isRoad: true, isRailway: true, isWaterway: true, order: 3, hasCost: true, hasArea: true },
|
||||||
3: { code: 'E1-3', name: '迁改工程', maxCoe: null, minCoe: null, defCoe: 2, desc: '适用于交通建设项目迁改工程的施工图预算、招标工程量清单及清单预算(或最高投标限价)、清理概算(仅限铁路工程)、合同(工程)结算和造价鉴定、计算工程量、工程变更费用咨询、工程成本测(核)算' },
|
3: { code: 'E1-3', name: '迁改工程', maxCoe: null, minCoe: null, defCoe: 2, desc: '适用于交通建设项目迁改工程的施工图预算、招标工程量清单及清单预算(或最高投标限价)、清理概算(仅限铁路工程)、合同(工程)结算和造价鉴定、计算工程量、工程变更费用咨询、工程成本测(核)算', isRoad: true, isRailway: true, isWaterway: true, order: 4, hasCost: true, hasArea: false },
|
||||||
4: { code: 'E1-4', name: '工程建设其他费', maxCoe: null, minCoe: null, defCoe: 1, desc: '适用于交通建设项目的工程建设其他费的施工图预算、招标工程量清单及清单预算(或最高投标限价)、清理概算(仅限铁路工程)和造价鉴定、计算工程量、工程变更费用咨询、工程成本测(核)算' },
|
4: { code: 'E1-4', name: '工程建设其他费', maxCoe: null, minCoe: null, defCoe: 1, desc: '适用于交通建设项目的工程建设其他费的施工图预算、招标工程量清单及清单预算(或最高投标限价)、清理概算(仅限铁路工程)和造价鉴定、计算工程量、工程变更费用咨询、工程成本测(核)算', isRoad: true, isRailway: true, isWaterway: true, order: 5, hasCost: true, hasArea: false },
|
||||||
5: { code: 'E2', name: '公路工程专业', maxCoe: null, minCoe: null, defCoe: 1, desc: '适用于公路工程的全过程造价咨询、分阶段造价咨询、投资估算、初步设计概算、竣工决算和调整估算、调整概算(含征地拆迁和工程建设其他费)' },
|
5: { code: 'E1-5', name: '预备费', maxCoe: null, minCoe: null, defCoe: 1, desc: '', isRoad: true, isRailway: true, isWaterway: true, order: 6, hasCost: true, hasArea: false },
|
||||||
6: { code: 'E2-1', name: '临时工程', maxCoe: null, minCoe: null, defCoe: 1, desc: '适用于临时工程专业的施工图预算、招标工程量清单及清单预算(或最高投标限价)、合同(工程)结算和造价鉴定、计算工程量、工程变更费用咨询、工程成本测(核)算' },
|
6: { code: 'E1-6', name: '建设期贷款利息', maxCoe: null, minCoe: null, defCoe: 1, desc: '', isRoad: true, isRailway: true, isWaterway: true, order: 7, hasCost: true, hasArea: false },
|
||||||
7: { code: 'E2-2', name: '路基工程', maxCoe: null, minCoe: null, defCoe: 1.2, desc: '适用于路基工程专业的施工图预算、招标工程量清单及清单预算(或最高投标限价)、合同(工程)结算和造价鉴定、计算工程量、工程变更费用咨询、工程成本测(核)算' },
|
7: { code: 'E2', name: '公路工程专业', maxCoe: null, minCoe: null, defCoe: 1, desc: '适用于公路工程的全过程造价咨询、分阶段造价咨询、投资估算、初步设计概算、竣工决算和调整估算、调整概算(含征地拆迁和工程建设其他费)', isRoad: true, isRailway: false, isWaterway: false, order: 8, hasCost: false, hasArea: false },
|
||||||
8: { code: 'E2-3', name: '路面工程', maxCoe: null, minCoe: null, defCoe: 0.8, desc: '适用于路面工程专业的施工图预算、招标工程量清单及清单预算(或最高投标限价)、合同(工程)结算和造价鉴定、计算工程量、工程变更费用咨询、工程成本测(核)算' },
|
8: { code: 'E2-1', name: '临时工程', maxCoe: null, minCoe: null, defCoe: 1, desc: '适用于临时工程专业的施工图预算、招标工程量清单及清单预算(或最高投标限价)、合同(工程)结算和造价鉴定、计算工程量、工程变更费用咨询、工程成本测(核)算', isRoad: true, isRailway: false, isWaterway: false, order: 9, hasCost: true, hasArea: false },
|
||||||
9: { code: 'E2-4', name: '桥涵工程', maxCoe: null, minCoe: null, defCoe: 0.9, desc: '适用于桥梁涵洞工程专业的施工图预算、招标工程量清单及清单预算(或最高投标限价)、合同(工程)结算和造价鉴定、计算工程量、工程变更费用咨询、工程成本测(核)算' },
|
9: { code: 'E2-2', name: '路基工程', maxCoe: null, minCoe: null, defCoe: 1.2, desc: '适用于路基工程专业的施工图预算、招标工程量清单及清单预算(或最高投标限价)、合同(工程)结算和造价鉴定、计算工程量、工程变更费用咨询、工程成本测(核)算', isRoad: true, isRailway: false, isWaterway: false, order: 10, hasCost: true, hasArea: false },
|
||||||
10: { code: 'E2-5', name: '隧道工程', maxCoe: null, minCoe: null, defCoe: 1, desc: '适用于隧道工程专业的施工图预算、招标工程量清单及清单预算(或最高投标限价)、合同(工程)结算和造价鉴定、计算工程量、工程变更费用咨询、工程成本测(核)算' },
|
10: { code: 'E2-3', name: '路面工程', maxCoe: null, minCoe: null, defCoe: 0.8, desc: '适用于路面工程专业的施工图预算、招标工程量清单及清单预算(或最高投标限价)、合同(工程)结算和造价鉴定、计算工程量、工程变更费用咨询、工程成本测(核)算', isRoad: true, isRailway: false, isWaterway: false, order: 11, hasCost: true, hasArea: false },
|
||||||
11: { code: 'E2-6', name: '交叉工程', maxCoe: null, minCoe: null, defCoe: 1.1, desc: '适用于交叉工程专业的施工图预算、招标工程量清单及清单预算(或最高投标限价)、合同(工程)结算和造价鉴定、计算工程量、工程变更费用咨询、工程成本测(核)算' },
|
11: { code: 'E2-4', name: '桥涵工程', maxCoe: null, minCoe: null, defCoe: 0.9, desc: '适用于桥梁涵洞工程专业的施工图预算、招标工程量清单及清单预算(或最高投标限价)、合同(工程)结算和造价鉴定、计算工程量、工程变更费用咨询、工程成本测(核)算', isRoad: true, isRailway: false, isWaterway: false, order: 12, hasCost: true, hasArea: false },
|
||||||
12: { code: 'E2-7', name: '机电工程', maxCoe: null, minCoe: null, defCoe: 1.2, desc: '适用于机电工程专业的施工图预算、招标工程量清单及清单预算(或最高投标限价)和造价鉴定、计算工程量、工程变更费用咨询、工程成本测(核)算' },
|
12: { code: 'E2-5', name: '隧道工程', maxCoe: null, minCoe: null, defCoe: 1, desc: '适用于隧道工程专业的施工图预算、招标工程量清单及清单预算(或最高投标限价)、合同(工程)结算和造价鉴定、计算工程量、工程变更费用咨询、工程成本测(核)算', isRoad: true, isRailway: false, isWaterway: false, order: 13, hasCost: true, hasArea: false },
|
||||||
13: { code: 'E2-8', name: '交通安全设施工程', maxCoe: null, minCoe: null, defCoe: 1.2, desc: '适用于交通安全设施工程专业的施工图预算、招标工程量清单及清单预算(或最高投标限价)和造价鉴定、计算工程量、工程变更费用咨询、工程成本测(核)算' },
|
13: { code: 'E2-6', name: '交叉工程', maxCoe: null, minCoe: null, defCoe: 1.1, desc: '适用于交叉工程专业的施工图预算、招标工程量清单及清单预算(或最高投标限价)、合同(工程)结算和造价鉴定、计算工程量、工程变更费用咨询、工程成本测(核)算', isRoad: true, isRailway: false, isWaterway: false, order: 14, hasCost: true, hasArea: false },
|
||||||
14: { code: 'E2-9', name: '绿化及环境保护工程', maxCoe: null, minCoe: null, defCoe: 1.2, desc: '适用于绿化工程专业的施工图预算、招标工程量清单及清单预算(或最高投标限价)和造价鉴定、计算工程量、工程变更费用咨询、工程成本测(核)算' },
|
14: { code: 'E2-7', name: '机电工程', maxCoe: null, minCoe: null, defCoe: 1.2, desc: '适用于机电工程专业的施工图预算、招标工程量清单及清单预算(或最高投标限价)和造价鉴定、计算工程量、工程变更费用咨询、工程成本测(核)算', isRoad: true, isRailway: false, isWaterway: false, order: 15, hasCost: true, hasArea: false },
|
||||||
15: { code: 'E2-10', name: '房建工程', maxCoe: null, minCoe: null, defCoe: 2.5, desc: '适用于房建工程专业的施工图预算、招标工程量清单及清单预算(或最高投标限价)、合同(工程)结算和造价鉴定、计算工程量、工程变更费用咨询、工程成本测(核)算' },
|
15: { code: 'E2-8', name: '交通安全设施工程', maxCoe: null, minCoe: null, defCoe: 1.2, desc: '适用于交通安全设施工程专业的施工图预算、招标工程量清单及清单预算(或最高投标限价)和造价鉴定、计算工程量、工程变更费用咨询、工程成本测(核)算', isRoad: true, isRailway: false, isWaterway: false, order: 16, hasCost: true, hasArea: false },
|
||||||
16: { code: 'E3', name: '铁路工程专业', maxCoe: null, minCoe: null, defCoe: 1, desc: '适用于铁路工程的投资估算、初步设计概算、清理概算、竣工决算和调整估算、调整概算(含征地拆迁和工程建设其他费)' },
|
16: { code: 'E2-9', name: '绿化及环境保护工程', maxCoe: null, minCoe: null, defCoe: 1.2, desc: '适用于绿化工程专业的施工图预算、招标工程量清单及清单预算(或最高投标限价)和造价鉴定、计算工程量、工程变更费用咨询、工程成本测(核)算', isRoad: true, isRailway: false, isWaterway: false, order: 17, hasCost: true, hasArea: false },
|
||||||
17: { code: 'E3-1', name: '大型临时设施和过渡工程', maxCoe: null, minCoe: null, defCoe: 1, desc: '适用于大型临时设施和过渡工程专业的施工图预算、招标工程量清单及清单预算(或最高投标限价)、合同(工程)结算和造价鉴定、计算工程量、工程变更费用咨询、工程成本测(核)算' },
|
17: { code: 'E2-10', name: '房建工程', maxCoe: null, minCoe: null, defCoe: 2.5, desc: '适用于房建工程专业的施工图预算、招标工程量清单及清单预算(或最高投标限价)、合同(工程)结算和造价鉴定、计算工程量、工程变更费用咨询、工程成本测(核)算', isRoad: true, isRailway: false, isWaterway: false, order: 18, hasCost: true, hasArea: false },
|
||||||
18: { code: 'E3-2', name: '路基工程', maxCoe: null, minCoe: null, defCoe: 1.2, desc: '适用于路基工程专业的施工图预算、招标工程量清单及清单预算(或最高投标限价)、合同(工程)结算和造价鉴定、计算工程量、工程变更费用咨询、工程成本测(核)算' },
|
18: { code: 'E3', name: '铁路工程专业', maxCoe: null, minCoe: null, defCoe: 1, desc: '适用于铁路工程的投资估算、初步设计概算、清理概算、竣工决算和调整估算、调整概算(含征地拆迁和工程建设其他费)', isRoad: false, isRailway: true, isWaterway: false, order: 19, hasCost: false, hasArea: false },
|
||||||
19: { code: 'E3-3', name: '桥涵工程', maxCoe: null, minCoe: null, defCoe: 0.9, desc: '适用于桥涵工程专业的施工图预算、招标工程量清单及清单预算(或最高投标限价)、合同(工程)结算和造价鉴定、计算工程量、工程变更费用咨询、工程成本测(核)算' },
|
19: { code: 'E3-1', name: '大型临时设施和过渡工程', maxCoe: null, minCoe: null, defCoe: 1, desc: '适用于大型临时设施和过渡工程专业的施工图预算、招标工程量清单及清单预算(或最高投标限价)、合同(工程)结算和造价鉴定、计算工程量、工程变更费用咨询、工程成本测(核)算', isRoad: false, isRailway: true, isWaterway: false, order: 20, hasCost: true, hasArea: false },
|
||||||
20: { code: 'E3-4', name: '隧道及明洞工程', maxCoe: null, minCoe: null, defCoe: 1, desc: '适用于隧道及明洞工程专业的施工图预算、招标工程量清单及清单预算(或最高投标限价)、合同(工程)结算、竣工决算和造价鉴定、计算工程量、工程变更费用咨询、工程成本测(核)算' },
|
20: { code: 'E3-2', name: '路基工程', maxCoe: null, minCoe: null, defCoe: 1.2, desc: '适用于路基工程专业的施工图预算、招标工程量清单及清单预算(或最高投标限价)、合同(工程)结算和造价鉴定、计算工程量、工程变更费用咨询、工程成本测(核)算', isRoad: false, isRailway: true, isWaterway: false, order: 21, hasCost: true, hasArea: false },
|
||||||
21: { code: 'E3-5', name: '轨道工程', maxCoe: null, minCoe: null, defCoe: 0.3, desc: '适用于轨道工程专业的施工图预算、招标工程量清单及清单预算(或最高投标限价)、合同(工程)结算和造价鉴定、计算工程量、工程变更费用咨询、工程成本测(核)算' },
|
21: { code: 'E3-3', name: '桥涵工程', maxCoe: null, minCoe: null, defCoe: 0.9, desc: '适用于桥涵工程专业的施工图预算、招标工程量清单及清单预算(或最高投标限价)、合同(工程)结算和造价鉴定、计算工程量、工程变更费用咨询、工程成本测(核)算', isRoad: false, isRailway: true, isWaterway: false, order: 22, hasCost: true, hasArea: false },
|
||||||
22: { code: 'E3-6', name: '通信、信号、信息及灾害监测工程', maxCoe: null, minCoe: null, defCoe: 2, desc: '适用于通信、信号、信息及防灾监测工程专业的施工图预算、招标工程量清单及清单预算(或最高投标限价)、合同(工程)结算和造价鉴定、计算工程量、工程变更费用咨询、工程成本测(核)算' },
|
22: { code: 'E3-4', name: '隧道及明洞工程', maxCoe: null, minCoe: null, defCoe: 1, desc: '适用于隧道及明洞工程专业的施工图预算、招标工程量清单及清单预算(或最高投标限价)、合同(工程)结算、竣工决算和造价鉴定、计算工程量、工程变更费用咨询、工程成本测(核)算', isRoad: false, isRailway: true, isWaterway: false, order: 23, hasCost: true, hasArea: false },
|
||||||
23: { code: 'E3-7', name: '电力及电力牵引供电工程', maxCoe: null, minCoe: null, defCoe: 1.5, desc: '适用于电力及电力牵引供电工程专业的施工图预算、招标工程量清单及清单预算(或最高投标限价)、合同(工程)结算和造价鉴定、计算工程量、工程变更费用咨询、工程成本测(核)算' },
|
23: { code: 'E3-5', name: '轨道工程', maxCoe: null, minCoe: null, defCoe: 0.3, desc: '适用于轨道工程专业的施工图预算、招标工程量清单及清单预算(或最高投标限价)、合同(工程)结算和造价鉴定、计算工程量、工程变更费用咨询、工程成本测(核)算', isRoad: false, isRailway: true, isWaterway: false, order: 24, hasCost: true, hasArea: false },
|
||||||
24: { code: 'E3-8', name: '房建工程(房屋建筑及附属工程)', maxCoe: null, minCoe: null, defCoe: 2.5, desc: '适用于房屋建筑及附属工程专业的施工图预算、招标工程量清单及清单预算(或最高投标限价)、合同(工程)结算和造价鉴定、计算工程量、工程变更费用咨询、工程成本测(核)算' },
|
24: { code: 'E3-6', name: '通信、信号、信息及灾害监测工程', maxCoe: null, minCoe: null, defCoe: 2, desc: '适用于通信、信号、信息及防灾监测工程专业的施工图预算、招标工程量清单及清单预算(或最高投标限价)、合同(工程)结算和造价鉴定、计算工程量、工程变更费用咨询、工程成本测(核)算', isRoad: false, isRailway: true, isWaterway: false, order: 25, hasCost: true, hasArea: false },
|
||||||
25: { code: 'E3-9', name: '装饰装修工程', maxCoe: null, minCoe: null, defCoe: 2.7, desc: '适用于装饰装修工程专业的施工图预算、招标工程量清单及清单预算(或最高投标限价)、合同(工程)结算和造价鉴定、计算工程量、工程变更费用咨询、工程成本测(核)算' },
|
25: { code: 'E3-7', name: '电力及电力牵引供电工程', maxCoe: null, minCoe: null, defCoe: 1.5, desc: '适用于电力及电力牵引供电工程专业的施工图预算、招标工程量清单及清单预算(或最高投标限价)、合同(工程)结算和造价鉴定、计算工程量、工程变更费用咨询、工程成本测(核)算', isRoad: false, isRailway: true, isWaterway: false, order: 26, hasCost: true, hasArea: false },
|
||||||
26: { code: 'E4', name: '水运工程专业', maxCoe: null, minCoe: null, defCoe: 1, desc: '适用于水运工程的投资估算、初步设计概算、竣工决算和调整估算、调整概算(含征地拆迁和工程建设其他费)' },
|
26: { code: 'E3-8', name: '房建工程(房屋建筑及附属工程)', maxCoe: null, minCoe: null, defCoe: 2.5, desc: '适用于房屋建筑及附属工程专业的施工图预算、招标工程量清单及清单预算(或最高投标限价)、合同(工程)结算和造价鉴定、计算工程量、工程变更费用咨询、工程成本测(核)算', isRoad: false, isRailway: true, isWaterway: false, order: 27, hasCost: true, hasArea: false },
|
||||||
27: { code: 'E4-1', name: '临时工程', maxCoe: null, minCoe: null, defCoe: 1.1, desc: '适用于临时工程专业的施工图预算、招标工程量清单及清单预算(或最高投标限价)、合同(工程)结算、竣工决算和造价鉴定、计算工程量、工程变更费用咨询、工程成本测(核)算' },
|
27: { code: 'E3-9', name: '装饰装修工程', maxCoe: null, minCoe: null, defCoe: 2.7, desc: '适用于装饰装修工程专业的施工图预算、招标工程量清单及清单预算(或最高投标限价)、合同(工程)结算和造价鉴定、计算工程量、工程变更费用咨询、工程成本测(核)算', isRoad: false, isRailway: true, isWaterway: false, order: 28, hasCost: true, hasArea: false },
|
||||||
28: { code: 'E4-2', name: '土建工程', maxCoe: null, minCoe: null, defCoe: 1, desc: '适用于土建工程专业的施工图预算、招标工程量清单及清单预算(或最高投标限价)、合同(工程)结算、竣工决算和造价鉴定、计算工程量、工程变更费用咨询、工程成本测(核)算' },
|
28: { code: 'E4', name: '水运工程专业', maxCoe: null, minCoe: null, defCoe: 1, desc: '适用于水运工程的投资估算、初步设计概算、竣工决算和调整估算、调整概算(含征地拆迁和工程建设其他费)', isRoad: false, isRailway: false, isWaterway: true, order: 29, hasCost: false, hasArea: false },
|
||||||
29: { code: 'E4-3', name: '机电与金属结构工程', maxCoe: null, minCoe: null, defCoe: 1.5, desc: '适用于机电与金属结构专业的施工图预算、招标工程量清单及清单预算(或最高投标限价)、合同(工程)结算和造价鉴定、计算工程量、工程变更费用咨询、工程成本测(核)算' },
|
29: { code: 'E4-1', name: '临时工程', maxCoe: null, minCoe: null, defCoe: 1.1, desc: '适用于临时工程专业的施工图预算、招标工程量清单及清单预算(或最高投标限价)、合同(工程)结算、竣工决算和造价鉴定、计算工程量、工程变更费用咨询、工程成本测(核)算', isRoad: false, isRailway: false, isWaterway: true, order: 30, hasCost: true, hasArea: false },
|
||||||
30: { code: 'E4-4', name: '设备工程', maxCoe: null, minCoe: null, defCoe: 1.5, desc: '适用于设备工程专业的施工图预算、招标工程量清单及清单预算(或最高投标限价)、合同(工程)结算和造价鉴定、计算工程量、工程变更费用咨询、工程成本测(核)算' },
|
30: { code: 'E4-2', name: '土建工程', maxCoe: null, minCoe: null, defCoe: 1, desc: '适用于土建工程专业的施工图预算、招标工程量清单及清单预算(或最高投标限价)、合同(工程)结算、竣工决算和造价鉴定、计算工程量、工程变更费用咨询、工程成本测(核)算', isRoad: false, isRailway: false, isWaterway: true, order: 31, hasCost: true, hasArea: false },
|
||||||
31: { code: 'E4-5', name: '附属房建工程(房屋建筑及附属工程)', maxCoe: null, minCoe: null, defCoe: 2.5, desc: '适用于房屋建筑与水运附属工程专业的施工图预算、招标工程量清单及清单预算(或最高投标限价)、合同(工程)结算和造价鉴定、计算工程量、工程变更费用咨询、工程成本测(核)算' },
|
31: { code: 'E4-3', name: '机电与金属结构工程', maxCoe: null, minCoe: null, defCoe: 1.5, desc: '适用于机电与金属结构专业的施工图预算、招标工程量清单及清单预算(或最高投标限价)、合同(工程)结算和造价鉴定、计算工程量、工程变更费用咨询、工程成本测(核)算', isRoad: false, isRailway: false, isWaterway: true, order: 32, hasCost: true, hasArea: false },
|
||||||
}
|
32: { code: 'E4-4', name: '设备工程', maxCoe: null, minCoe: null, defCoe: 1.5, desc: '适用于设备工程专业的施工图预算、招标工程量清单及清单预算(或最高投标限价)、合同(工程)结算和造价鉴定、计算工程量、工程变更费用咨询、工程成本测(核)算', isRoad: false, isRailway: false, isWaterway: true, order: 33, hasCost: true, hasArea: false },
|
||||||
export const serviceList = {
|
33: { code: 'E4-5', name: '附属房建工程(房屋建筑及附属工程)', maxCoe: null, minCoe: null, defCoe: 2.5, desc: '适用于房屋建筑与水运附属工程专业的施工图预算、招标工程量清单及清单预算(或最高投标限价)、合同(工程)结算和造价鉴定、计算工程量、工程变更费用咨询、工程成本测(核)算', isRoad: false, isRailway: false, isWaterway: true, order: 34, hasCost: true, hasArea: false },
|
||||||
0: { code: 'D1', name: '全过程造价咨询', maxCoe: null, minCoe: null, defCoe: 1, desc: '' },
|
|
||||||
1: { code: 'D2', name: '分阶段造价咨询', maxCoe: null, minCoe: null, defCoe: null, desc: '' },
|
|
||||||
2: { code: 'D2-1', name: '前期阶段造价咨询', maxCoe: null, minCoe: null, defCoe: 0.5, desc: '' },
|
|
||||||
3: { code: 'D2-2-1', name: '实施阶段造价咨询(公路、水运)', maxCoe: null, minCoe: null, defCoe: 0.55, desc: '本系数适用于公路和水运工程。' },
|
|
||||||
4: { code: 'D2-2-2', name: '实施阶段造价咨询(铁路)', maxCoe: null, minCoe: null, defCoe: 0.6, desc: '本系数适用于铁路工程。' },
|
|
||||||
5: { code: 'D3', name: '基本造价咨询', maxCoe: null, minCoe: null, defCoe: null, desc: '' },
|
|
||||||
6: { code: 'D3-1', name: '投资估算', maxCoe: null, minCoe: null, defCoe: 0.1, desc: '委托同一咨询人同时负责D3-1和D3-2时,D3-1和D3-2的合计调整系数为0.25。' },
|
|
||||||
7: { code: 'D3-2', name: '设计概算', maxCoe: null, minCoe: null, defCoe: 0.2, desc: '' },
|
|
||||||
8: { code: 'D3-3', name: '施工图预算', maxCoe: null, minCoe: null, defCoe: 0.25, desc: '委托同一咨询人同时负责D3-3和D3-4时,D3-3和D3-4的合计调整系数为0.3。' },
|
|
||||||
9: { code: 'D3-4', name: '招标工程量清单及清单预算(或最高投标限价)', maxCoe: null, minCoe: null, defCoe: 0.15, desc: '' },
|
|
||||||
10: { code: 'D3-5', name: '清理概算(仅限铁路)', maxCoe: null, minCoe: null, defCoe: 0.2, desc: '本系数适用于铁路工程。' },
|
|
||||||
11: { code: 'D3-6-1', name: '合同(工程)结算', maxCoe: null, minCoe: null, defCoe: 0.3, desc: '本系数适用于公路和水运工程。' },
|
|
||||||
12: { code: 'D3-6-2', name: '合同(工程)结算', maxCoe: null, minCoe: null, defCoe: 0.2, desc: '本系数适用于铁路工程。' },
|
|
||||||
13: { code: 'D3-7', name: '竣工决算', maxCoe: null, minCoe: null, defCoe: 0.1, desc: '' },
|
|
||||||
14: { code: 'D4', name: '专项造价咨询', maxCoe: null, minCoe: null, defCoe: null, desc: '' },
|
|
||||||
15: { code: 'D4-1', name: '工程造价顾问', maxCoe: null, minCoe: null, defCoe: 1, desc: '本表系数适用于采用工作量计价法基准预算的调整系数。' },
|
|
||||||
16: { code: 'D4-2', name: '造价政策制(修)订', maxCoe: null, minCoe: null, defCoe: 1, desc: '' },
|
|
||||||
17: { code: 'D4-3', name: '造价科学与技术研究', maxCoe: null, minCoe: null, defCoe: 1, desc: '' },
|
|
||||||
18: { code: 'D4-4', name: '定额测定', maxCoe: null, minCoe: null, defCoe: 1, desc: '' },
|
|
||||||
19: { code: 'D4-5', name: '造价信息咨询', maxCoe: null, minCoe: null, defCoe: 1, desc: '' },
|
|
||||||
20: { code: 'D4-6', name: '造价鉴定', maxCoe: null, minCoe: null, defCoe: 0.5, desc: '本表系数适用于采用规模计价法基准预算的调整系数。' },
|
|
||||||
21: { code: 'D4-7', name: '工程成本测算', maxCoe: null, minCoe: null, defCoe: 0.1, desc: '' },
|
|
||||||
22: { code: 'D4-8', name: '工程成本核算', maxCoe: null, minCoe: null, defCoe: 0.1, desc: '' },
|
|
||||||
23: { code: 'D4-9', name: '计算工程量', maxCoe: null, minCoe: null, defCoe: 0.2, desc: '' },
|
|
||||||
24: { code: 'D4-10', name: '工程变更费用咨询', maxCoe: null, minCoe: null, defCoe: 0.5, desc: '' },
|
|
||||||
25: { code: 'D4-11', name: '调整估算', maxCoe: 0.2, minCoe: 0.1, defCoe: 0.15, desc: '' },
|
|
||||||
26: { code: 'D4-12', name: '调整概算', maxCoe: 0.3, minCoe: 0.15, defCoe: 0.225, desc: '本表系数适用于采用规模计价法基准预算的系数;依据其调整时期所在建设阶段和基础资料的不同,其系数取值不同。' },
|
|
||||||
27: { code: 'D4-13', name: '造价检查', maxCoe: null, minCoe: null, defCoe: null, desc: '可按照服务工日数量×服务工日人工单价×综合预算系数;也可按照服务工日数量×服务工日综合预算单价。', notshowByzxflxs: true },
|
|
||||||
28: { code: 'D4-14', name: '其他专项咨询', maxCoe: null, minCoe: null, defCoe: null, desc: '可参照相同或相似服务的系数。', notshowByzxflxs: true },
|
|
||||||
};
|
|
||||||
//basicParam预算基数
|
|
||||||
|
|
||||||
export const taskList = {
|
|
||||||
0: { serviceID: 15, ref: 'C4-1', name: '工程造价日常顾问', basicParam: '服务月份数', required: true, unit: '万元/月', conversion: 10000, maxPrice: 0.5, minPrice: 0.3, defPrice: 0.4, desc: '' },
|
|
||||||
1: { serviceID: 15, ref: 'C4-2', name: '工程造价专项顾问', basicParam: '服务项目的造价金额', required: true, unit: '%', conversion: 0.01, maxPrice: null, minPrice: null, defPrice: 0.01, desc: '适用于涉及造价费用类的顾问' },
|
|
||||||
2: { serviceID: 16, ref: 'C5-1', name: '组织与调研工作', basicParam: '调研次数', required: true, unit: '万元/次', conversion: 10000, maxPrice: 2, minPrice: 1, defPrice: 1.5, desc: '' },
|
|
||||||
3: { serviceID: 16, ref: 'C5-2-1', name: '文件编写工作', basicParam: '文件份数', required: true, unit: '万元/份', conversion: 10000, maxPrice: 5, minPrice: 3, defPrice: 4, desc: '主编' },
|
|
||||||
4: { serviceID: 16, ref: 'C5-2-2', name: '文件编写工作', basicParam: '文件份数', required: true, unit: '万元/份', conversion: 10000, maxPrice: 3, minPrice: 1, defPrice: 2, desc: '参编' },
|
|
||||||
5: { serviceID: 16, ref: 'C5-3-1', name: '评审工作', basicParam: '评审次数', required: false, unit: '万元/次', conversion: 10000, maxPrice: 20, minPrice: 8, defPrice: 14, desc: '大型评审' },
|
|
||||||
6: { serviceID: 16, ref: 'C5-3-2', name: '评审工作', basicParam: '评审次数', required: false, unit: '万元/次', conversion: 10000, maxPrice: 10, minPrice: 5, defPrice: 7.5, desc: '中型评审' },
|
|
||||||
7: { serviceID: 16, ref: 'C5-3-3', name: '评审工作', basicParam: '评审次数', required: false, unit: '万元/次', conversion: 10000, maxPrice: 6, minPrice: 3, defPrice: 4.5, desc: '小型评审' },
|
|
||||||
8: { serviceID: 17, ref: 'C6-1', name: '组织与调研工作', basicParam: '调研次数', required: true, unit: '万元/次', conversion: 10000, maxPrice: 2, minPrice: 1, defPrice: 1.5, desc: '' },
|
|
||||||
9: { serviceID: 17, ref: 'C6-2-1', name: '研究及编写报告', basicParam: '文件份数', required: true, unit: '万元/份', conversion: 10000, maxPrice: 50, minPrice: 20, defPrice: 35, desc: '国家级' },
|
|
||||||
10: { serviceID: 17, ref: 'C6-2-2', name: '研究及编写报告', basicParam: '文件份数', required: true, unit: '万元/份', conversion: 10000, maxPrice: 20, minPrice: 10, defPrice: 15, desc: '省部级' },
|
|
||||||
11: { serviceID: 17, ref: 'C6-2-3', name: '研究及编写报告', basicParam: '文件份数', required: true, unit: '万元/份', conversion: 10000, maxPrice: 10, minPrice: 5, defPrice: 7.5, desc: '其他级' },
|
|
||||||
12: { serviceID: 17, ref: 'C6-3-1', name: '标准与技术性指导文件的编制', basicParam: '文件与标准的数量', required: true, unit: '万元/份', conversion: 10000, maxPrice: 80, minPrice: 50, defPrice: 65, desc: '复杂标准' },
|
|
||||||
13: { serviceID: 17, ref: 'C6-3-2', name: '标准与技术性指导文件的编制', basicParam: '文件与标准的数量', required: true, unit: '万元/份', conversion: 10000, maxPrice: 50, minPrice: 20, defPrice: 35, desc: '较复杂标准' },
|
|
||||||
14: { serviceID: 17, ref: 'C6-3-3', name: '标准与技术性指导文件的编制', basicParam: '文件与标准的数量', required: true, unit: '万元/份', conversion: 10000, maxPrice: 20, minPrice: 10, defPrice: 15, desc: '一般标准' },
|
|
||||||
15: { serviceID: 17, ref: 'C6-3-4', name: '标准与技术性指导文件的编制', basicParam: '文件与标准的数量', required: true, unit: '万元/份', conversion: 10000, maxPrice: 10, minPrice: 5, defPrice: 7.5, desc: '简单标准' },
|
|
||||||
16: { serviceID: 17, ref: 'C6-4-1', name: '评审与验收工作', basicParam: '评审与验收次数', required: false, unit: '万元/次', conversion: 10000, maxPrice: 20, minPrice: 8, defPrice: 14, desc: '大型评审' },
|
|
||||||
17: { serviceID: 17, ref: 'C6-4-2', name: '评审与验收工作', basicParam: '评审与验收次数', required: false, unit: '万元/次', conversion: 10000, maxPrice: 10, minPrice: 5, defPrice: 7.5, desc: '中型评审' },
|
|
||||||
18: { serviceID: 17, ref: 'C6-4-3', name: '评审与验收工作', basicParam: '评审与验收次数', required: false, unit: '万元/次', conversion: 10000, maxPrice: 6, minPrice: 3, defPrice: 4.5, desc: '小型评审' },
|
|
||||||
19: { serviceID: 17, ref: 'C6-5-1', name: '培训与宣贯工作', basicParam: '项目数量', required: false, unit: '万元/次', conversion: 10000, maxPrice: 3, minPrice: 1, defPrice: 2, desc: '培训与宣贯材料' },
|
|
||||||
20: { serviceID: 17, ref: 'C6-5-2', name: '培训与宣贯工作', basicParam: '培训与宣贯次数', required: false, unit: '万元/次', conversion: 10000, maxPrice: 1, minPrice: 0.5, defPrice: 0.75, desc: '组织培训与宣贯' },
|
|
||||||
21: { serviceID: 17, ref: 'C6-6', name: '测试与验证工作', basicParam: '', required: false, unit: '%', conversion: 0.01, maxPrice: 50, minPrice: 30, defPrice: 40, desc: '' },
|
|
||||||
22: { serviceID: 18, ref: 'C7-1', name: '组织与调研工作', basicParam: '调研次数', required: true, unit: '万元/次', conversion: 10000, maxPrice: 2, minPrice: 1, defPrice: 1.5, desc: '' },
|
|
||||||
23: { serviceID: 18, ref: 'C7-2', name: '编制大纲', basicParam: '项目数量', required: true, unit: '万元/个', conversion: 10000, maxPrice: 3, minPrice: 2, defPrice: 2.5, desc: '包括技术与定额子目研究' },
|
|
||||||
24: { serviceID: 18, ref: 'C7-3', name: '数据采集与测定', basicParam: '采集组数', required: true, unit: '万元/组', conversion: 10000, maxPrice: 0.8, minPrice: 0.2, defPrice: 0.5, desc: '现场采集方式时计' },
|
|
||||||
25: { serviceID: 18, ref: 'C7-4-1', name: '数据整理与分析', basicParam: '定额子目条数', required: true, unit: '万元/条', conversion: 10000, maxPrice: 0.3, minPrice: 0.1, defPrice: 0.2, desc: '简单定额' },
|
|
||||||
26: { serviceID: 18, ref: 'C7-4-2', name: '数据整理与分析', basicParam: '定额子目条数', required: true, unit: '万元/条', conversion: 10000, maxPrice: 3, minPrice: 0.3, defPrice: 1.65, desc: '复杂定额' },
|
|
||||||
27: { serviceID: 18, ref: 'C7-5', name: '编写定额测定报告', basicParam: '项目数量', required: true, unit: '万元/份', conversion: 10000, maxPrice: 5, minPrice: 2, defPrice: 3.5, desc: '' },
|
|
||||||
28: { serviceID: 18, ref: 'C7-6-1', name: '编制定额文本和释义', basicParam: '基本费用', required: true, unit: '万元/份', conversion: 10000, maxPrice: 1, minPrice: 0.5, defPrice: 0.75, desc: '20条定额子目内' },
|
|
||||||
29: { serviceID: 18, ref: 'C7-6-2', name: '编制定额文本和释义', basicParam: '定额子目条数', required: true, unit: '万元/条', conversion: 10000, maxPrice: 0.2, minPrice: 0.1, defPrice: 0.15, desc: '超过20条每增加1条' },
|
|
||||||
30: { serviceID: 18, ref: 'C7-7-1', name: '评审与验收工作', basicParam: '评审与验收次数', required: false, unit: '万元/次', conversion: 10000, maxPrice: 20, minPrice: 8, defPrice: 14, desc: '大型评审' },
|
|
||||||
31: { serviceID: 18, ref: 'C7-7-2', name: '评审与验收工作', basicParam: '评审与验收次数', required: false, unit: '万元/次', conversion: 10000, maxPrice: 10, minPrice: 5, defPrice: 7.5, desc: '中型评审' },
|
|
||||||
32: { serviceID: 18, ref: 'C7-7-3', name: '评审与验收工作', basicParam: '评审与验收次数', required: false, unit: '万元/次', conversion: 10000, maxPrice: 6, minPrice: 3, defPrice: 4.5, desc: '小型评审' },
|
|
||||||
33: { serviceID: 18, ref: 'C7-8-1', name: '培训与宣贯工作', basicParam: '项目数量', required: false, unit: '万元/次', conversion: 10000, maxPrice: 3, minPrice: 1, defPrice: 2, desc: '培训与宣贯材料' },
|
|
||||||
34: { serviceID: 18, ref: 'C7-8-2', name: '培训与宣贯工作', basicParam: '培训与宣贯次数', required: false, unit: '万元/次', conversion: 10000, maxPrice: 1, minPrice: 0.5, defPrice: 0.75, desc: '组织培训与宣贯' },
|
|
||||||
35: { serviceID: 18, ref: 'C7-9', name: '定额测试与验证', basicParam: '', required: false, unit: '%', conversion: 0.01, maxPrice: 50, minPrice: 30, defPrice: 40, desc: '' },
|
|
||||||
36: { serviceID: 19, ref: 'C8-1', name: 'Q≤10条', basicParam: '价格信息数量', required: true, unit: '元/条', conversion: 1, maxPrice: null, minPrice: null, defPrice: 500, desc: '' },
|
|
||||||
37: { serviceID: 19, ref: 'C8-2', name: '10条<Q≤30条', basicParam: '价格信息数量', required: true, unit: '元/条', conversion: 1, maxPrice: null, minPrice: null, defPrice: 400, desc: '' },
|
|
||||||
38: { serviceID: 19, ref: 'C8-3', name: '30条<Q≤50条', basicParam: '价格信息数量', required: true, unit: '元/条', conversion: 1, maxPrice: null, minPrice: null, defPrice: 300, desc: '' },
|
|
||||||
39: { serviceID: 19, ref: 'C8-4', name: '50条<Q≤100条', basicParam: '价格信息数量', required: true, unit: '元/条', conversion: 1, maxPrice: null, minPrice: null, defPrice: 200, desc: '' },
|
|
||||||
40: { serviceID: 19, ref: 'C8-5', name: 'Q>100条', basicParam: '价格信息数量', required: true, unit: '元/条', conversion: 1, maxPrice: null, minPrice: null, defPrice: 100, desc: '' }
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export const expertList = {
|
export const serviceList = {
|
||||||
|
0: { code: 'D1', name: '全过程造价咨询', maxCoe: null, minCoe: null, defCoe: 1, desc: '', isRoad: true, isRailway: true, isWaterway: true, mutiple: false, order: 1, scale: true, onlyCostScale: true, amount: false, workDay: true },
|
||||||
|
1: { code: 'D2', name: '分阶段造价咨询', maxCoe: null, minCoe: null, defCoe: null, desc: '', isRoad: true, isRailway: true, isWaterway: true, mutiple: false, order: 2, scale: null, onlyCostScale: null, amount: null, workDay: null },
|
||||||
|
2: { code: 'D2-1', name: '前期阶段造价咨询', maxCoe: null, minCoe: null, defCoe: 0.5, desc: '', isRoad: true, isRailway: true, isWaterway: true, mutiple: false, order: 3, scale: true, onlyCostScale: true, amount: false, workDay: true },
|
||||||
|
3: { code: 'D2-2-1', name: '实施阶段造价咨询(公路、水运)', maxCoe: null, minCoe: null, defCoe: 0.55, desc: '本系数适用于公路和水运工程。', isRoad: true, isRailway: false, isWaterway: true, mutiple: false, order: 4, scale: true, onlyCostScale: true, amount: false, workDay: true },
|
||||||
|
4: { code: 'D2-2-2', name: '实施阶段造价咨询(铁路)', maxCoe: null, minCoe: null, defCoe: 0.6, desc: '本系数适用于铁路工程。', isRoad: false, isRailway: true, isWaterway: false, mutiple: false, order: 5, scale: true, onlyCostScale: true, amount: false, workDay: true },
|
||||||
|
5: { code: 'D3', name: '基本造价咨询', maxCoe: null, minCoe: null, defCoe: null, desc: '', isRoad: true, isRailway: true, isWaterway: true, mutiple: false, order: 6, scale: null, onlyCostScale: null, amount: null, workDay: null },
|
||||||
|
6: { code: 'D3-1', name: '投资估算', maxCoe: null, minCoe: null, defCoe: 0.1, desc: '委托同一咨询人同时负责D3-1和D3-2时,D3-1和D3-2的合计调整系数为0.25。', isRoad: true, isRailway: true, isWaterway: true, mutiple: false, order: 7, scale: true, onlyCostScale: true, amount: false, workDay: true },
|
||||||
|
7: { code: 'D3-2', name: '设计概算', maxCoe: null, minCoe: null, defCoe: 0.2, desc: '', isRoad: true, isRailway: true, isWaterway: true, mutiple: false, order: 8, scale: true, onlyCostScale: true, amount: false, workDay: true },
|
||||||
|
8: { code: 'D3-3', name: '施工图预算', maxCoe: null, minCoe: null, defCoe: 0.25, desc: '委托同一咨询人同时负责D3-3和D3-4时,D3-3和D3-4的合计调整系数为0.3。', isRoad: true, isRailway: true, isWaterway: true, mutiple: false, order: 9, scale: true, onlyCostScale: false, amount: false, workDay: true },
|
||||||
|
9: { code: 'D3-4', name: '招标工程量清单及清单预算(或最高投标限价)', maxCoe: null, minCoe: null, defCoe: 0.15, desc: '', isRoad: true, isRailway: true, isWaterway: true, mutiple: false, order: 10, scale: true, onlyCostScale: false, amount: false, workDay: true },
|
||||||
|
10: { code: 'D3-5', name: '清理概算(仅限铁路)', maxCoe: null, minCoe: null, defCoe: 0.2, desc: '本系数适用于铁路工程。', isRoad: false, isRailway: true, isWaterway: false, mutiple: false, order: 11, scale: true, onlyCostScale: true, amount: false, workDay: true },
|
||||||
|
11: { code: 'D3-6-1', name: '合同(工程)结算', maxCoe: null, minCoe: null, defCoe: 0.3, desc: '本系数适用于公路和水运工程。', isRoad: true, isRailway: false, isWaterway: true, mutiple: false, order: 12, scale: true, onlyCostScale: false, amount: false, workDay: true },
|
||||||
|
12: { code: 'D3-6-2', name: '合同(工程)结算', maxCoe: null, minCoe: null, defCoe: 0.2, desc: '本系数适用于铁路工程。', isRoad: false, isRailway: true, isWaterway: false, mutiple: false, order: 13, scale: true, onlyCostScale: false, amount: false, workDay: true },
|
||||||
|
13: { code: 'D3-7', name: '竣工决算', maxCoe: null, minCoe: null, defCoe: 0.1, desc: '', isRoad: true, isRailway: true, isWaterway: true, mutiple: false, order: 14, scale: true, onlyCostScale: true, amount: false, workDay: true },
|
||||||
|
14: { code: 'D4', name: '专项造价咨询', maxCoe: null, minCoe: null, defCoe: null, desc: '', isRoad: true, isRailway: true, isWaterway: true, mutiple: false, order: 15, scale: null, onlyCostScale: null, amount: null, workDay: null },
|
||||||
|
15: { code: 'D4-1', name: '工程造价顾问', maxCoe: null, minCoe: null, defCoe: 1, desc: '本表系数适用于采用工作量计价法基准预算的调整系数。', isRoad: true, isRailway: true, isWaterway: true, mutiple: false, order: 16, scale: false, onlyCostScale: null, amount: true, workDay: true },
|
||||||
|
16: { code: 'D4-2', name: '造价政策制(修)订', maxCoe: null, minCoe: null, defCoe: 1, desc: '', isRoad: true, isRailway: true, isWaterway: true, mutiple: false, order: 17, scale: false, onlyCostScale: null, amount: true, workDay: true },
|
||||||
|
17: { code: 'D4-3', name: '造价科学与技术研究', maxCoe: null, minCoe: null, defCoe: 1, desc: '', isRoad: true, isRailway: true, isWaterway: true, mutiple: false, order: 18, scale: false, onlyCostScale: null, amount: true, workDay: true },
|
||||||
|
18: { code: 'D4-4', name: '定额测定', maxCoe: null, minCoe: null, defCoe: 1, desc: '', isRoad: true, isRailway: true, isWaterway: true, mutiple: false, order: 19, scale: false, onlyCostScale: null, amount: true, workDay: true },
|
||||||
|
19: { code: 'D4-5', name: '造价信息咨询', maxCoe: null, minCoe: null, defCoe: 1, desc: '', isRoad: true, isRailway: true, isWaterway: true, mutiple: false, order: 20, scale: false, onlyCostScale: null, amount: true, workDay: true },
|
||||||
|
20: { code: 'D4-6', name: '造价鉴定', maxCoe: null, minCoe: null, defCoe: 0.5, desc: '本表系数适用于采用规模计价法基准预算的调整系数。', isRoad: true, isRailway: true, isWaterway: true, mutiple: false, order: 21, scale: true, onlyCostScale: false, amount: false, workDay: true },
|
||||||
|
21: { code: 'D4-7', name: '工程成本测算', maxCoe: null, minCoe: null, defCoe: 0.1, desc: '', isRoad: true, isRailway: true, isWaterway: true, mutiple: false, order: 22, scale: true, onlyCostScale: false, amount: false, workDay: true },
|
||||||
|
22: { code: 'D4-8', name: '工程成本核算', maxCoe: null, minCoe: null, defCoe: 0.1, desc: '', isRoad: true, isRailway: true, isWaterway: true, mutiple: false, order: 23, scale: true, onlyCostScale: false, amount: false, workDay: true },
|
||||||
|
23: { code: 'D4-9', name: '计算工程量', maxCoe: null, minCoe: null, defCoe: 0.2, desc: '', isRoad: true, isRailway: true, isWaterway: true, mutiple: false, order: 24, scale: true, onlyCostScale: false, amount: false, workDay: true },
|
||||||
|
24: { code: 'D4-10', name: '工程变更费用咨询', maxCoe: null, minCoe: null, defCoe: 0.5, desc: '', isRoad: true, isRailway: true, isWaterway: true, mutiple: false, order: 25, scale: true, onlyCostScale: false, amount: false, workDay: true },
|
||||||
|
25: { code: 'D4-11', name: '调整估算', maxCoe: 0.2, minCoe: 0.1, defCoe: 0.15, desc: '', isRoad: true, isRailway: true, isWaterway: true, mutiple: false, order: 26, scale: true, onlyCostScale: true, amount: false, workDay: true },
|
||||||
|
26: { code: 'D4-12', name: '调整概算', maxCoe: 0.3, minCoe: 0.15, defCoe: 0.225, desc: '本表系数适用于采用规模计价法基准预算的系数;依据其调整时期所在建设阶段和基础资料的不同,其系数取值不同。', isRoad: true, isRailway: true, isWaterway: true, mutiple: false, order: 27, scale: true, onlyCostScale: true, amount: false, workDay: true },
|
||||||
|
27: { code: 'D4-13', name: '造价检查', maxCoe: null, minCoe: null, defCoe: null, desc: '可按照服务工日数量×服务工日人工单价×综合预算系数;也可按照服务工日数量×服务工日综合预算单价。', isRoad: true, isRailway: true, isWaterway: true, mutiple: false, order: 28, scale: false, onlyCostScale: null, amount: false, workDay: true },
|
||||||
|
28: { code: 'D4-14', name: '其他专项咨询', maxCoe: null, minCoe: null, defCoe: null, desc: '可参照相同或相似服务的系数。', isRoad: true, isRailway: true, isWaterway: true, mutiple: false, order: 29, scale: false, onlyCostScale: null, amount: false, workDay: true },
|
||||||
|
29: { code: 'D4-15-1', name: '造价数据测试验证(估算)', maxCoe: null, minCoe: null, defCoe: 0.04, desc: '委托同一咨询人同时负责D3-1和D3-2时,D3-1和D3-2的合计调整系数为0.25。', isRoad: true, isRailway: true, isWaterway: true, mutiple: false, order: 30, scale: false, onlyCostScale: null, amount: false, workDay: true },
|
||||||
|
30: { code: 'D4-15-2', name: '造价数据测试验证(概算)', maxCoe: null, minCoe: null, defCoe: 0.08, desc: '', isRoad: true, isRailway: true, isWaterway: true, mutiple: false, order: 31, scale: false, onlyCostScale: null, amount: false, workDay: true },
|
||||||
|
31: { code: 'D4-15-3', name: '造价数据测试验证(施工图预算)', maxCoe: null, minCoe: null, defCoe: 0.1, desc: '委托同一咨询人同时负责D3-3和D3-4时,D3-3和D3-4的合计调整系数为0.3。', isRoad: true, isRailway: true, isWaterway: true, mutiple: false, order: 32, scale: false, onlyCostScale: null, amount: false, workDay: true },
|
||||||
|
32: { code: 'D4-15-4', name: '造价数据测试验证(招标工程量清单及清单预算(或最高投标限价))', maxCoe: null, minCoe: null, defCoe: 0.06, desc: '', isRoad: true, isRailway: true, isWaterway: true, mutiple: false, order: 33, scale: false, onlyCostScale: null, amount: false, workDay: true },
|
||||||
|
33: { code: 'D4-15-5', name: '造价数据测试验证(清理概算(仅限铁路))', maxCoe: null, minCoe: null, defCoe: 0.08, desc: '本系数适用于铁路工程。', isRoad: true, isRailway: true, isWaterway: true, mutiple: false, order: 34, scale: false, onlyCostScale: null, amount: false, workDay: true },
|
||||||
|
34: { code: 'D4-15-6', name: '造价数据测试验证(合同(工程)结算)', maxCoe: null, minCoe: null, defCoe: 0.12, desc: '本系数适用于公路和水运工程。', isRoad: true, isRailway: true, isWaterway: true, mutiple: false, order: 35, scale: false, onlyCostScale: null, amount: false, workDay: true },
|
||||||
|
35: { code: 'D4-15-7', name: '造价数据测试验证(合同(工程)结算)', maxCoe: null, minCoe: null, defCoe: 0.08, desc: '本系数适用于铁路工程。', isRoad: true, isRailway: true, isWaterway: true, mutiple: false, order: 36, scale: false, onlyCostScale: null, amount: false, workDay: true },
|
||||||
|
36: { code: 'D4-15-8', name: '造价数据测试验证(竣工决算)', maxCoe: null, minCoe: null, defCoe: 0.04, desc: '', isRoad: true, isRailway: true, isWaterway: true, mutiple: false, order: 37, scale: false, onlyCostScale: null, amount: false, workDay: true },
|
||||||
|
};
|
||||||
|
|
||||||
|
export const taskList = {
|
||||||
|
0: { serviceID: 15, code: 'C4-1', name: '工程造价日常顾问', basicParam: '服务月份数', required: true, unit: '万元/月', conversion: 10000, maxPrice: 0.5, minPrice: 0.3, defPrice: 0.4, desc: '' },
|
||||||
|
1: { serviceID: 15, code: 'C4-2', name: '工程造价专项顾问', basicParam: '服务项目的造价金额', required: true, unit: '%', conversion: 0.01, maxPrice: null, minPrice: null, defPrice: 0.01, desc: '适用于涉及造价费用类的顾问' },
|
||||||
|
2: { serviceID: 16, code: 'C5-1', name: '组织与调研工作', basicParam: '调研次数', required: true, unit: '万元/次', conversion: 10000, maxPrice: 2, minPrice: 1, defPrice: 1.5, desc: '' },
|
||||||
|
3: { serviceID: 16, code: 'C5-2-1', name: '文件编写工作', basicParam: '文件份数', required: true, unit: '万元/份', conversion: 10000, maxPrice: 5, minPrice: 3, defPrice: 4, desc: '主编' },
|
||||||
|
4: { serviceID: 16, code: 'C5-2-2', name: '文件编写工作', basicParam: '文件份数', required: true, unit: '万元/份', conversion: 10000, maxPrice: 3, minPrice: 1, defPrice: 2, desc: '参编' },
|
||||||
|
5: { serviceID: 16, code: 'C5-3-1', name: '评审工作', basicParam: '评审次数', required: false, unit: '万元/次', conversion: 10000, maxPrice: 20, minPrice: 8, defPrice: 14, desc: '大型评审' },
|
||||||
|
6: { serviceID: 16, code: 'C5-3-2', name: '评审工作', basicParam: '评审次数', required: false, unit: '万元/次', conversion: 10000, maxPrice: 10, minPrice: 5, defPrice: 7.5, desc: '中型评审' },
|
||||||
|
7: { serviceID: 16, code: 'C5-3-3', name: '评审工作', basicParam: '评审次数', required: false, unit: '万元/次', conversion: 10000, maxPrice: 6, minPrice: 3, defPrice: 4.5, desc: '小型评审' },
|
||||||
|
8: { serviceID: 17, code: 'C6-1', name: '组织与调研工作', basicParam: '调研次数', required: true, unit: '万元/次', conversion: 10000, maxPrice: 2, minPrice: 1, defPrice: 1.5, desc: '' },
|
||||||
|
9: { serviceID: 17, code: 'C6-2-1', name: '研究及编写报告', basicParam: '文件份数', required: true, unit: '万元/份', conversion: 10000, maxPrice: 50, minPrice: 20, defPrice: 35, desc: '国家级' },
|
||||||
|
10: { serviceID: 17, code: 'C6-2-2', name: '研究及编写报告', basicParam: '文件份数', required: true, unit: '万元/份', conversion: 10000, maxPrice: 20, minPrice: 10, defPrice: 15, desc: '省部级' },
|
||||||
|
11: { serviceID: 17, code: 'C6-2-3', name: '研究及编写报告', basicParam: '文件份数', required: true, unit: '万元/份', conversion: 10000, maxPrice: 10, minPrice: 5, defPrice: 7.5, desc: '其他级' },
|
||||||
|
12: { serviceID: 17, code: 'C6-3-1', name: '标准与技术性指导文件的编制', basicParam: '文件与标准的数量', required: true, unit: '万元/份', conversion: 10000, maxPrice: 80, minPrice: 50, defPrice: 65, desc: '复杂标准' },
|
||||||
|
13: { serviceID: 17, code: 'C6-3-2', name: '标准与技术性指导文件的编制', basicParam: '文件与标准的数量', required: true, unit: '万元/份', conversion: 10000, maxPrice: 50, minPrice: 20, defPrice: 35, desc: '较复杂标准' },
|
||||||
|
14: { serviceID: 17, code: 'C6-3-3', name: '标准与技术性指导文件的编制', basicParam: '文件与标准的数量', required: true, unit: '万元/份', conversion: 10000, maxPrice: 20, minPrice: 10, defPrice: 15, desc: '一般标准' },
|
||||||
|
15: { serviceID: 17, code: 'C6-3-4', name: '标准与技术性指导文件的编制', basicParam: '文件与标准的数量', required: true, unit: '万元/份', conversion: 10000, maxPrice: 10, minPrice: 5, defPrice: 7.5, desc: '简单标准' },
|
||||||
|
16: { serviceID: 17, code: 'C6-4-1', name: '评审与验收工作', basicParam: '评审与验收次数', required: false, unit: '万元/次', conversion: 10000, maxPrice: 20, minPrice: 8, defPrice: 14, desc: '大型评审' },
|
||||||
|
17: { serviceID: 17, code: 'C6-4-2', name: '评审与验收工作', basicParam: '评审与验收次数', required: false, unit: '万元/次', conversion: 10000, maxPrice: 10, minPrice: 5, defPrice: 7.5, desc: '中型评审' },
|
||||||
|
18: { serviceID: 17, code: 'C6-4-3', name: '评审与验收工作', basicParam: '评审与验收次数', required: false, unit: '万元/次', conversion: 10000, maxPrice: 6, minPrice: 3, defPrice: 4.5, desc: '小型评审' },
|
||||||
|
19: { serviceID: 17, code: 'C6-5-1', name: '培训与宣贯工作', basicParam: '项目数量', required: false, unit: '万元/次', conversion: 10000, maxPrice: 3, minPrice: 1, defPrice: 2, desc: '培训与宣贯材料' },
|
||||||
|
20: { serviceID: 17, code: 'C6-5-2', name: '培训与宣贯工作', basicParam: '培训与宣贯次数', required: false, unit: '万元/次', conversion: 10000, maxPrice: 1, minPrice: 0.5, defPrice: 0.75, desc: '组织培训与宣贯' },
|
||||||
|
21: { serviceID: 18, code: 'C7-1', name: '组织与调研工作', basicParam: '调研次数', required: true, unit: '万元/次', conversion: 10000, maxPrice: 2, minPrice: 1, defPrice: 1.5, desc: '' },
|
||||||
|
22: { serviceID: 18, code: 'C7-2', name: '编制大纲', basicParam: '项目数量', required: true, unit: '万元/个', conversion: 10000, maxPrice: 3, minPrice: 2, defPrice: 2.5, desc: '包括技术与定额子目研究' },
|
||||||
|
23: { serviceID: 18, code: 'C7-3', name: '数据采集与测定', basicParam: '采集组数', required: true, unit: '万元/组', conversion: 10000, maxPrice: 0.8, minPrice: 0.2, defPrice: 0.5, desc: '现场采集方式时计' },
|
||||||
|
24: { serviceID: 18, code: 'C7-4-1', name: '数据整理与分析', basicParam: '定额子目条数', required: true, unit: '万元/条', conversion: 10000, maxPrice: 0.3, minPrice: 0.1, defPrice: 0.2, desc: '简单定额' },
|
||||||
|
25: { serviceID: 18, code: 'C7-4-2', name: '数据整理与分析', basicParam: '定额子目条数', required: true, unit: '万元/条', conversion: 10000, maxPrice: 3, minPrice: 0.3, defPrice: 1.65, desc: '复杂定额' },
|
||||||
|
26: { serviceID: 18, code: 'C7-5', name: '编写定额测定报告', basicParam: '项目数量', required: true, unit: '万元/份', conversion: 10000, maxPrice: 5, minPrice: 2, defPrice: 3.5, desc: '' },
|
||||||
|
27: { serviceID: 18, code: 'C7-6-1', name: '编制定额文本和释义', basicParam: '基本费用', required: true, unit: '万元/份', conversion: 10000, maxPrice: 1, minPrice: 0.5, defPrice: 0.75, desc: '20条定额子目内' },
|
||||||
|
28: { serviceID: 18, code: 'C7-6-2', name: '编制定额文本和释义', basicParam: '定额子目条数', required: true, unit: '万元/条', conversion: 10000, maxPrice: 0.2, minPrice: 0.1, defPrice: 0.15, desc: '超过20条每增加1条' },
|
||||||
|
29: { serviceID: 18, code: 'C7-7-1', name: '评审与验收工作', basicParam: '评审与验收次数', required: false, unit: '万元/次', conversion: 10000, maxPrice: 20, minPrice: 8, defPrice: 14, desc: '大型评审' },
|
||||||
|
30: { serviceID: 18, code: 'C7-7-2', name: '评审与验收工作', basicParam: '评审与验收次数', required: false, unit: '万元/次', conversion: 10000, maxPrice: 10, minPrice: 5, defPrice: 7.5, desc: '中型评审' },
|
||||||
|
31: { serviceID: 18, code: 'C7-7-3', name: '评审与验收工作', basicParam: '评审与验收次数', required: false, unit: '万元/次', conversion: 10000, maxPrice: 6, minPrice: 3, defPrice: 4.5, desc: '小型评审' },
|
||||||
|
32: { serviceID: 18, code: 'C7-8-1', name: '培训与宣贯工作', basicParam: '项目数量', required: false, unit: '万元/次', conversion: 10000, maxPrice: 3, minPrice: 1, defPrice: 2, desc: '培训与宣贯材料' },
|
||||||
|
33: { serviceID: 18, code: 'C7-8-2', name: '培训与宣贯工作', basicParam: '培训与宣贯次数', required: false, unit: '万元/次', conversion: 10000, maxPrice: 1, minPrice: 0.5, defPrice: 0.75, desc: '组织培训与宣贯' },
|
||||||
|
34: { serviceID: 19, code: 'C8-1', name: 'Q≤10条', basicParam: '价格信息数量', required: true, unit: '元/条', conversion: 1, maxPrice: null, minPrice: null, defPrice: 500, desc: '' },
|
||||||
|
35: { serviceID: 19, code: 'C8-2', name: '10条<Q≤30条', basicParam: '价格信息数量', required: true, unit: '元/条', conversion: 1, maxPrice: null, minPrice: null, defPrice: 400, desc: '' },
|
||||||
|
36: { serviceID: 19, code: 'C8-3', name: '30条<Q≤50条', basicParam: '价格信息数量', required: true, unit: '元/条', conversion: 1, maxPrice: null, minPrice: null, defPrice: 300, desc: '' },
|
||||||
|
37: { serviceID: 19, code: 'C8-4', name: '50条<Q≤100条', basicParam: '价格信息数量', required: true, unit: '元/条', conversion: 1, maxPrice: null, minPrice: null, defPrice: 200, desc: '' },
|
||||||
|
38: { serviceID: 19, code: 'C8-5', name: 'Q>100条', basicParam: '价格信息数量', required: true, unit: '元/条', conversion: 1, maxPrice: null, minPrice: null, defPrice: 100, desc: '' },
|
||||||
|
};
|
||||||
|
|
||||||
|
export const expertList = {
|
||||||
0: { code: 'C9-1-1', name: '技术员及其他', maxPrice: 800, minPrice: 600, defPrice: 700, manageCoe: 2.3 },
|
0: { code: 'C9-1-1', name: '技术员及其他', maxPrice: 800, minPrice: 600, defPrice: 700, manageCoe: 2.3 },
|
||||||
1: { code: 'C9-1-2', name: '助理工程师', maxPrice: 1000, minPrice: 800, defPrice: 900, manageCoe: 2.3 },
|
1: { code: 'C9-1-2', name: '助理工程师', maxPrice: 1000, minPrice: 800, defPrice: 900, manageCoe: 2.3 },
|
||||||
2: { code: 'C9-1-3', name: '中级工程师或二级造价工程师', maxPrice: 1500, minPrice: 1000, defPrice: 1250, manageCoe: 2.2 },
|
2: { code: 'C9-1-3', name: '中级工程师或二级造价工程师', maxPrice: 1500, minPrice: 1000, defPrice: 1250, manageCoe: 2.2 },
|
||||||
@ -133,7 +140,7 @@ export const expertList = {
|
|||||||
7: { code: 'C9-3-2', name: '一级造价工程师且具备高级工程师资格', maxPrice: 2000, minPrice: 1800, defPrice: 1900, manageCoe: 2.05 },
|
7: { code: 'C9-3-2', name: '一级造价工程师且具备高级工程师资格', maxPrice: 2000, minPrice: 1800, defPrice: 1900, manageCoe: 2.05 },
|
||||||
};
|
};
|
||||||
|
|
||||||
const costScaleCal = [
|
let costScaleCal = [
|
||||||
{ code: 'C1-1', staLine: 0, endLine: 100, basic: { staPrice: 0, rate: 0.01 }, optional: { staPrice: 0, rate: 0.002 } },
|
{ code: 'C1-1', staLine: 0, endLine: 100, basic: { staPrice: 0, rate: 0.01 }, optional: { staPrice: 0, rate: 0.002 } },
|
||||||
{ code: 'C1-2', staLine: 100, endLine: 300, basic: { staPrice: 10000, rate: 0.008 }, optional: { staPrice: 2000, rate: 0.0016 } },
|
{ code: 'C1-2', staLine: 100, endLine: 300, basic: { staPrice: 10000, rate: 0.008 }, optional: { staPrice: 2000, rate: 0.0016 } },
|
||||||
{ code: 'C1-3', staLine: 300, endLine: 500, basic: { staPrice: 26000, rate: 0.005 }, optional: { staPrice: 5200, rate: 0.001 } },
|
{ code: 'C1-3', staLine: 300, endLine: 500, basic: { staPrice: 26000, rate: 0.005 }, optional: { staPrice: 5200, rate: 0.001 } },
|
||||||
@ -153,7 +160,7 @@ const costScaleCal = [
|
|||||||
{ code: 'C1-17', staLine: 1000000, endLine: null, basic: { staPrice: 5906000, rate: 0.00025 }, optional: { staPrice: 1181200, rate: 0.00005 } },
|
{ code: 'C1-17', staLine: 1000000, endLine: null, basic: { staPrice: 5906000, rate: 0.00025 }, optional: { staPrice: 1181200, rate: 0.00005 } },
|
||||||
];
|
];
|
||||||
|
|
||||||
const areaScaleCal = [
|
let areaScaleCal = [
|
||||||
{ code: 'C2-1', staLine: 0, endLine: 50, basic: { staPrice: 0, rate: 200 }, optional: { staPrice: 0, rate: 40 } },
|
{ code: 'C2-1', staLine: 0, endLine: 50, basic: { staPrice: 0, rate: 200 }, optional: { staPrice: 0, rate: 40 } },
|
||||||
{ code: 'C2-2', staLine: 50, endLine: 100, basic: { staPrice: 10000, rate: 160 }, optional: { staPrice: 2000, rate: 32 } },
|
{ code: 'C2-2', staLine: 50, endLine: 100, basic: { staPrice: 10000, rate: 160 }, optional: { staPrice: 2000, rate: 32 } },
|
||||||
{ code: 'C2-3', staLine: 100, endLine: 500, basic: { staPrice: 18000, rate: 120 }, optional: { staPrice: 3600, rate: 24 } },
|
{ code: 'C2-3', staLine: 100, endLine: 500, basic: { staPrice: 18000, rate: 120 }, optional: { staPrice: 3600, rate: 24 } },
|
||||||
@ -162,6 +169,25 @@ const areaScaleCal = [
|
|||||||
{ code: 'C2-6', staLine: 5000, endLine: null, basic: { staPrice: 346000, rate: 20 }, optional: { staPrice: 69200, rate: 4 } },
|
{ code: 'C2-6', staLine: 5000, endLine: null, basic: { staPrice: 346000, rate: 20 }, optional: { staPrice: 69200, rate: 4 } },
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
export const GENERIC_MAJOR_CODE = 'E1'
|
||||||
|
|
||||||
|
export const isMajorCodeInIndustryScope = (majorCode, industryCode, includeGeneric = true) => {
|
||||||
|
const code = String(majorCode || '').trim()
|
||||||
|
const industry = String(industryCode || '').trim()
|
||||||
|
if (!code || !industry) return false
|
||||||
|
if (code === industry || code.startsWith(`${industry}-`)) return true
|
||||||
|
if (!includeGeneric) return false
|
||||||
|
if (industry === GENERIC_MAJOR_CODE) return code === GENERIC_MAJOR_CODE || code.startsWith(`${GENERIC_MAJOR_CODE}-`)
|
||||||
|
return code === GENERIC_MAJOR_CODE || code.startsWith(`${GENERIC_MAJOR_CODE}-`)
|
||||||
|
}
|
||||||
|
|
||||||
|
export const isMajorIndustrySelectable = (item) =>
|
||||||
|
Boolean(item?.code && !String(item.code).includes('-') && !item?.hideInIndustrySelector)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const infoServiceScaleCal: Array<{ staLine: number; endLine: number | null; staPrice: number; rate: number }> = []
|
const infoServiceScaleCal: Array<{ staLine: number; endLine: number | null; staPrice: number; rate: number }> = []
|
||||||
|
|
||||||
const inRange = (sv: number, staLine: number, endLine: number | null) =>
|
const inRange = (sv: number, staLine: number, endLine: number | null) =>
|
||||||
@ -336,7 +362,7 @@ export async function exportFile(fileName, data) {
|
|||||||
const blob = new Blob([buffer], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' });
|
const blob = new Blob([buffer], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' });
|
||||||
const url1 = window.URL.createObjectURL(blob);
|
const url1 = window.URL.createObjectURL(blob);
|
||||||
const a = document.createElement('a');
|
const a = document.createElement('a');
|
||||||
a.href = url1;
|
a.hcode = url1;
|
||||||
a.download = `${fileName}.xlsx`;
|
a.download = `${fileName}.xlsx`;
|
||||||
a.click();
|
a.click();
|
||||||
URL.revokeObjectURL(url1);
|
URL.revokeObjectURL(url1);
|
||||||
@ -344,6 +370,9 @@ export async function exportFile(fileName, data) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function generateTemplate(data) {
|
async function generateTemplate(data) {
|
||||||
|
try {
|
||||||
|
|
||||||
|
|
||||||
console.log(data)
|
console.log(data)
|
||||||
// 获取模板
|
// 获取模板
|
||||||
let templateExcel = 'template20260226001test010';
|
let templateExcel = 'template20260226001test010';
|
||||||
@ -548,7 +577,7 @@ async function generateTemplate(data) {
|
|||||||
let serviceX = serviceList[sobj.id];
|
let serviceX = serviceList[sobj.id];
|
||||||
cusInsertRowFunc(4 + sindex, [sheet_1.getRow(3)], sheet_1, (targetRow) => {
|
cusInsertRowFunc(4 + sindex, [sheet_1.getRow(3)], sheet_1, (targetRow) => {
|
||||||
targetRow.getCell(1).value = sindex + 1;
|
targetRow.getCell(1).value = sindex + 1;
|
||||||
targetRow.getCell(2).value = serviceX.ref;
|
targetRow.getCell(2).value = serviceX.code;
|
||||||
targetRow.getCell(3).value = serviceX.name;
|
targetRow.getCell(3).value = serviceX.name;
|
||||||
targetRow.getCell(4).value = sobj.method1 ? sobj.method1.fee : '';
|
targetRow.getCell(4).value = sobj.method1 ? sobj.method1.fee : '';
|
||||||
targetRow.getCell(5).value = sobj.method2 ? sobj.method2.fee : '';
|
targetRow.getCell(5).value = sobj.method2 ? sobj.method2.fee : '';
|
||||||
@ -569,7 +598,7 @@ async function generateTemplate(data) {
|
|||||||
|
|
||||||
cusInsertRowFunc(4 + num_2, [sheet_2.getRow(4)], sheet_2, (targetRow) => {
|
cusInsertRowFunc(4 + num_2, [sheet_2.getRow(4)], sheet_2, (targetRow) => {
|
||||||
targetRow.getCell(1).value = num_2++;
|
targetRow.getCell(1).value = num_2++;
|
||||||
targetRow.getCell(2).value = serviceX.ref;
|
targetRow.getCell(2).value = serviceX.code;
|
||||||
targetRow.getCell(3).value = serviceX.name;
|
targetRow.getCell(3).value = serviceX.name;
|
||||||
targetRow.getCell(4).value = '/';
|
targetRow.getCell(4).value = '/';
|
||||||
targetRow.getCell(5).value = '/';
|
targetRow.getCell(5).value = '/';
|
||||||
@ -578,7 +607,7 @@ async function generateTemplate(data) {
|
|||||||
targetRow.getCell(7).value = sobj.method1.fee;
|
targetRow.getCell(7).value = sobj.method1.fee;
|
||||||
cusInsertRowFunc(4 + num_2_1, [sheet_2_1.getRow(4)], sheet_2_1, (targetRow) => {
|
cusInsertRowFunc(4 + num_2_1, [sheet_2_1.getRow(4)], sheet_2_1, (targetRow) => {
|
||||||
targetRow.getCell(1).value = num_2_1++;
|
targetRow.getCell(1).value = num_2_1++;
|
||||||
targetRow.getCell(2).value = serviceX.ref;
|
targetRow.getCell(2).value = serviceX.code;
|
||||||
targetRow.getCell(3).value = serviceX.name;
|
targetRow.getCell(3).value = serviceX.name;
|
||||||
targetRow.getCell(4).value = sobj.method1.cost;
|
targetRow.getCell(4).value = sobj.method1.cost;
|
||||||
targetRow.getCell(5).value = '/';
|
targetRow.getCell(5).value = '/';
|
||||||
@ -593,7 +622,7 @@ async function generateTemplate(data) {
|
|||||||
targetRow.getCell(9).value = sobj.method2.fee;
|
targetRow.getCell(9).value = sobj.method2.fee;
|
||||||
cusInsertRowFunc(4 + num_2_2, [sheet_2_2.getRow(4)], sheet_2_2, (targetRow) => {
|
cusInsertRowFunc(4 + num_2_2, [sheet_2_2.getRow(4)], sheet_2_2, (targetRow) => {
|
||||||
targetRow.getCell(1).value = num_2_2++;
|
targetRow.getCell(1).value = num_2_2++;
|
||||||
targetRow.getCell(2).value = serviceX.ref;
|
targetRow.getCell(2).value = serviceX.code;
|
||||||
targetRow.getCell(3).value = serviceX.name;
|
targetRow.getCell(3).value = serviceX.name;
|
||||||
targetRow.getCell(4).value = sobj.method2.area;
|
targetRow.getCell(4).value = sobj.method2.area;
|
||||||
targetRow.getCell(5).value = '/';
|
targetRow.getCell(5).value = '/';
|
||||||
@ -608,7 +637,7 @@ async function generateTemplate(data) {
|
|||||||
let majorX = majorList[m.major];
|
let majorX = majorList[m.major];
|
||||||
cusInsertRowFunc(4 + num_2, [sheet_2.getRow(4)], sheet_2, (targetRow) => {
|
cusInsertRowFunc(4 + num_2, [sheet_2.getRow(4)], sheet_2, (targetRow) => {
|
||||||
targetRow.getCell(1).value = num_2++;
|
targetRow.getCell(1).value = num_2++;
|
||||||
targetRow.getCell(2).value = serviceX.ref + '-' + (mindex + 1);
|
targetRow.getCell(2).value = serviceX.code + '-' + (mindex + 1);
|
||||||
targetRow.getCell(3).value = majorX.name;
|
targetRow.getCell(3).value = majorX.name;
|
||||||
if (m.mth1) {
|
if (m.mth1) {
|
||||||
targetRow.getCell(4).value = m.mth1.serviceCoe;
|
targetRow.getCell(4).value = m.mth1.serviceCoe;
|
||||||
@ -619,7 +648,7 @@ async function generateTemplate(data) {
|
|||||||
targetRow.getCell(9).value = 0;
|
targetRow.getCell(9).value = 0;
|
||||||
cusInsertRowFunc(4 + num_2_1, [sheet_2_1.getRow(4)], sheet_2_1, (targetRow) => {
|
cusInsertRowFunc(4 + num_2_1, [sheet_2_1.getRow(4)], sheet_2_1, (targetRow) => {
|
||||||
targetRow.getCell(1).value = num_2_1++;
|
targetRow.getCell(1).value = num_2_1++;
|
||||||
targetRow.getCell(2).value = serviceX.ref + '-' + (mindex + 1);
|
targetRow.getCell(2).value = serviceX.code + '-' + (mindex + 1);
|
||||||
targetRow.getCell(3).value = majorX.name;
|
targetRow.getCell(3).value = majorX.name;
|
||||||
targetRow.getCell(4).value = m.mth1.cost;
|
targetRow.getCell(4).value = m.mth1.cost;
|
||||||
targetRow.getCell(5).value = m.mth1.basicFormula;
|
targetRow.getCell(5).value = m.mth1.basicFormula;
|
||||||
@ -637,7 +666,7 @@ async function generateTemplate(data) {
|
|||||||
targetRow.getCell(9).value = m.mth2.fee;
|
targetRow.getCell(9).value = m.mth2.fee;
|
||||||
cusInsertRowFunc(4 + num_2_2, [sheet_2_2.getRow(4)], sheet_2_2, (targetRow) => {
|
cusInsertRowFunc(4 + num_2_2, [sheet_2_2.getRow(4)], sheet_2_2, (targetRow) => {
|
||||||
targetRow.getCell(1).value = num_2_2++;
|
targetRow.getCell(1).value = num_2_2++;
|
||||||
targetRow.getCell(2).value = serviceX.ref + '-' + (mindex + 1);
|
targetRow.getCell(2).value = serviceX.code + '-' + (mindex + 1);
|
||||||
targetRow.getCell(3).value = majorX.name;
|
targetRow.getCell(3).value = majorX.name;
|
||||||
targetRow.getCell(4).value = m.mth2.area;
|
targetRow.getCell(4).value = m.mth2.area;
|
||||||
targetRow.getCell(5).value = m.mth2.basicFormula;
|
targetRow.getCell(5).value = m.mth2.basicFormula;
|
||||||
@ -653,7 +682,7 @@ async function generateTemplate(data) {
|
|||||||
if (sobj.method3) {
|
if (sobj.method3) {
|
||||||
cusInsertRowFunc(3 + num_3, [sheet_3.getRow(3)], sheet_3, (targetRow) => {
|
cusInsertRowFunc(3 + num_3, [sheet_3.getRow(3)], sheet_3, (targetRow) => {
|
||||||
targetRow.getCell(1).value = num_3++;
|
targetRow.getCell(1).value = num_3++;
|
||||||
targetRow.getCell(2).value = serviceX.ref;
|
targetRow.getCell(2).value = serviceX.code;
|
||||||
targetRow.getCell(3).value = serviceX.name;
|
targetRow.getCell(3).value = serviceX.name;
|
||||||
targetRow.getCell(4).value = '/';
|
targetRow.getCell(4).value = '/';
|
||||||
targetRow.getCell(5).value = '/';
|
targetRow.getCell(5).value = '/';
|
||||||
@ -666,7 +695,7 @@ async function generateTemplate(data) {
|
|||||||
const taskX = taskList[tobj.task];
|
const taskX = taskList[tobj.task];
|
||||||
cusInsertRowFunc(3 + num_3, [sheet_3.getRow(3)], sheet_3, (targetRow) => {
|
cusInsertRowFunc(3 + num_3, [sheet_3.getRow(3)], sheet_3, (targetRow) => {
|
||||||
targetRow.getCell(1).value = num_3++;
|
targetRow.getCell(1).value = num_3++;
|
||||||
targetRow.getCell(2).value = taskX.ref;
|
targetRow.getCell(2).value = taskX.code;
|
||||||
targetRow.getCell(3).value = taskX.name + (taskX.desc ? `(${taskX.desc})` : '');
|
targetRow.getCell(3).value = taskX.name + (taskX.desc ? `(${taskX.desc})` : '');
|
||||||
targetRow.getCell(4).value = taskX.basicParam;
|
targetRow.getCell(4).value = taskX.basicParam;
|
||||||
targetRow.getCell(5).value = tobj.price;
|
targetRow.getCell(5).value = tobj.price;
|
||||||
@ -680,7 +709,7 @@ async function generateTemplate(data) {
|
|||||||
if (sobj.method4) {
|
if (sobj.method4) {
|
||||||
cusInsertRowFunc(4 + num_4, [sheet_4.getRow(4)], sheet_4, (targetRow) => {
|
cusInsertRowFunc(4 + num_4, [sheet_4.getRow(4)], sheet_4, (targetRow) => {
|
||||||
targetRow.getCell(1).value = num_4++;
|
targetRow.getCell(1).value = num_4++;
|
||||||
targetRow.getCell(2).value = serviceX.ref;
|
targetRow.getCell(2).value = serviceX.code;
|
||||||
targetRow.getCell(3).value = serviceX.name;
|
targetRow.getCell(3).value = serviceX.name;
|
||||||
targetRow.getCell(4).value = sobj.method4.person_num;
|
targetRow.getCell(4).value = sobj.method4.person_num;
|
||||||
targetRow.getCell(5).value = sobj.method4.work_day;
|
targetRow.getCell(5).value = sobj.method4.work_day;
|
||||||
@ -688,7 +717,7 @@ async function generateTemplate(data) {
|
|||||||
});
|
});
|
||||||
cusInsertRowFunc(5 + num_4_1, [sheet_4_1.getRow(5)], sheet_4_1, (targetRow) => {
|
cusInsertRowFunc(5 + num_4_1, [sheet_4_1.getRow(5)], sheet_4_1, (targetRow) => {
|
||||||
targetRow.getCell(1).value = num_4_1++;
|
targetRow.getCell(1).value = num_4_1++;
|
||||||
targetRow.getCell(2).value = serviceX.ref;
|
targetRow.getCell(2).value = serviceX.code;
|
||||||
targetRow.getCell(3).value = serviceX.name;
|
targetRow.getCell(3).value = serviceX.name;
|
||||||
targetRow.getCell(4).value = '/';
|
targetRow.getCell(4).value = '/';
|
||||||
targetRow.getCell(5).value = '/';
|
targetRow.getCell(5).value = '/';
|
||||||
@ -701,7 +730,7 @@ async function generateTemplate(data) {
|
|||||||
const expertX = expertList[eobj.expert];
|
const expertX = expertList[eobj.expert];
|
||||||
cusInsertRowFunc(5 + num_4_1, [sheet_4_1.getRow(5)], sheet_4_1, (targetRow) => {
|
cusInsertRowFunc(5 + num_4_1, [sheet_4_1.getRow(5)], sheet_4_1, (targetRow) => {
|
||||||
targetRow.getCell(1).value = num_4_1++;
|
targetRow.getCell(1).value = num_4_1++;
|
||||||
targetRow.getCell(2).value = expertX.ref;
|
targetRow.getCell(2).value = expertX.code;
|
||||||
targetRow.getCell(3).value = expertX.name;
|
targetRow.getCell(3).value = expertX.name;
|
||||||
targetRow.getCell(4).value = `${expertX.minPrice}~${expertX.maxPrice}`;
|
targetRow.getCell(4).value = `${expertX.minPrice}~${expertX.maxPrice}`;
|
||||||
targetRow.getCell(5).value = `${roundTo(toDecimal(toFiniteNumber(expertX.minPrice)).mul(toFiniteNumber(expertX.manageCoe)), 0)}~${roundTo(toDecimal(toFiniteNumber(expertX.maxPrice)).mul(toFiniteNumber(expertX.manageCoe)), 0)}`;
|
targetRow.getCell(5).value = `${roundTo(toDecimal(toFiniteNumber(expertX.minPrice)).mul(toFiniteNumber(expertX.manageCoe)), 0)}~${roundTo(toDecimal(toFiniteNumber(expertX.maxPrice)).mul(toFiniteNumber(expertX.manageCoe)), 0)}`;
|
||||||
@ -723,7 +752,7 @@ async function generateTemplate(data) {
|
|||||||
let siSum = 0;
|
let siSum = 0;
|
||||||
for (let i = 0; i < yz01Num; i++) {
|
for (let i = 0; i < yz01Num; i++) {
|
||||||
targetRow.getCell(i * 7 + 1).value = sindex + 1;
|
targetRow.getCell(i * 7 + 1).value = sindex + 1;
|
||||||
targetRow.getCell(i * 7 + 2).value = serviceX.ref;
|
targetRow.getCell(i * 7 + 2).value = serviceX.code;
|
||||||
targetRow.getCell(i * 7 + 3).value = serviceX.name;
|
targetRow.getCell(i * 7 + 3).value = serviceX.name;
|
||||||
targetRow.getCell(i * 7 + 4).value = s.contracts[i * 4];
|
targetRow.getCell(i * 7 + 4).value = s.contracts[i * 4];
|
||||||
targetRow.getCell(i * 7 + 5).value = s.contracts[i * 4 + 1];
|
targetRow.getCell(i * 7 + 5).value = s.contracts[i * 4 + 1];
|
||||||
@ -743,7 +772,7 @@ async function generateTemplate(data) {
|
|||||||
}
|
}
|
||||||
if (yz01Mod) {
|
if (yz01Mod) {
|
||||||
targetRow.getCell(yz01Num * 7 + 1).value = sindex + 1;
|
targetRow.getCell(yz01Num * 7 + 1).value = sindex + 1;
|
||||||
targetRow.getCell(yz01Num * 7 + 2).value = serviceX.ref;
|
targetRow.getCell(yz01Num * 7 + 2).value = serviceX.code;
|
||||||
targetRow.getCell(yz01Num * 7 + 3).value = serviceX.name;
|
targetRow.getCell(yz01Num * 7 + 3).value = serviceX.name;
|
||||||
if (yz01Mod == 1) {
|
if (yz01Mod == 1) {
|
||||||
targetRow.getCell(yz01Num * 7 + 4).value = numberFormatter(siSum, 2);
|
targetRow.getCell(yz01Num * 7 + 4).value = numberFormatter(siSum, 2);
|
||||||
@ -815,6 +844,10 @@ async function generateTemplate(data) {
|
|||||||
window.workbook = workbook;
|
window.workbook = workbook;
|
||||||
|
|
||||||
return workbook;
|
return workbook;
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error)
|
||||||
|
throw error
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -166,17 +166,84 @@ html {
|
|||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
gap: 6px;
|
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.zxfw-action-btn {
|
.zxfw-action-group {
|
||||||
border: 0;
|
display: inline-flex;
|
||||||
background: transparent;
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ag-theme-quartz .zxfw-action-btn {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 4px;
|
||||||
|
height: 24px;
|
||||||
|
padding: 0 7px;
|
||||||
|
border: 1px solid var(--border) !important;
|
||||||
|
box-shadow: inset 0 0 0 1px var(--border);
|
||||||
|
border-radius: 0;
|
||||||
|
background: var(--background) !important;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
font-size: 14px;
|
font-size: 11px;
|
||||||
line-height: 1;
|
line-height: 1.1;
|
||||||
padding: 0;
|
color: var(--foreground) !important;
|
||||||
|
transition: background-color 120ms ease, border-color 120ms ease, color 120ms ease, transform 90ms ease;
|
||||||
|
position: relative;
|
||||||
|
user-select: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.zxfw-action-group .zxfw-action-btn + .zxfw-action-btn {
|
||||||
|
margin-left: -1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.zxfw-action-group .zxfw-action-btn:first-child {
|
||||||
|
border-top-left-radius: 4px;
|
||||||
|
border-bottom-left-radius: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.zxfw-action-group .zxfw-action-btn:last-child {
|
||||||
|
border-top-right-radius: 4px;
|
||||||
|
border-bottom-right-radius: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ag-theme-quartz .zxfw-action-btn:hover {
|
||||||
|
color: var(--foreground) !important;
|
||||||
|
border-color: color-mix(in srgb, var(--muted-foreground) 45%, transparent) !important;
|
||||||
|
box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--muted-foreground) 45%, transparent);
|
||||||
|
background: color-mix(in srgb, var(--muted) 55%, transparent) !important;
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ag-theme-quartz .zxfw-action-btn:active {
|
||||||
|
transform: translateY(1px);
|
||||||
|
border-color: color-mix(in srgb, var(--foreground) 35%, transparent) !important;
|
||||||
|
box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--foreground) 35%, transparent);
|
||||||
|
background: var(--muted) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ag-theme-quartz .zxfw-action-btn:focus-visible {
|
||||||
|
outline: 2px solid color-mix(in srgb, var(--foreground) 25%, transparent);
|
||||||
|
outline-offset: 1px;
|
||||||
|
z-index: 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ag-theme-quartz .zxfw-action-btn--danger {
|
||||||
|
color: var(--destructive) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ag-theme-quartz .zxfw-action-btn--danger:hover {
|
||||||
|
color: var(--destructive) !important;
|
||||||
|
border-color: color-mix(in srgb, var(--destructive) 45%, transparent) !important;
|
||||||
|
box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--destructive) 45%, transparent);
|
||||||
|
background: color-mix(in srgb, var(--destructive) 10%, transparent) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ag-theme-quartz .zxfw-action-btn--danger:active {
|
||||||
|
border-color: color-mix(in srgb, var(--destructive) 65%, transparent) !important;
|
||||||
|
box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--destructive) 65%, transparent);
|
||||||
|
background: color-mix(in srgb, var(--destructive) 18%, transparent) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.picker-item-clickable {
|
.picker-item-clickable {
|
||||||
|
|||||||
@ -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/utils.ts","./src/lib/xmfactordefaults.ts","./src/lib/zwarchive.ts","./src/lib/zxfwpricingsync.ts","./src/pinia/pricingpanereload.ts","./src/pinia/tab.ts","./src/app.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/contractdetailview.vue","./src/components/views/ht.vue","./src/components/views/xm.vue","./src/components/views/xmconsultcategoryfactor.vue","./src/components/views/xmfactorgrid.vue","./src/components/views/xmmajorfactor.vue","./src/components/views/zxfwview.vue","./src/components/views/htinfo.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/utils.ts","./src/lib/xmfactordefaults.ts","./src/lib/zwarchive.ts","./src/lib/zxfwpricingsync.ts","./src/pinia/pricingpanereload.ts","./src/pinia/tab.ts","./src/app.vue","./src/components/common/commonaggrid.vue","./src/components/common/methodunavailablenotice.vue","./src/components/common/xmfactorgrid.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/contractdetailview.vue","./src/components/views/ht.vue","./src/components/views/servicecheckboxselector.vue","./src/components/views/xm.vue","./src/components/views/xmconsultcategoryfactor.vue","./src/components/views/xmmajorfactor.vue","./src/components/views/zxfwview.vue","./src/components/views/htinfo.vue","./src/components/views/info.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"}
|
||||||
Loading…
x
Reference in New Issue
Block a user