This commit is contained in:
zwgczx committed 2026-03-18 11:19:30 +08:00
commit ad363041c3
6 files changed
+546 -56

No files matched your search

+22 -21
View File
@@ -594,9 +594,11 @@ const columnDefs: ColDef<DetailRow>[] = [
{
headerName: '名称',
field: 'name',
minWidth: 250,
minWidth: 180,
flex: 3,
tooltipField: 'name',
wrapText: true,
autoHeight: true,
cellStyle: { lineHeight: '1.4', paddingTop: '4px', paddingBottom: '4px' },
valueGetter: params => {
if (!params.data) return ''
if (isFixedRow(params.data)) return ''
@@ -607,9 +609,9 @@ const columnDefs: ColDef<DetailRow>[] = [
headerName: '工作环节',
field: 'process',
headerClass: 'ag-center-header zxfw-process-header',
minWidth: 170,
maxWidth: 220,
flex: 1.2,
minWidth: 80,
maxWidth: 100,
flex: 1,
editable: false,
sortable: false,
filter: false,
@@ -629,8 +631,8 @@ const columnDefs: ColDef<DetailRow>[] = [
headerName: '投资规模法',
field: 'investScale',
headerClass: 'ag-right-aligned-header',
minWidth: 140,
flex: 2,
minWidth: 100,
flex: 1.5,
cellClass: 'ag-right-aligned-cell',
editable: false,
@@ -646,8 +648,8 @@ const columnDefs: ColDef<DetailRow>[] = [
headerName: '用地规模法',
field: 'landScale',
headerClass: 'ag-right-aligned-header',
minWidth: 140,
flex: 2,
minWidth: 100,
flex: 1.5,
cellClass: 'ag-right-aligned-cell',
editable: false,
@@ -663,8 +665,8 @@ const columnDefs: ColDef<DetailRow>[] = [
headerName: '工作量法',
field: 'workload',
headerClass: 'ag-right-aligned-header',
minWidth: 120,
flex: 2,
minWidth: 90,
flex: 1.5,
cellClass: 'ag-right-aligned-cell',
editable: false,
@@ -681,8 +683,8 @@ const columnDefs: ColDef<DetailRow>[] = [
headerName: '工时法',
field: 'hourly',
headerClass: 'ag-right-aligned-header',
minWidth: 120,
flex: 2,
minWidth: 90,
flex: 1.5,
cellClass: 'ag-right-aligned-cell',
editable: false,
@@ -699,9 +701,8 @@ const columnDefs: ColDef<DetailRow>[] = [
headerName: '小计',
field: 'subtotal',
headerClass: 'ag-right-aligned-header',
flex: 3,
minWidth: 120,
flex: 2,
minWidth: 100,
cellClass: 'ag-right-aligned-cell',
editable: false,
valueGetter: params => {
@@ -720,8 +721,8 @@ const columnDefs: ColDef<DetailRow>[] = [
headerName: '确认金额',
field: 'finalFee',
headerClass: 'ag-right-aligned-header',
flex: 3,
minWidth: 140,
flex: 2,
minWidth: 110,
cellClass: 'ag-right-aligned-cell',
editable: params => !isFixedRow(params.data),
valueGetter: params => {
@@ -748,9 +749,9 @@ const columnDefs: ColDef<DetailRow>[] = [
{
headerName: '操作',
field: 'actions',
minWidth: 220,
flex: 2,
maxWidth: 260,
minWidth: 180,
flex: 1.5,
maxWidth: 220,
editable: false,
sortable: false,
filter: false,
+5 -5
View File
@@ -1092,15 +1092,15 @@ export const useZxFwPricingStore = defineStore('zxFwPricing', () => {
if (!state?.detailRows?.length) return null
const fixedRow = state.detailRows.find(row => String(row.id || '') === FIXED_ROW_ID)
const fixedSubtotal = toFiniteNumberOrNull(fixedRow?.subtotal)
if (fixedSubtotal != null) return round3(fixedSubtotal)
const fixedFinalFee = toFiniteNumberOrNull(fixedRow?.finalFee)
if (fixedFinalFee != null) return round3(fixedFinalFee)
let hasValid = false
const sum = state.detailRows.reduce((acc, row) => {
if (String(row.id || '') === FIXED_ROW_ID) return acc
const subtotal = toFiniteNumberOrNull(row.subtotal)
if (subtotal != null) hasValid = true
return subtotal == null ? acc : acc + subtotal
const fee = toFiniteNumberOrNull(row.finalFee) ?? toFiniteNumberOrNull(row.subtotal)
if (fee != null) hasValid = true
return fee == null ? acc : acc + fee
}, 0)
return hasValid ? round3(sum) : null
}
+152 -30
View File
@@ -152,7 +152,8 @@ export const expertList = {
};
export const additionalWorkList = [
{ id:'1',
{
id: '1',
code: {
richText: [
{ font: { charset: 134, color: { theme: 1 }, italic: true, name: '宋体', size: 10 }, text: 'C' },
@@ -161,7 +162,8 @@ export const additionalWorkList = [
},
name: '人员驻场服务及其他附加工作'
},
{id:'2',
{
id: '2',
code: {
richText: [
{ font: { charset: 134, color: { theme: 1 }, italic: true, name: '宋体', size: 10 }, text: 'C' },
@@ -174,7 +176,7 @@ export const additionalWorkList = [
export const reserveList = [
{
id:1,
id: 1,
code: {
richText: [
{ font: { charset: 134, color: { theme: 1 }, italic: true, name: '宋体', size: 10 }, text: 'Y' },
@@ -698,7 +700,7 @@ export async function exportFile(fileName: string, data: any | (() => Promise<an
}]
});
try {
onSaveConfirmed?.()
onSaveConfirmed?.()
const resolvedData = typeof data === 'function' ? await data() : data
const workbook = await generateTemplate(resolvedData);
const buffer = await workbook.xlsx.writeBuffer();
@@ -736,7 +738,7 @@ export async function exportFile(fileName: string, data: any | (() => Promise<an
// 按模板生成最终工作簿:填充封面、目录、各分表及汇总数据。
async function generateTemplate(data) {
data.contracts[0].services[0].tasks = ['依据本项目在招标阶段确认的设计图纸工程量,结合工程量清单计量支付规则,对设计工程量进行复核,包括构件工程量、明细表工程量和汇总表工程量,同时与相关方核对工程量', '依据核对后确认的设计图纸数量,细化与合并招标工程量清单或合同工程量清单,建立各维度清单间的数据链接,与相关单位完成核对与确认', '依据确定的招标工程量清单或合同工程量清单,拆解与合并相应的清单费用,与相关单位完成核对与确认', '现场勘查与测量现场实施工程量'];
// data.contracts[0].services[0].tasks = [{ text: '依据本项目在招标阶段确认的设计图纸工程量,结合工程量清单计量支付规则,对设计工程量进行复核,包括构件工程量、明细表工程量和汇总表工程量,同时与相关方核对工程量', '依据核对后确认的设计图纸数量,细化与合并招标工程量清单或合同工程量清单,建立各维度清单间的数据链接,与相关单位完成核对与确认', '依据确定的招标工程量清单或合同工程量清单,拆解与合并相应的清单费用,与相关单位完成核对与确认', '现场勘查与测量现场实施工程量'}];
// 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)
// 编制说明 → 工作内容的前后默认项
@@ -2096,16 +2098,118 @@ async function generateTemplate(data) {
// 合同段划分
descSheet.spliceRows(descRowNum, 1);
// 咨询服务类型
let serviceText = ' (二)咨询服务类型:' + data.contracts[0].services.slice(0, -1).map(si => serviceList[si.id].name).join('、') + (data.contracts[0].services.length > 1 ? '和' : '') + serviceList[data.contracts[0].services.slice(-1)[0].id].name + '。';
let serviceTextArr = paragraphLineBreakFor1112(serviceText, ctx);
serviceTextArr.forEach(ti => {
if (data.contracts[0].services.length) {
let serviceText = ' (二)咨询服务类型:' + data.contracts[0].services.slice(0, -1).map(si => serviceList[si.id].name).join('、') + (data.contracts[0].services.length > 1 ? '和' : '') + serviceList[data.contracts[0].services.slice(-1)[0].id].name + '。';
let serviceTextArr = paragraphLineBreakFor1112(serviceText, ctx);
serviceTextArr.forEach(ti => {
cusInsertRowFunc(descRowNum, [descSheet.getRow(descRowNum - 1)], descSheet, (targetRow) => {
descRowNum++;
targetRow.getCell(1).value = ti;
});
});
descSheet.spliceRows(descRowNum, 1);
} else {
descSheet.getRow(descRowNum).getCell(1).value = ' (二)咨询服务类型:×××××。';
descRowNum++;
}
// 工作内容及要求
let ci = data.contracts[0];
let ciTastNum = 1;
let ciTaskTitle = ` (三)${ci.name}工作内容及要求`;
let ciTaskTitleArr = paragraphLineBreakFor1112(ciTaskTitle, ctx);
ciTaskTitleArr.forEach(ti => {
cusInsertRowFunc(descRowNum, [descSheet.getRow(descRowNum - 1)], descSheet, (targetRow) => {
descRowNum++;
targetRow.getCell(1).value = ti;
});
});
// 工作内容及要求
descRowNum++;
cusInsertRowFunc(descRowNum, [descSheet.getRow(descRowNum - 1)], descSheet, (targetRow) => {
descRowNum++;
targetRow.getCell(1).value = ' 1.工作内容包括:';
});
if (ci.hasPreTexts) {
prefixTexts.forEach(ti => {
let texts = paragraphLineBreakFor1112(` (${ciTastNum})${ti}。`, ctx);
texts.forEach(ti => {
cusInsertRowFunc(descRowNum, [descSheet.getRow(descRowNum - 1)], descSheet, (targetRow) => {
descRowNum++;
targetRow.getCell(1).value = ti;
ciTastNum++;
});
});
});
}
ci.services.forEach((si, sindex) => {
let siTextArr = paragraphLineBreakFor1112(` (${ciTastNum})${si.process == null ? '' : (si.process == 1 ? '审核' : '编制')}${serviceList[si.id].name},具体工作内容包括:`, ctx);
siTextArr.forEach(ti => {
cusInsertRowFunc(descRowNum, [descSheet.getRow(descRowNum - 1)], descSheet, (targetRow) => {
descRowNum++;
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(descRowNum, [descSheet.getRow(descRowNum - 1)], descSheet, (targetRow) => {
descRowNum++;
targetRow.getCell(1).value = ti;
});
});
});
} else {
cusInsertRowFunc(descRowNum, [descSheet.getRow(descRowNum - 1)], descSheet, (targetRow) => {
descRowNum++;
targetRow.getCell(1).value = ' 1)×××××。';
});
}
});
if (ci.addtional && ci.addtional.det.length) {
ci.addtional.det.forEach(ai => {
cusInsertRowFunc(descRowNum, [descSheet.getRow(descRowNum - 1)], descSheet, (targetRow) => {
descRowNum++;
targetRow.getCell(1).value = ` (${ciTastNum})${ai.id == 1 ? '负责协调工作,具体工作内容包括:' : '其他附加工作,具体工作内容包括:'}`;
ciTastNum++;
});
if (ai.tasks?.length) {
ai.tasks.forEach((ati, atindex) => {
let atiTextArr = paragraphLineBreakFor1112(` ${atindex + 1})${ati}。`, ctx);
atiTextArr.forEach(ti => {
cusInsertRowFunc(descRowNum, [descSheet.getRow(descRowNum - 1)], descSheet, (targetRow) => {
descRowNum++;
targetRow.getCell(1).value = ti;
});
});
});
} else {
cusInsertRowFunc(descRowNum, [descSheet.getRow(descRowNum - 1)], descSheet, (targetRow) => {
descRowNum++;
targetRow.getCell(1).value = ' 1)×××××。';
});
}
});
}
if (ci.hasSufTexts) {
suffixTexts.forEach(ti => {
let texts = paragraphLineBreakFor1112(` (${ciTastNum})${ti}。`, ctx);
texts.forEach(ti => {
cusInsertRowFunc(descRowNum, [descSheet.getRow(descRowNum - 1)], descSheet, (targetRow) => {
descRowNum++;
targetRow.getCell(1).value = ti;
ciTastNum++;
});
});
});
}
cusInsertRowFunc(descRowNum, [descSheet.getRow(descRowNum - 1)], descSheet, (targetRow) => {
descRowNum++;
targetRow.getCell(1).value = ` 2.质量标准:${ci.quality || '×××××'}${/。$/.test(ci.quality) ? '' : '。'}`;
});
cusInsertRowFunc(descRowNum, [descSheet.getRow(descRowNum - 1)], descSheet, (targetRow) => {
descRowNum++;
targetRow.getCell(1).value = ` 3.服务工期:${ci.duration || '×××××'}${/。$/.test(ci.duration) ? '' : '。'}`;
});
} else {
descSheet.getRow(descRowNum).getCell(1).value = descSheet.getRow(descRowNum).getCell(1).value.replace(/×××/g, data.contracts.length);
let descRowNum1 = descRowNum + 1;
@@ -2144,8 +2248,12 @@ async function generateTemplate(data) {
});
// 咨询服务类型
descRowNum2 = descRowNum1 + descRowNum2 + 1;
console.log(ci.services)
let ciServiceText = ` ${cindex + 1}.${ci.name}:` + ci.services.slice(0, -1).map(si => serviceList[si.id].name).join('、') + (ci.services.length > 1 ? '和' : '') + serviceList[ci.services.slice(-1)[0].id].name + '。';
if (ci.services.length) {
var ciServiceText = ` ${cindex + 1}.${ci.name}:` + ci.services.slice(0, -1).map(si => serviceList[si.id].name).join('、') + (ci.services.length > 1 ? '和' : '') + serviceList[ci.services.slice(-1)[0].id].name + '。';
} else {
var ciServiceText = ` ${cindex + 1}.${ci.name}:×××××。`;
}
let ciServiceTextArr = paragraphLineBreakFor1112(ciServiceText, ctx);
ciServiceTextArr.forEach(ti => {
cusInsertRowFunc(descRowNum2, [descSheet.getRow(descRowNum2 - 1)], descSheet, (targetRow) => {
@@ -2166,7 +2274,7 @@ async function generateTemplate(data) {
});
cusInsertRowFunc(descRowNum3, [descSheet.getRow(descRowNum3 - 1)], descSheet, (targetRow) => {
descRowNum3++;
targetRow.getCell(1).value = ` 1.工作内容包括:`;
targetRow.getCell(1).value = ' 1.工作内容包括:';
});
if (ci.hasPreTexts) {
prefixTexts.forEach(ti => {
@@ -2181,7 +2289,7 @@ async function generateTemplate(data) {
});
}
ci.services.forEach((si, sindex) => {
let siTextArr = paragraphLineBreakFor1112(` (${ciTastNum})${si.process == 1 ? '审核' : '编制'}${serviceList[si.id].name},具体工作内容包括:`, ctx);
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++;
@@ -2189,15 +2297,22 @@ async function generateTemplate(data) {
ciTastNum++;
});
});
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;
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)×××××。';
});
}
});
if (ci.addtional && ci.addtional.det.length) {
ci.addtional.det.forEach(ai => {
@@ -2206,15 +2321,22 @@ async function generateTemplate(data) {
targetRow.getCell(1).value = ` (${ciTastNum})${ai.id == 1 ? '负责协调工作,具体工作内容包括:' : '其他附加工作,具体工作内容包括:'}`;
ciTastNum++;
});
ai.tasks?.forEach((ati, atindex) => {
let atiTextArr = paragraphLineBreakFor1112(` ${atindex + 1})${ati}。`, ctx);
atiTextArr.forEach(ti => {
cusInsertRowFunc(descRowNum3, [descSheet.getRow(descRowNum3 - 1)], descSheet, (targetRow) => {
descRowNum3++;
targetRow.getCell(1).value = ti;
if (ai.tasks?.length) {
ai.tasks.forEach((ati, atindex) => {
let atiTextArr = paragraphLineBreakFor1112(` ${atindex + 1})${ati}。`, ctx);
atiTextArr.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)×××××。';
});
}
});
}
if (ci.hasSufTexts) {
@@ -2231,11 +2353,11 @@ async function generateTemplate(data) {
}
cusInsertRowFunc(descRowNum3, [descSheet.getRow(descRowNum3 - 1)], descSheet, (targetRow) => {
descRowNum3++;
targetRow.getCell(1).value = ` 2.质量标准:${ci.quality || '×××'}${/。$/.test(ci.quality) ? '' : '。'}`;
targetRow.getCell(1).value = ` 2.质量标准:${ci.quality || '×××××'}${/。$/.test(ci.quality) ? '' : '。'}`;
});
cusInsertRowFunc(descRowNum3, [descSheet.getRow(descRowNum3 - 1)], descSheet, (targetRow) => {
descRowNum3++;
targetRow.getCell(1).value = ` 3.服务工期:${ci.duration || '×××'}${/。$/.test(ci.duration) ? '' : '。'}`;
targetRow.getCell(1).value = ` 3.服务工期:${ci.duration || '×××××'}${/。$/.test(ci.duration) ? '' : '。'}`;
});
});
descRowNum = descRowNum3;