Compare commits
2 Commits
49c86d5668
...
c04ed4acb1
| Author | SHA1 | Date | |
|---|---|---|---|
| c04ed4acb1 | |||
| 68357babda |
@ -62,6 +62,14 @@ type XmInfoLike = {
|
||||
reviewedBy?: unknown
|
||||
preparedDate?: unknown
|
||||
projectIndustry?: unknown
|
||||
preparedCompany?: unknown
|
||||
overview?: unknown
|
||||
desc?: unknown
|
||||
}
|
||||
|
||||
type HtBaseInfoLike = {
|
||||
quality?: unknown
|
||||
duration?: unknown
|
||||
}
|
||||
|
||||
interface ScaleRowLike {
|
||||
@ -89,12 +97,26 @@ interface ZxFwRowLike {
|
||||
id: string
|
||||
process?: unknown
|
||||
subtotal?: unknown
|
||||
finalFee?: unknown
|
||||
investScale?: unknown
|
||||
landScale?: unknown
|
||||
workload?: unknown
|
||||
hourly?: unknown
|
||||
}
|
||||
|
||||
interface WorkContentRowLike {
|
||||
id?: unknown
|
||||
content?: unknown
|
||||
checked?: unknown
|
||||
custom?: unknown
|
||||
serviceGroup?: unknown
|
||||
isAddTrigger?: unknown
|
||||
}
|
||||
|
||||
interface WorkContentStateLike {
|
||||
detailRows?: WorkContentRowLike[]
|
||||
}
|
||||
|
||||
interface ZxFwStorageLike {
|
||||
selectedIds?: string[]
|
||||
selectedCodes?: string[]
|
||||
@ -175,6 +197,7 @@ interface ExportScaleRow {
|
||||
}
|
||||
|
||||
interface ExportMethod1Detail {
|
||||
proNum: number
|
||||
major: number
|
||||
cost: number
|
||||
basicFee: number
|
||||
@ -191,6 +214,7 @@ interface ExportMethod1Detail {
|
||||
}
|
||||
|
||||
interface ExportMethod1 {
|
||||
proAmount: number
|
||||
cost: number
|
||||
basicFee: number
|
||||
basicFee_basic: number
|
||||
@ -200,6 +224,7 @@ interface ExportMethod1 {
|
||||
}
|
||||
|
||||
interface ExportMethod2Detail {
|
||||
proNum: number
|
||||
major: number
|
||||
area: number
|
||||
basicFee: number
|
||||
@ -216,6 +241,7 @@ interface ExportMethod2Detail {
|
||||
}
|
||||
|
||||
interface ExportMethod2 {
|
||||
proAmount: number
|
||||
area: number
|
||||
basicFee: number
|
||||
basicFee_basic: number
|
||||
@ -259,13 +285,20 @@ interface ExportMethod4 {
|
||||
interface ExportService {
|
||||
id: number
|
||||
fee: number
|
||||
finalFee: number
|
||||
process: number
|
||||
tasks: ExportTaskGroup[]
|
||||
method1?: ExportMethod1
|
||||
method2?: ExportMethod2
|
||||
method3?: ExportMethod3
|
||||
method4?: ExportMethod4
|
||||
}
|
||||
|
||||
interface ExportTaskGroup {
|
||||
serviceid?: number
|
||||
text: string[]
|
||||
}
|
||||
|
||||
interface ExportServiceCoe {
|
||||
serviceid: number
|
||||
coe: number
|
||||
@ -284,6 +317,8 @@ interface ExportContract {
|
||||
addtionalFee: number
|
||||
reserveFee: number
|
||||
fee: number
|
||||
quality: string
|
||||
duration: string
|
||||
scale: ExportScaleRow[]
|
||||
serviceCoes: ExportServiceCoe[]
|
||||
majorCoes: ExportMajorCoe[]
|
||||
@ -314,10 +349,11 @@ interface ExportMethod5 {
|
||||
}
|
||||
|
||||
interface ExportAdditionalDetail {
|
||||
id: number
|
||||
id: number | string
|
||||
code?: unknown
|
||||
name: string
|
||||
fee: number
|
||||
tasks: ExportTaskGroup[]
|
||||
m0?: ExportMethod0
|
||||
m4?: ExportMethod4
|
||||
m5?: ExportMethod5
|
||||
@ -334,6 +370,7 @@ interface ExportReserve {
|
||||
code?: unknown
|
||||
name: string
|
||||
fee: number
|
||||
tasks: ExportTaskGroup[]
|
||||
m0?: ExportMethod0
|
||||
m4?: ExportMethod4
|
||||
m5?: ExportMethod5
|
||||
@ -343,10 +380,13 @@ interface ExportReportPayload {
|
||||
name: string
|
||||
writer: string
|
||||
reviewer: string
|
||||
company: string
|
||||
date: string
|
||||
industry: number
|
||||
fee: number
|
||||
scaleCost: number
|
||||
overview: string
|
||||
desc: string
|
||||
scale: ExportScaleRow[]
|
||||
serviceCoes: ExportServiceCoe[]
|
||||
majorCoes: ExportMajorCoe[]
|
||||
@ -1032,6 +1072,83 @@ const mapIndustryCodeToExportIndustry = (value: unknown): number => {
|
||||
return 0
|
||||
}
|
||||
|
||||
const parseScaleScopedRowId = (rowId: unknown) => {
|
||||
const raw = String(rowId || '').trim()
|
||||
const scopedMatch = /^(\d+)::(.+)$/.exec(raw)
|
||||
if (scopedMatch) {
|
||||
return {
|
||||
proNum: toSafeInteger(scopedMatch[1]) ?? 1,
|
||||
majorPart: String(scopedMatch[2] || '').trim()
|
||||
}
|
||||
}
|
||||
return {
|
||||
proNum: 1,
|
||||
majorPart: raw
|
||||
}
|
||||
}
|
||||
|
||||
const toScaleMajorId = (row: ScaleMethodRowLike): number | null => {
|
||||
const direct = toSafeInteger((row as { majorDictId?: unknown }).majorDictId)
|
||||
if (direct != null) return direct
|
||||
const parsed = parseScaleScopedRowId(row.id)
|
||||
return toSafeInteger(parsed.majorPart)
|
||||
}
|
||||
|
||||
const toScaleProNum = (row: ScaleMethodRowLike): number => {
|
||||
const parsed = parseScaleScopedRowId(row.id)
|
||||
return parsed.proNum > 0 ? parsed.proNum : 1
|
||||
}
|
||||
|
||||
const normalizeTaskText = (value: unknown): string => String(value || '').trim()
|
||||
|
||||
const groupWorkContentTasks = (
|
||||
rows: WorkContentRowLike[] | undefined,
|
||||
options?: { forceUngroup?: boolean; serviceLabelToId?: Map<string, number> }
|
||||
): ExportTaskGroup[] => {
|
||||
const source = Array.isArray(rows) ? rows : []
|
||||
const selected = source.filter(item => {
|
||||
if (item && item.isAddTrigger === true) return false
|
||||
const isCustom = Boolean(item?.custom)
|
||||
const isChecked = Boolean(item?.checked)
|
||||
return isCustom || isChecked
|
||||
})
|
||||
if (selected.length === 0) return []
|
||||
|
||||
const hasGroup = !options?.forceUngroup && selected.some(item => normalizeTaskText(item?.serviceGroup).length > 0)
|
||||
if (!hasGroup) {
|
||||
const text = selected
|
||||
.map(item => normalizeTaskText(item?.content))
|
||||
.filter(Boolean)
|
||||
return text.length > 0 ? [{ text }] : []
|
||||
}
|
||||
|
||||
const grouped = new Map<string, string[]>()
|
||||
const orderedGroupKeys: string[] = []
|
||||
for (const item of selected) {
|
||||
const groupName = normalizeTaskText(item?.serviceGroup)
|
||||
const key = groupName || '__ungrouped__'
|
||||
if (!grouped.has(key)) {
|
||||
grouped.set(key, [])
|
||||
orderedGroupKeys.push(key)
|
||||
}
|
||||
const content = normalizeTaskText(item?.content)
|
||||
if (!content) continue
|
||||
grouped.get(key)?.push(content)
|
||||
}
|
||||
|
||||
const byLabel = options?.serviceLabelToId || new Map<string, number>()
|
||||
return orderedGroupKeys
|
||||
.map(groupName => {
|
||||
const text = grouped.get(groupName) || []
|
||||
if (text.length === 0) return null
|
||||
const entry: ExportTaskGroup = { text }
|
||||
const resolvedServiceId = byLabel.get(groupName)
|
||||
if (resolvedServiceId != null) entry.serviceid = resolvedServiceId
|
||||
return entry
|
||||
})
|
||||
.filter((item): item is ExportTaskGroup => Boolean(item))
|
||||
}
|
||||
|
||||
const buildProjectServiceCoes = (rows: FactorRowLike[] | undefined): ExportServiceCoe[] => {
|
||||
if (!Array.isArray(rows)) return []
|
||||
return rows
|
||||
@ -1084,10 +1201,13 @@ const toExportScaleRows = (rows: ScaleRowLike[] | undefined): ExportScaleRow[] =
|
||||
const buildMethod1 = (rows: ScaleMethodRowLike[] | undefined): ExportMethod1 | null => {
|
||||
if (!Array.isArray(rows)) return null
|
||||
let hasTotalValue = false
|
||||
const proSet = new Set<number>()
|
||||
const det = rows
|
||||
.map(row => {
|
||||
const major = toSafeInteger(row.id)
|
||||
const major = toScaleMajorId(row)
|
||||
if (major == null || row.budgetFee == null) return null
|
||||
const proNum = toScaleProNum(row)
|
||||
proSet.add(proNum)
|
||||
const cost = toFiniteNumber(row.amount)
|
||||
const basicFee = toFiniteNumber(row.budgetFee)
|
||||
if (basicFee != null) hasTotalValue = true
|
||||
@ -1102,6 +1222,7 @@ const buildMethod1 = (rows: ScaleMethodRowLike[] | undefined): ExportMethod1 | n
|
||||
isNonEmptyString(remark)
|
||||
if (!hasValue) return null
|
||||
return {
|
||||
proNum,
|
||||
major,
|
||||
cost: cost ?? 0,
|
||||
basicFee: basicFee ?? 0,
|
||||
@ -1121,6 +1242,7 @@ const buildMethod1 = (rows: ScaleMethodRowLike[] | undefined): ExportMethod1 | n
|
||||
|
||||
if (det.length === 0 || !hasTotalValue) return null
|
||||
return {
|
||||
proAmount: proSet.size > 0 ? proSet.size : 1,
|
||||
cost: sumNumbers(det.map(item => item.cost)),
|
||||
basicFee: sumNumbers(det.map(item => item.basicFee)),
|
||||
basicFee_basic: sumNumbers(det.map(item => item.basicFee_basic)),
|
||||
@ -1133,10 +1255,13 @@ const buildMethod1 = (rows: ScaleMethodRowLike[] | undefined): ExportMethod1 | n
|
||||
const buildMethod2 = (rows: ScaleMethodRowLike[] | undefined): ExportMethod2 | null => {
|
||||
if (!Array.isArray(rows)) return null
|
||||
let hasTotalValue = false
|
||||
const proSet = new Set<number>()
|
||||
const det = rows
|
||||
.map(row => {
|
||||
const major = toSafeInteger(row.id)
|
||||
const major = toScaleMajorId(row)
|
||||
if (major == null || row.budgetFee == null) return null
|
||||
const proNum = toScaleProNum(row)
|
||||
proSet.add(proNum)
|
||||
const area = toFiniteNumber(row.landArea)
|
||||
const basicFee = toFiniteNumber(row.budgetFee)
|
||||
if (basicFee != null) hasTotalValue = true
|
||||
@ -1151,6 +1276,7 @@ const buildMethod2 = (rows: ScaleMethodRowLike[] | undefined): ExportMethod2 | n
|
||||
isNonEmptyString(remark)
|
||||
if (!hasValue) return null
|
||||
return {
|
||||
proNum,
|
||||
major,
|
||||
area: area ?? 0,
|
||||
basicFee: basicFee ?? 0,
|
||||
@ -1170,6 +1296,7 @@ const buildMethod2 = (rows: ScaleMethodRowLike[] | undefined): ExportMethod2 | n
|
||||
|
||||
if (det.length === 0 || !hasTotalValue) return null
|
||||
return {
|
||||
proAmount: proSet.size > 0 ? proSet.size : 1,
|
||||
area: sumNumbers(det.map(item => item.area)),
|
||||
basicFee: sumNumbers(det.map(item => item.basicFee)),
|
||||
basicFee_basic: sumNumbers(det.map(item => item.basicFee_basic)),
|
||||
@ -1353,6 +1480,50 @@ const loadHtFeeMethodsByRow = async (mainStorageKey: string, rowId: string) => {
|
||||
}
|
||||
}
|
||||
|
||||
const buildServiceGroupLabelToIdMap = (serviceIds: string[]): Map<string, number> => {
|
||||
const map = new Map<string, number>()
|
||||
for (const serviceId of serviceIds) {
|
||||
const item = (serviceList as Record<string, any>)[serviceId]
|
||||
if (!item) continue
|
||||
const id = toSafeInteger(serviceId)
|
||||
if (id == null) continue
|
||||
const label = `${String(item.code || '').trim()} ${String(item.name || '').trim()}`.trim()
|
||||
if (!label) continue
|
||||
map.set(label, id)
|
||||
}
|
||||
return map
|
||||
}
|
||||
|
||||
const buildServiceTasks = async (
|
||||
contractId: string,
|
||||
serviceId: string,
|
||||
serviceLabelToId: Map<string, number>
|
||||
): Promise<ExportTaskGroup[]> => {
|
||||
const taskState = await zxFwPricingStore.loadKeyState<WorkContentStateLike>(`work-content-${contractId}-${serviceId}`)
|
||||
return groupWorkContentTasks(taskState?.detailRows, { serviceLabelToId })
|
||||
}
|
||||
|
||||
const buildAdditionalRowTasks = async (contractId: string, rowId: string): Promise<ExportTaskGroup[]> => {
|
||||
const taskStorageKey = `work-content-htExtraFee-${contractId}-additional-work-${rowId}`
|
||||
const taskState = await zxFwPricingStore.loadKeyState<WorkContentStateLike>(taskStorageKey)
|
||||
return groupWorkContentTasks(taskState?.detailRows, { forceUngroup: true })
|
||||
}
|
||||
|
||||
const buildServiceFinalFee = (
|
||||
row: ZxFwRowLike | null | undefined,
|
||||
method1: ExportMethod1 | null,
|
||||
method2: ExportMethod2 | null,
|
||||
method3: ExportMethod3 | null,
|
||||
method4: ExportMethod4 | null
|
||||
) => {
|
||||
const finalFee = toFiniteNumber(row?.finalFee)
|
||||
if (finalFee != null) return finalFee
|
||||
const subtotal = toFiniteNumber(row?.subtotal)
|
||||
if (subtotal != null) return subtotal
|
||||
const methodSum = sumNumbers([method1?.fee, method2?.fee, method3?.fee, method4?.fee])
|
||||
return methodSum
|
||||
}
|
||||
|
||||
|
||||
|
||||
const buildAdditionalExport = async (contractId: string): Promise<ExportAdditional | null> => {
|
||||
@ -1363,15 +1534,17 @@ const buildAdditionalExport = async (contractId: string): Promise<ExportAddition
|
||||
|
||||
const det = (
|
||||
await Promise.all(
|
||||
rows.map(async (row, index) => {
|
||||
rows.map(async row => {
|
||||
const methodPayload = await loadHtFeeMethodsByRow(storageKey, row.id)
|
||||
if (!methodPayload) return null
|
||||
const tasks = await buildAdditionalRowTasks(contractId, row.id)
|
||||
const item: ExportAdditionalDetail = {
|
||||
id: index,
|
||||
id: row.id,
|
||||
code: { richText: [{ font: { charset: 134, color: { theme: 1 }, italic: true, name: '宋体', size: 10 }, text: 'C' }, { font: { charset: 134, color: { theme: 1 }, italic: true, name: 'Calibri', size: 10, vertAlign: 'subscript' }, text: 'F' }] },
|
||||
|
||||
name: row.name,
|
||||
fee: methodPayload.fee
|
||||
fee: methodPayload.fee,
|
||||
tasks
|
||||
}
|
||||
if (methodPayload.m0) item.m0 = methodPayload.m0
|
||||
if (methodPayload.m4) item.m4 = methodPayload.m4
|
||||
@ -1402,7 +1575,8 @@ const buildReserveExport = async (contractId: string): Promise<ExportReserve | n
|
||||
if (!methodPayload) continue
|
||||
const reserve: ExportReserve = {
|
||||
name: row.name || '预备费',
|
||||
fee: methodPayload.fee
|
||||
fee: methodPayload.fee,
|
||||
tasks: []
|
||||
}
|
||||
if (methodPayload.m0) reserve.m0 = methodPayload.m0
|
||||
if (methodPayload.m4) reserve.m4 = methodPayload.m4
|
||||
@ -1436,8 +1610,11 @@ const buildExportReportPayload = async (): Promise<ExportReportPayload> => {
|
||||
const projectName = isNonEmptyString(projectInfo.projectName) ? projectInfo.projectName.trim() : '造价项目'
|
||||
const writer = isNonEmptyString(projectInfo.preparedBy) ? projectInfo.preparedBy.trim() : ''
|
||||
const reviewer = isNonEmptyString(projectInfo.reviewedBy) ? projectInfo.reviewedBy.trim() : ''
|
||||
const company = isNonEmptyString(projectInfo.preparedCompany) ? projectInfo.preparedCompany.trim() : ''
|
||||
const date = isNonEmptyString(projectInfo.preparedDate) ? projectInfo.preparedDate.trim() : ''
|
||||
const industry = mapIndustryCodeToExportIndustry(projectInfo.projectIndustry)
|
||||
const overview = isNonEmptyString(projectInfo.overview) ? projectInfo.overview.trim() : ''
|
||||
const desc = isNonEmptyString(projectInfo.desc) ? projectInfo.desc.trim() : ''
|
||||
|
||||
const contractCards = (Array.isArray(contractCardsRaw) ? contractCardsRaw : [])
|
||||
.filter(item => item && typeof item.id === 'string')
|
||||
@ -1449,11 +1626,12 @@ const buildExportReportPayload = async (): Promise<ExportReportPayload> => {
|
||||
const contract = contractCards[index]
|
||||
const contractId = contract.id
|
||||
await zxFwPricingStore.loadContract(contractId)
|
||||
const [htInfoRaw, zxFwRaw, htConsultCategoryFactorRaw, htMajorFactorRaw] = await Promise.all([
|
||||
const [htInfoRaw, zxFwRaw, htConsultCategoryFactorRaw, htMajorFactorRaw, htBaseInfoRaw] = await Promise.all([
|
||||
kvStore.getItem<DetailRowsStorageLike<ScaleRowLike>>(`ht-info-v3-${contractId}`),
|
||||
kvStore.getItem<ZxFwStorageLike>(`zxFW-${contractId}`),
|
||||
kvStore.getItem<DetailRowsStorageLike<FactorRowLike>>(`ht-consult-category-factor-v1-${contractId}`),
|
||||
kvStore.getItem<DetailRowsStorageLike<FactorRowLike>>(`ht-major-factor-v1-${contractId}`)
|
||||
kvStore.getItem<DetailRowsStorageLike<FactorRowLike>>(`ht-major-factor-v1-${contractId}`),
|
||||
kvStore.getItem<HtBaseInfoLike>(`ht-base-info-${contractId}`)
|
||||
])
|
||||
|
||||
const contractState = zxFwPricingStore.getContractState(contractId)
|
||||
@ -1462,6 +1640,7 @@ const buildExportReportPayload = async (): Promise<ExportReportPayload> => {
|
||||
id: String(row.id || ''),
|
||||
process: row.process,
|
||||
subtotal: row.subtotal,
|
||||
finalFee: row.finalFee,
|
||||
investScale: row.investScale,
|
||||
landScale: row.landScale,
|
||||
workload: row.workload,
|
||||
@ -1494,6 +1673,7 @@ const buildExportReportPayload = async (): Promise<ExportReportPayload> => {
|
||||
const serviceIdTexts = sortServiceIdsByDict(
|
||||
(selectedIds.length > 0 ? selectedIds : fallbackServiceIds).filter(hasServiceId)
|
||||
)
|
||||
const serviceLabelToId = buildServiceGroupLabelToIdMap(serviceIdTexts)
|
||||
|
||||
const services = (
|
||||
await Promise.all(
|
||||
@ -1518,11 +1698,15 @@ const buildExportReportPayload = async (): Promise<ExportReportPayload> => {
|
||||
const method3 = buildMethod3(method3Raw?.detailRows)
|
||||
const method4 = buildMethod4(method4Raw?.detailRows)
|
||||
const fee = buildServiceFee(sourceRow, method1, method2, method3, method4)
|
||||
const finalFee = buildServiceFinalFee(sourceRow, method1, method2, method3, method4)
|
||||
const tasks = await buildServiceTasks(contractId, serviceIdText, serviceLabelToId)
|
||||
const process = Number(sourceRow?.process) === 1 ? 1 : 0
|
||||
const service: ExportService = {
|
||||
id: serviceId,
|
||||
process,
|
||||
fee
|
||||
fee,
|
||||
finalFee,
|
||||
tasks
|
||||
}
|
||||
if (method1) service.method1 = method1
|
||||
if (method2) service.method2 = method2
|
||||
@ -1564,6 +1748,8 @@ const buildExportReportPayload = async (): Promise<ExportReportPayload> => {
|
||||
addtionalFee,
|
||||
reserveFee,
|
||||
fee: contractFee,
|
||||
quality: isNonEmptyString(htBaseInfoRaw?.quality) ? htBaseInfoRaw.quality.trim() : '',
|
||||
duration: isNonEmptyString(htBaseInfoRaw?.duration) ? htBaseInfoRaw.duration.trim() : '',
|
||||
scale: contractScale,
|
||||
serviceCoes: contractServiceCoesRaw,
|
||||
majorCoes: contractMajorCoesRaw,
|
||||
@ -1577,10 +1763,13 @@ const buildExportReportPayload = async (): Promise<ExportReportPayload> => {
|
||||
name: projectName,
|
||||
writer,
|
||||
reviewer,
|
||||
company,
|
||||
date,
|
||||
industry,
|
||||
fee: sumNumbers(contracts.map(item => item.fee)),
|
||||
scaleCost: projectScaleCost,
|
||||
overview,
|
||||
desc,
|
||||
scale: projectScale,
|
||||
serviceCoes: projectServiceCoes,
|
||||
majorCoes: projectMajorCoes,
|
||||
|
||||
@ -9,7 +9,7 @@ import {
|
||||
PinnedRowModule,
|
||||
RowAutoHeightModule,
|
||||
TextEditorModule,
|
||||
TooltipModule,
|
||||
TooltipModule,ClientSideRowModelApiModule ,
|
||||
UndoRedoEditModule,RenderApiModule ,ColumnApiModule ,CellSpanModule ,RowStyleModule ,RowSelectionModule
|
||||
|
||||
} from 'ag-grid-community'
|
||||
@ -39,7 +39,7 @@ const AG_GRID_MODULES = [
|
||||
RowAutoHeightModule,ContextMenuModule,
|
||||
LargeTextEditorModule,
|
||||
UndoRedoEditModule,
|
||||
CellStyleModule,
|
||||
CellStyleModule,ClientSideRowModelApiModule ,
|
||||
PinnedRowModule,RenderApiModule ,ColumnApiModule ,
|
||||
TooltipModule,
|
||||
TreeDataModule,
|
||||
|
||||
94
src/sql.ts
94
src/sql.ts
@ -11,6 +11,34 @@ const toFiniteNumber = (value: unknown) => {
|
||||
const num = Number(value)
|
||||
return Number.isFinite(num) ? num : 0
|
||||
}
|
||||
|
||||
// 兼容导出 tasks 对象结构:[{ text: [] }, { serviceid, text: [] }]
|
||||
const normalizeTaskTexts = (tasks: unknown): string[] => {
|
||||
if (!Array.isArray(tasks)) return [];
|
||||
const result: string[] = [];
|
||||
const seen = new Set<string>();
|
||||
const pushText = (value: unknown) => {
|
||||
const text = String(value ?? '').trim();
|
||||
if (!text) return;
|
||||
if (seen.has(text)) return;
|
||||
seen.add(text);
|
||||
result.push(text);
|
||||
};
|
||||
tasks.forEach(item => {
|
||||
if (typeof item === 'string') {
|
||||
pushText(item);
|
||||
return;
|
||||
}
|
||||
if (!item || typeof item !== 'object') return;
|
||||
const textField = item.text;
|
||||
if (Array.isArray(textField)) {
|
||||
textField.forEach(pushText);
|
||||
return;
|
||||
}
|
||||
pushText(textField);
|
||||
});
|
||||
return result;
|
||||
}
|
||||
export type WorkType = '基本工作' | '可选工作' | '日常顾问' | '专项顾问' | '附加工作' | '自定义'
|
||||
|
||||
export const TYPE_LABEL_MAP: Record<number, WorkType> = {
|
||||
@ -797,7 +825,7 @@ export async function exportFile(fileName: string, data: any | (() => Promise<an
|
||||
const blob = new Blob([buffer], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' });
|
||||
const url1 = window.URL.createObjectURL(blob);
|
||||
const a = document.createElement('a');
|
||||
a.hcode = url1;
|
||||
a.href = url1;
|
||||
a.download = `${fileName}.xlsx`;
|
||||
a.click();
|
||||
URL.revokeObjectURL(url1);
|
||||
@ -811,7 +839,6 @@ export async function exportFile(fileName: string, data: any | (() => Promise<an
|
||||
// 按模板生成最终工作簿:填充封面、目录、各分表及汇总数据。
|
||||
async function generateTemplate(data) {
|
||||
// const downTextTmp = { richText: [{ font: { charset: 134, color: { theme: 1 }, italic: true, name: '宋体', size: 10 }, text: '常规' }, { font: { charset: 134, color: { theme: 1 }, italic: true, name: 'Calibri', size: 10, vertAlign: 'subscript' }, text: '下标' }] };
|
||||
console.log(data)
|
||||
// 编制说明 → 工作内容的前后默认项
|
||||
let prefixIDs = [6, 7, 8, 9, 10, 11, 12, 13, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27];
|
||||
let suffixIDs = [6, 7, 8, 9, 10, 11, 12, 13, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27];
|
||||
@ -2259,8 +2286,9 @@ async function generateTemplate(data) {
|
||||
targetRow.getCell(1).value = ` (${ciTastNum})${ai.id == 1 ? '负责协调工作,具体工作内容包括:' : '其他附加工作,具体工作内容包括:'}`;
|
||||
ciTastNum++;
|
||||
});
|
||||
if (ai.tasks?.length) {
|
||||
ai.tasks.forEach((ati, atindex) => {
|
||||
const additionalTaskTexts = normalizeTaskTexts(ai.tasks);
|
||||
if (additionalTaskTexts.length) {
|
||||
additionalTaskTexts.forEach((ati, atindex) => {
|
||||
let atiTextArr = paragraphLineBreakFor1112(` ${atindex + 1})${ati}。`, ctx);
|
||||
atiTextArr.forEach(ti => {
|
||||
cusInsertRowFunc(descRowNum, [descSheet.getRow(descRowNum - 1)], descSheet, (targetRow) => {
|
||||
@ -2375,41 +2403,25 @@ async function generateTemplate(data) {
|
||||
});
|
||||
}
|
||||
ci.services.forEach((si, sindex) => {
|
||||
let flag = false;
|
||||
if (si.tasks?.length) {
|
||||
si.tasks.forEach(tsi => {
|
||||
if (tsi.text?.length) {
|
||||
flag = true;
|
||||
let sx = tsi.serviceid == null ? { id: si.id, process: si.process } : { id: tsi.serviceid, process: tsi.process };
|
||||
let tsiTextArr = paragraphLineBreakFor1112(` (${ciTastNum})${sx.process == null ? '完成' : (sx.process == 1 ? '审核' : '编制')}${serviceList[sx.id].name},具体工作内容包括:`, ctx);
|
||||
tsiTextArr.forEach(ti => {
|
||||
cusInsertRowFunc(descRowNum3, [descSheet.getRow(descRowNum3 - 1)], descSheet, (targetRow) => {
|
||||
descRowNum3++;
|
||||
targetRow.getCell(1).value = ti;
|
||||
ciTastNum++;
|
||||
});
|
||||
});
|
||||
tsi.text.forEach((sti, stindex) => {
|
||||
let stiTextArr = paragraphLineBreakFor1112(` ${stindex + 1})${sti}。`, ctx);
|
||||
stiTextArr.forEach(ti => {
|
||||
cusInsertRowFunc(descRowNum3, [descSheet.getRow(descRowNum3 - 1)], descSheet, (targetRow) => {
|
||||
descRowNum3++;
|
||||
targetRow.getCell(1).value = ti;
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
let siTextArr = paragraphLineBreakFor1112(` (${ciTastNum})${si.process == null ? '' : (si.process == 1 ? '审核' : '编制')}${serviceList[si.id].name},具体工作内容包括:`, ctx);
|
||||
siTextArr.forEach(ti => {
|
||||
cusInsertRowFunc(descRowNum3, [descSheet.getRow(descRowNum3 - 1)], descSheet, (targetRow) => {
|
||||
descRowNum3++;
|
||||
targetRow.getCell(1).value = ti;
|
||||
ciTastNum++;
|
||||
});
|
||||
}
|
||||
if (!flag) {
|
||||
let siTextArr = paragraphLineBreakFor1112(` (${ciTastNum})${si.process == null ? '完成' : (si.process == 1 ? '审核' : '编制')}${serviceList[si.id].name},具体工作内容包括:`, ctx);
|
||||
siTextArr.forEach(ti => {
|
||||
cusInsertRowFunc(descRowNum3, [descSheet.getRow(descRowNum3 - 1)], descSheet, (targetRow) => {
|
||||
descRowNum3++;
|
||||
targetRow.getCell(1).value = ti;
|
||||
ciTastNum++;
|
||||
});
|
||||
if (si.tasks?.length) {
|
||||
si.tasks.forEach((sti, stindex) => {
|
||||
let stiTextArr = paragraphLineBreakFor1112(` ${stindex + 1})${sti}。`, ctx);
|
||||
stiTextArr.forEach(ti => {
|
||||
cusInsertRowFunc(descRowNum3, [descSheet.getRow(descRowNum3 - 1)], descSheet, (targetRow) => {
|
||||
descRowNum3++;
|
||||
targetRow.getCell(1).value = ti;
|
||||
});
|
||||
});
|
||||
});
|
||||
} else {
|
||||
cusInsertRowFunc(descRowNum3, [descSheet.getRow(descRowNum3 - 1)], descSheet, (targetRow) => {
|
||||
descRowNum3++;
|
||||
targetRow.getCell(1).value = ' 1)×××××。';
|
||||
@ -2423,8 +2435,9 @@ async function generateTemplate(data) {
|
||||
targetRow.getCell(1).value = ` (${ciTastNum})${ai.id == 1 ? '负责协调工作,具体工作内容包括:' : '其他附加工作,具体工作内容包括:'}`;
|
||||
ciTastNum++;
|
||||
});
|
||||
if (ai.tasks?.length) {
|
||||
ai.tasks.forEach((ati, atindex) => {
|
||||
const additionalTaskTexts = normalizeTaskTexts(ai.tasks);
|
||||
if (additionalTaskTexts.length) {
|
||||
additionalTaskTexts.forEach((ati, atindex) => {
|
||||
let atiTextArr = paragraphLineBreakFor1112(` ${atindex + 1})${ati}。`, ctx);
|
||||
atiTextArr.forEach(ti => {
|
||||
cusInsertRowFunc(descRowNum3, [descSheet.getRow(descRowNum3 - 1)], descSheet, (targetRow) => {
|
||||
@ -2520,9 +2533,10 @@ async function generateTemplate(data) {
|
||||
});
|
||||
}
|
||||
}
|
||||
if (data.desc) {
|
||||
if (String(data.desc || '').trim()) {
|
||||
descRowNum++;
|
||||
let otherDesc = paragraphLineBreakFor1112(` ${data.desc}${/。$/.test(ci.duration) ? '' : '。'}`, ctx);
|
||||
const otherDescText = String(data.desc || '').trim();
|
||||
let otherDesc = paragraphLineBreakFor1112(` ${otherDescText}${/。$/.test(otherDescText) ? '' : '。'}`, ctx);
|
||||
descSheet.getRow(descRowNum).getCell(1).value = otherDesc[0];
|
||||
descRowNum++;
|
||||
if (otherDesc.length > 1) {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user