1.4.1前端:

fix(市场预算):
   预算金额都改为元。
   导出文件名格式:S-XXX_ 项目名称_ 预算表,导出模板修改。
   预算人工标准:添加部门下拉框选择提醒。
   预算材料费 选择标准物料、非标准物料方式优化。
   预算材料费材料名称改为物料名称。
   预算安装费,分为承包、非承包类型,承包只填金额。
   预算差旅费,添加列高温补贴(元)、艰苦补贴(元)。
   其他费用的项目改为下拉框可输出,去掉运输费。
   预算表合同净额可以编辑
dev
xs 3 weeks ago
parent 0403e0ba20
commit c9de5fe849

@ -481,11 +481,11 @@ const updateBudgetTable = async () => {
const otherTotal = otherCostRef.value?.getTotalAmount() || { budgetAmount: 0, reducedAmount: 0 };
// ,
budgetTableRef.value.updateBudgetDetailData('材料费', materialTotal.budgetAmount / 10000, materialTotal.reducedAmount / 10000);
budgetTableRef.value.updateBudgetDetailData('人工费', laborTotal.budgetAmount / 10000, laborTotal.reducedAmount / 10000);
budgetTableRef.value.updateBudgetDetailData('安装费', installationTotal.budgetAmount / 10000, installationTotal.reducedAmount / 10000);
budgetTableRef.value.updateBudgetDetailData('差旅费', travelTotal.budgetAmount / 10000, travelTotal.reducedAmount / 10000);
budgetTableRef.value.updateBudgetDetailData('其他费用', otherTotal.budgetAmount / 10000, otherTotal.reducedAmount / 10000);
budgetTableRef.value.updateBudgetDetailData('材料费', materialTotal.budgetAmount, materialTotal.reducedAmount);
budgetTableRef.value.updateBudgetDetailData('人工费', laborTotal.budgetAmount, laborTotal.reducedAmount);
budgetTableRef.value.updateBudgetDetailData('安装费', installationTotal.budgetAmount, installationTotal.reducedAmount);
budgetTableRef.value.updateBudgetDetailData('差旅费', travelTotal.budgetAmount, travelTotal.reducedAmount);
budgetTableRef.value.updateBudgetDetailData('其他费用', otherTotal.budgetAmount, otherTotal.reducedAmount);
};
//
@ -507,13 +507,13 @@ const updateRdBudgetTable = async () => {
const otherTotal = otherCost.otherTotal || 0;
// ,
rdBudgetTableRef.value.updateRdBudgetDetailData('材料费', materialTotal / 10000);
rdBudgetTableRef.value.updateRdBudgetDetailData('人工费', laborTotal / 10000);
rdBudgetTableRef.value.updateRdBudgetDetailData('差旅费', travelTotal / 10000);
rdBudgetTableRef.value.updateRdBudgetDetailData('测试化验加工费', testingTotal / 10000);
rdBudgetTableRef.value.updateRdBudgetDetailData('专家咨询费用', expertConsultTotal / 10000);
rdBudgetTableRef.value.updateRdBudgetDetailData('新产品设计费', techConsultTotal / 10000);
rdBudgetTableRef.value.updateRdBudgetDetailData('其他费用', otherTotal / 10000);
rdBudgetTableRef.value.updateRdBudgetDetailData('材料费', materialTotal);
rdBudgetTableRef.value.updateRdBudgetDetailData('人工费', laborTotal);
rdBudgetTableRef.value.updateRdBudgetDetailData('差旅费', travelTotal);
rdBudgetTableRef.value.updateRdBudgetDetailData('测试化验加工费', testingTotal);
rdBudgetTableRef.value.updateRdBudgetDetailData('专家咨询费用', expertConsultTotal);
rdBudgetTableRef.value.updateRdBudgetDetailData('新产品设计费', techConsultTotal);
rdBudgetTableRef.value.updateRdBudgetDetailData('其他费用', otherTotal);
};
//

@ -86,9 +86,9 @@
<el-table-column label="版本" align="center" prop="budgetVersion" v-if="columns[34].visible" width="60"/>
<el-table-column label="项目经理" align="center" prop="managerName" v-if="columns[8].visible" width="100px;"/>
<el-table-column label="产品经理" align="center" prop="productManagerName" v-if="columns[10].visible" />
<el-table-column label="合同额(元)" align="center" prop="contractAmount" v-if="columns[14].visible" />
<el-table-column label="合同净额(元)" align="center" prop="netContractAmount" v-if="columns[15].visible" />
<el-table-column label="预算成本(元)" align="center" prop="budgetCost" v-if="columns[16].visible" />
<el-table-column label="合同额(元)" align="center" prop="contractAmount" v-if="columns[14].visible" />
<el-table-column label="合同净额(元)" align="center" prop="netContractAmount" v-if="columns[15].visible" />
<el-table-column label="预算成本(元)" align="center" prop="budgetCost" v-if="columns[16].visible" />
<el-table-column label="预算毛利率" align="center" prop="budgetRate" v-if="columns[17].visible">
<template #default="scope">
{{ formatRate(scope.row.budgetRate) }}
@ -459,7 +459,7 @@ const handleExport = (row?: budgetInfoVO) => {
{
budgetId: budgetId
},
fileNamePrefix + projectName + `(` + projectCode + `)` + `.xlsx`
projectCode + '_' + projectName + `_预算表.xlsx`
);
};

@ -36,14 +36,12 @@
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="合同额">
<el-input-number v-model="budgetForm.contractAmount" :min="0" :precision="2" @change="computedAmountAndRate" style="width:100%;text-align: left"/>
<el-input-number v-model="budgetForm.contractAmount" :min="0" :precision="2" @change="contractAmountChange" style="width:100%;text-align: left"/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="合同净额">
<div class="custom-display">
{{ budgetForm.netContractAmount || '0.00' }}
</div>
<el-input-number v-model="budgetForm.netContractAmount" :min="0" :precision="2" @change="computedAmountAndRate" style="width:100%;text-align: left"/>
</el-form-item>
</el-col>
</el-row>
@ -153,7 +151,7 @@ const budgetForm = reactive({
reduceBudgetRate: undefined,
duringOperation: undefined,
unitId: undefined,
unitName: '元',
unitName: '元',
exportFlag: undefined,
budgetStatus: undefined,
flowStatus: undefined,
@ -229,7 +227,7 @@ const budgetDetailData = ref([
}
]);
// ,
//
const formatNumber = (value: number) => {
if (!value) return '0.00';
return parseFloat(value).toFixed(2);
@ -318,9 +316,6 @@ watch(
);
const computedAmountAndRate = async () => {
if (budgetForm.contractAmount) {
budgetForm.netContractAmount = (budgetForm.contractAmount / 1.13).toFixed(2);
}
if (budgetForm.netContractAmount && budgetForm.budgetCost && budgetForm.netContractAmount > 0 && budgetForm.budgetCost > 0) {
budgetForm.budgetRate = (((budgetForm.netContractAmount - budgetForm.budgetCost) * 100) / budgetForm.netContractAmount).toFixed(2);
}
@ -329,6 +324,14 @@ const computedAmountAndRate = async () => {
}
};
const contractAmountChange = async () => {
if (budgetForm.contractAmount) {
budgetForm.netContractAmount = (budgetForm.contractAmount / 1.13).toFixed(2);
}
};
//
defineExpose({
updateBudgetDetailData,

@ -34,6 +34,13 @@
<!-- 预算成本 -->
<el-table-column label="预算成本" align="center">
<el-table-column prop="sortOrder" label="序号" width="60" align="center" />
<el-table-column prop="type" label="类型" width="120">
<template #default="scope">
<el-select v-model="scope.row.installType" placeholder="请选择类型" clearable @change="handleTypeChange(scope.row)">
<el-option v-for="dict in install_type" :key="dict.value" :label="dict.label" :value="dict.value" />
</el-select>
</template>
</el-table-column>
<el-table-column prop="personnelCategory" label="人员类别" width="150">
<template #default="scope">
<el-input v-model="scope.row.personnelCategory" placeholder="请输入人员类别" />
@ -41,27 +48,32 @@
</el-table-column>
<el-table-column prop="peopleNumber" label="人数" width="120">
<template #default="scope">
<el-input-number v-model="scope.row.peopleNumber" :min="0" :precision="0" size="small" @change="calculateBudgetAmount(scope.row)" style="width:106px;"/>
<el-input-number v-if="scope.row.installType === INSTALL_TYPE.NON_CONTRACT" v-model="scope.row.peopleNumber" :min="0" :precision="0" size="small" @change="calculateBudgetAmount(scope.row)" style="width:106px;"/>
<span v-else></span>
</template>
</el-table-column>
<el-table-column prop="cumulativeTime" label="累计时间(月)" width="120">
<template #default="scope">
<el-input-number v-model="scope.row.cumulativeTime" :min="0" :precision="2" size="small" @change="calculateBudgetAmount(scope.row)" style="width:106px;"/>
<el-input-number v-if="scope.row.installType === INSTALL_TYPE.NON_CONTRACT" v-model="scope.row.cumulativeTime" :min="0" :precision="2" size="small" @change="calculateBudgetAmount(scope.row)" style="width:106px;"/>
<span v-else></span>
</template>
</el-table-column>
<el-table-column prop="monthRate" label="月平均投入比例(%)" width="150">
<template #default="scope">
<el-input-number v-model="scope.row.monthRate" :min="0" :max="100" :precision="2" size="small" @change="calculateBudgetAmount(scope.row)" style="width:136px;"/>
<el-input-number v-if="scope.row.installType === INSTALL_TYPE.NON_CONTRACT" v-model="scope.row.monthRate" :min="0" :max="100" :precision="2" size="small" @change="calculateBudgetAmount(scope.row)" style="width:136px;"/>
<span v-else></span>
</template>
</el-table-column>
<el-table-column prop="artificialStandard" label="人工标准(元/人月)" width="150">
<template #default="scope">
<el-input-number v-model="scope.row.artificialStandard" :min="0" :precision="2" :step="10" size="small" @change="calculateBudgetAmount(scope.row)" style="width:136px;"/>
<el-input-number v-if="scope.row.installType === INSTALL_TYPE.NON_CONTRACT" v-model="scope.row.artificialStandard" :min="0" :precision="2" :step="10" size="small" @change="calculateBudgetAmount(scope.row)" style="width:136px;"/>
<span v-else></span>
</template>
</el-table-column>
<el-table-column prop="price" label="金额(万元)" width="100">
<el-table-column prop="price" label="金额(元)" width="150">
<template #default="scope">
{{ format2TenThousandNumber(scope.row.price) }}
<el-input-number v-if="scope.row.installType === INSTALL_TYPE.CONTRACT" v-model="scope.row.price" :min="0" :precision="2" size="small" style="width:136px;"/>
<span v-else>{{ formatNumber(scope.row.price) }}</span>
</template>
</el-table-column>
</el-table-column>
@ -75,27 +87,32 @@
</el-table-column>
<el-table-column prop="reducePeopleNumber" label="人数" width="120">
<template #default="scope">
<el-input-number v-model="scope.row.reducePeopleNumber" :min="0" :precision="0" size="small" @change="calculateReducedAmount(scope.row)" style="width:106px;"/>
<el-input-number v-if="scope.row.installType === INSTALL_TYPE.NON_CONTRACT" v-model="scope.row.reducePeopleNumber" :min="0" :precision="0" size="small" @change="calculateReducedAmount(scope.row)" style="width:106px;"/>
<span v-else></span>
</template>
</el-table-column>
<el-table-column prop="reduceCumulativeTime" label="累计时间(月)" width="120">
<template #default="scope">
<el-input-number v-model="scope.row.reduceCumulativeTime" :min="0" :precision="2" size="small" @change="calculateReducedAmount(scope.row)" style="width:106px;"/>
<el-input-number v-if="scope.row.installType === INSTALL_TYPE.NON_CONTRACT" v-model="scope.row.reduceCumulativeTime" :min="0" :precision="2" size="small" @change="calculateReducedAmount(scope.row)" style="width:106px;"/>
<span v-else></span>
</template>
</el-table-column>
<el-table-column prop="reduceMonthRate" label="月平均投入比例(%)" width="150">
<template #default="scope">
<el-input-number v-model="scope.row.reduceMonthRate" :min="0" :max="100" :precision="2" size="small" @change="calculateReducedAmount(scope.row)" style="width:136px;"/>
<el-input-number v-if="scope.row.installType === INSTALL_TYPE.NON_CONTRACT" v-model="scope.row.reduceMonthRate" :min="0" :max="100" :precision="2" size="small" @change="calculateReducedAmount(scope.row)" style="width:136px;"/>
<span v-else></span>
</template>
</el-table-column>
<el-table-column prop="reduceArtificialStandard" label="人工标准(元/人月)" width="150">
<template #default="scope">
<el-input-number v-model="scope.row.reduceArtificialStandard" :min="0" :precision="2" :step="10" size="small" @change="calculateReducedAmount(scope.row)" style="width:136px;"/>
<el-input-number v-if="scope.row.installType === INSTALL_TYPE.NON_CONTRACT" v-model="scope.row.reduceArtificialStandard" :min="0" :precision="2" :step="10" size="small" @change="calculateReducedAmount(scope.row)" style="width:136px;"/>
<span v-else></span>
</template>
</el-table-column>
<el-table-column prop="reducePrice" label="金额(万元)" width="100">
<el-table-column prop="reducePrice" label="金额(元)" width="150">
<template #default="scope">
{{ format2TenThousandNumber(scope.row.reducePrice) }}
<el-input-number v-if="scope.row.installType === INSTALL_TYPE.CONTRACT" v-model="scope.row.reducePrice" :min="0" :precision="2" size="small" style="width:136px;"/>
<span v-else>{{ formatNumber(scope.row.reducePrice) }}</span>
</template>
</el-table-column>
</el-table-column>
@ -135,9 +152,16 @@
<script setup lang="ts">
import { ref } from 'vue'
import { budgetInstallCostVO } from '@/api/oa/erp/budgetInfo/market/budgetInstallCost/types';
import { budgetMaterialCostVO } from '@/api/oa/erp/budgetInfo/market/budgetMaterialCost/types';
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
const { install_type } = toRefs<any>(
proxy?.useDict('install_type')
);
const INSTALL_TYPE = {
NON_CONTRACT: '1', //
CONTRACT: '2' //
}
//
const installCostList = ref<budgetInstallCostVO[]>([]);
const toDeletedInstallCostIdList = ref([]);
@ -163,7 +187,7 @@ const personnelCategories = ref([
{ label: '其他', value: '其他' }
])
// ,
//
const formatNumber = (value: number) => {
if (!value) return '0.00';
return parseFloat(value).toFixed(2);
@ -175,24 +199,37 @@ const format2TenThousandNumber = (value: number) => {
return (parseFloat(value) / 10000).toFixed(2);
};
//
const handleTypeChange = (row: any) => {
if (row.installType === INSTALL_TYPE.NON_CONTRACT) {
//
calculateBudgetAmount(row)
}
}
//
const calculateBudgetAmount = (row: any) => {
const peopleNumber = parseFloat(row.peopleNumber) || 0
const cumulativeTime = parseFloat(row.cumulativeTime) || 0
const monthRate = parseFloat(row.monthRate) || 0
const artificialStandard = parseFloat(row.artificialStandard) || 0
//
if (row.installType === INSTALL_TYPE.NON_CONTRACT) {
const peopleNumber = parseFloat(row.peopleNumber) || 0
const cumulativeTime = parseFloat(row.cumulativeTime) || 0
const monthRate = parseFloat(row.monthRate) || 0
const artificialStandard = parseFloat(row.artificialStandard) || 0
row.price = peopleNumber * cumulativeTime * (monthRate / 100) * artificialStandard
row.price = peopleNumber * cumulativeTime * (monthRate / 100) * artificialStandard
}
}
//
const calculateReducedAmount = (row: any) => {
const peopleNumber = parseFloat(row.reducePeopleNumber) || 0
const cumulativeTime = parseFloat(row.reduceCumulativeTime) || 0
const monthRate = parseFloat(row.reduceMonthRate) || 0
const artificialStandard = parseFloat(row.reduceArtificialStandard) || 0
if (row.installType === INSTALL_TYPE.NON_CONTRACT) {
const peopleNumber = parseFloat(row.reducePeopleNumber) || 0
const cumulativeTime = parseFloat(row.reduceCumulativeTime) || 0
const monthRate = parseFloat(row.reduceMonthRate) || 0
const artificialStandard = parseFloat(row.reduceArtificialStandard) || 0
row.reducePrice = peopleNumber * cumulativeTime * (monthRate / 100) * artificialStandard
row.reducePrice = peopleNumber * cumulativeTime * (monthRate / 100) * artificialStandard
}
}
//
@ -209,6 +246,7 @@ const handleAddRows = () => {
for (let i = 0; i < addRowCount.value; i++) {
installCostList.value.push({
sortOrder: currentSortOrder + i + 1,
installType: INSTALL_TYPE.NON_CONTRACT,
personnelCategory: '',
peopleNumber: 0,
cumulativeTime: 0,
@ -267,7 +305,7 @@ const getSummaries = (param: any) => {
const sums: any[] = []
columns.forEach((column: any, index: number) => {
if (index === 2) {
sums[index] = '合计(元)'
sums[index] = '合计(元)'
return
}
if (column.property === 'price' || column.property === 'reducePrice') {
@ -281,7 +319,7 @@ const getSummaries = (param: any) => {
return prev
}
}, 0)
sums[index] = format2TenThousandNumber(sums[index])
sums[index] = formatNumber(sums[index])
} else {
sums[index] = ''
}
@ -294,8 +332,8 @@ const getSummaries = (param: any) => {
//
const getTotalAmount = () => {
const totalBudgetAmount = installCostList.value.reduce((sum, item) => sum + Number(item.price), 0)
const totalReducedAmount = installCostList.value.reduce((sum, item) => sum + Number(item.reducePrice), 0)
const totalBudgetAmount = installCostList.value.reduce((sum, item) => sum + Number(item.price), 0);
const totalReducedAmount = installCostList.value.reduce((sum, item) => sum + Number(item.reducePrice), 0);
return {
budgetAmount: totalBudgetAmount,
reducedAmount: totalReducedAmount

@ -78,20 +78,25 @@
</el-table-column>
<el-table-column prop="artificialStandard" label="人工标准(元/人月)" width="150">
<template #default="scope">
<el-input-number
v-model="scope.row.artificialStandard"
:min="0"
:precision="2"
:step="10"
size="small"
@change="calculateBudgetAmount(scope.row)"
style="width: 136px"
/>
<el-tooltip
:content="getArtificialStandardTooltipContent(scope.row)"
placement="top"
raw-content
:show-after="500"
>
<el-select v-model="scope.row.artificialStandard" placeholder="请选择或输入后回车" clearable
filterable
allow-create style="flex: 1" default-first-option
@change="handleChangeArtificialStandard(scope.row)"
@blur="handleBlurArtificialStandard(scope.row)">
<el-option v-for="dict in artificial_standard" :key="dict.value" :label="dict.value" :value="dict.value"/>
</el-select>
</el-tooltip>
</template>
</el-table-column>
<el-table-column prop="price" label="金额(万元)" width="100">
<el-table-column prop="price" label="金额(元)" width="100">
<template #default="scope">
{{ format2TenThousandNumber(scope.row.price) }}
{{ formatNumber(scope.row.price) }}
</template>
</el-table-column>
</el-table-column>
@ -142,20 +147,25 @@
</el-table-column>
<el-table-column prop="reduceArtificialStandard" label="人工标准(元/人月)" width="150">
<template #default="scope">
<el-input-number
v-model="scope.row.reduceArtificialStandard"
:min="0"
:precision="2"
:step="10"
size="small"
@change="calculateReducedAmount(scope.row)"
style="width: 136px"
/>
<el-tooltip
:content="getArtificialStandardTooltipContent(scope.row)"
placement="top"
raw-content
:show-after="500"
>
<el-select v-model="scope.row.reduceArtificialStandard" placeholder="请选择或输入后回车" clearable
filterable
allow-create style="flex: 1" default-first-option
@change="handleChangeReduceArtificialStandard(scope.row)"
@blur="handleBlurReduceArtificialStandard(scope.row)">
<el-option v-for="dict in artificial_standard" :key="dict.value" :label="dict.value" :value="dict.value"/>
</el-select>
</el-tooltip>
</template>
</el-table-column>
<el-table-column prop="reducePrice" label="金额(万元)" width="100">
<el-table-column prop="reducePrice" label="金额(元)" width="100">
<template #default="scope">
{{ format2TenThousandNumber(scope.row.reducePrice) }}
{{ formatNumber(scope.row.reducePrice) }}
</template>
</el-table-column>
</el-table-column>
@ -192,6 +202,11 @@
import { ref } from 'vue';
import { budgetLaborCostVO } from '@/api/oa/erp/budgetInfo/market/budgetLaborCost/types';
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
const { artificial_standard } = toRefs<any>(
proxy?.useDict('artificial_standard')
);
//
const budgetLaborCostList = ref<budgetLaborCostVO[]>([]);
const toDeletedLaborCostIdList = ref([]);
@ -203,6 +218,8 @@ const selectedRows = ref([]);
const showAddDialog = ref(false);
const addRowCount = ref(1);
//
const personnelCategories = ref([
{ label: '项目经理', value: '项目经理' },
@ -217,7 +234,7 @@ const personnelCategories = ref([
{ label: '其他', value: '其他' }
]);
// ,
//
const formatNumber = (value: number) => {
if (!value) return '0.00';
return parseFloat(value).toFixed(2);
@ -229,6 +246,42 @@ const format2TenThousandNumber = (value: number) => {
return (parseFloat(value) / 10000).toFixed(2);
};
const getArtificialStandardTooltipContent = (row: any) => {
if (!artificial_standard.value || artificial_standard.value.length === 0) {
return '暂无可用选项'
}
// valuelabel
const optionsHtml = artificial_standard.value
.map(dict => `<div style="padding: 2px 0;">${dict.value}${dict.label}</div>`)
.join('')
return `<div style="max-height: 200px; overflow-y: auto;">${optionsHtml}</div>`
};
//
const isValidNumber = (value) => {
if (value === null || value === undefined || value === '') return true
return /^\d+$/.test(String(value))
}
const handleChangeArtificialStandard = (row) => {
if (!isValidNumber(row.artificialStandard) && row.artificialStandard !== '') {
ElMessage.warning('只能输入数字')
row.artificialStandard = null
} else {
calculateBudgetAmount(row)
}
}
const handleBlurArtificialStandard = (row) => {
//
if (row.artificialStandard && !isNaN(row.artificialStandard)) {
row.artificialStandard = Number(row.artificialStandard)
}
}
//
const calculateBudgetAmount = (row: any) => {
const peopleNumber = parseFloat(row.peopleNumber) || 0;
@ -239,6 +292,23 @@ const calculateBudgetAmount = (row: any) => {
row.price = peopleNumber * cumulativeTime * (monthRate / 100) * artificialStandard; //yuan
};
const handleChangeReduceArtificialStandard = (row) => {
if (!isValidNumber(row.reduceArtificialStandard) && row.reduceArtificialStandard !== '') {
ElMessage.warning('只能输入数字')
row.reduceArtificialStandard = null
} else {
calculateReducedAmount(row)
}
}
const handleBlurReduceArtificialStandard = (row) => {
//
if (row.reduceArtificialStandard && !isNaN(row.reduceArtificialStandard)) {
row.reduceArtificialStandard = Number(row.reduceArtificialStandard)
}
}
//
const calculateReducedAmount = (row: any) => {
const peopleNumber = parseFloat(row.reducePeopleNumber) || 0;
@ -265,13 +335,13 @@ const handleAddRows = () => {
peopleNumber: 0,
cumulativeTime: 0,
monthRate: 0,
artificialStandard: 0,
artificialStandard: undefined,
price: 0,
reducePersonnelCategory: '',
reducePeopleNumber: 0,
reduceCumulativeTime: 0,
reduceMonthRate: 0,
reduceArtificialStandard: 0,
reduceArtificialStandard: undefined,
reducePrice: 0,
reduceProposal: ''
});
@ -318,7 +388,7 @@ const getSummaries = (param: any) => {
const sums: any[] = [];
columns.forEach((column: any, index: number) => {
if (index === 2) {
sums[index] = '合计(元)';
sums[index] = '合计(元)';
return;
}
@ -333,7 +403,7 @@ const getSummaries = (param: any) => {
return prev;
}
}, 0);
sums[index] = format2TenThousandNumber(sums[index]);
sums[index] = formatNumber(sums[index]);
} else {
sums[index] = '';
}

@ -4,23 +4,56 @@
<div class="card-header">
<span class="title">材料费预算明细表</span>
<div class="flex items-center gap-2">
<span style="white-space: nowrap">行数:</span>
<el-input-number v-model="addRowCount" :min="1" :max="10" size="small" style="width: 80px" />
<el-button type="primary" size="small" @click="handleAddRows">
<el-icon>
<Plus />
</el-icon>
添加</el-button>
<el-button type="primary" size="small" @click="handleShowMaterial">
<el-icon>
<Search />
</el-icon>
选择物料</el-button>
<!-- <span style="white-space: nowrap">行数:</span>-->
<!-- <el-input-number v-model="addRowCount" :min="1" :max="10" size="small" style="width: 80px" />-->
<!-- <el-button type="primary" size="small" @click="handleAddRows">-->
<!-- <el-icon>-->
<!-- <Plus />-->
<!-- </el-icon>-->
<!-- 添加-->
<!-- </el-button>-->
<!-- <el-button type="primary" size="small" @click="handleShowMaterial"> <el-icon>-->
<!-- <Search />-->
<!-- </el-icon>-->
<!-- 选择物料-->
<!-- </el-button>-->
<!-- 新增的下拉按钮 -->
<el-dropdown trigger="click" @command="handleDropdownCommand">
<el-button type="primary" size="small">
添加物料 <el-icon><ArrowDown /></el-icon>
</el-button>
<template #dropdown>
<el-dropdown-menu>
<el-dropdown-item divided>
<div class="custom-dropdown-item" @click.stop="handleAddRows">
<span>添加非标准物料</span>
<el-input-number
v-model="addRowCount"
:min="1"
:max="1000"
size="small"
controls-position="right"
style="width: 80px"
@click.stop
/>
<span style="margin-left: 4px"></span>
</div>
</el-dropdown-item>
<el-dropdown-item command="standard">
选择标准物料
</el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown>
<el-button type="danger" size="small" @click="handleBatchDelete" :disabled="selectedRows.length === 0">
<el-icon>
<Delete />
</el-icon>
删除 </el-button>
删除
</el-button>
</div>
</div>
</template>
@ -45,7 +78,7 @@
<span>{{ scope.row.materialCode }}</span>
</template>
</el-table-column>
<el-table-column prop="materialName" label="料名称" width="200">
<el-table-column prop="materialName" label="料名称" width="200">
<template #default="scope">
<el-input v-model="scope.row.materialName" type="textarea" :rows="1" :disabled="scope.row.materialId !== null" />
</template>
@ -311,6 +344,17 @@ const getMaterialList = async () => {
materialLoading.value = false;
};
const handleDropdownCommand = (command) => {
if (command === 'notStandard') {
//
handleAddRows();
} else if (command === 'standard') {
//
handleShowMaterial();
//
}
};
//
const handleAddRows = () => {
const currentSortOrder =
@ -489,7 +533,7 @@ const confirmMaterialSelection = () => {
materialSearchKeyword.value = '';
};
// ,
//
const formatNumber = (value: number) => {
if (!value) return '0.00';
return parseFloat(value).toFixed(2);
@ -536,7 +580,7 @@ const getSummaries = (param: any) => {
return;
}
if (column.property === 'materialName') {
sums[index] = '合计(元)';
sums[index] = '合计(元)';
return;
}
@ -551,7 +595,7 @@ const getSummaries = (param: any) => {
}
}, 0);
if (column.property === 'price' || column.property === 'reducePrice') {
sums[index] = format2TenThousandNumber(sums[index]);
sums[index] = formatNumber(sums[index]);
} else {
sums[index] = formatNumber(sums[index]);
}

@ -29,7 +29,9 @@
<el-table-column prop="sortOrder" label="序号" width="80" align="center" />
<el-table-column prop="itemDesc" label="项目" width="200">
<template #default="scope">
<el-input v-model="scope.row.itemDesc" />
<el-select v-model="scope.row.itemDesc" placeholder="请选择项目" clearable filterable allow-create>
<el-option v-for="dict in budget_other_item" :key="dict.value" :label="dict.label" :value="dict.value" />
</el-select>
</template>
</el-table-column>
<el-table-column prop="price" label="金额(元)" width="160">
@ -43,7 +45,9 @@
<el-table-column label="降成本后预算成本" align="center">
<el-table-column prop="reduceItemDesc" label="项目" width="200">
<template #default="scope">
<el-input v-model="scope.row.reduceItemDesc" />
<el-select v-model="scope.row.reduceItemDesc" placeholder="请选择项目" clearable filterable allow-create>
<el-option v-for="dict in budget_other_item" :key="dict.value" :label="dict.label" :value="dict.value" />
</el-select>
</template>
</el-table-column>
<el-table-column prop="reducePrice" label="金额(元)" width="160">
@ -83,9 +87,10 @@
<script setup lang="ts">
import { ref } from 'vue';
import { budgetTravelCostVO } from '@/api/oa/erp/budgetInfo/market/budgetTravelCost/types';
import { budgetOtherCostVO } from '@/api/oa/erp/budgetInfo/market/budgetOtherCost/types';
import { budgetMaterialCostVO } from '@/api/oa/erp/budgetInfo/market/budgetMaterialCost/types';
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
const { budget_other_item } = toRefs<any>(proxy?.useDict('budget_other_item'));
const loaded = ref(false);
@ -100,7 +105,7 @@ const selectedRows = ref([]);
const showAddDialog = ref(false);
const addRowCount = ref(1);
// ,
//
const formatNumber = (value: number) => {
if (!value) return '0.00';
return parseFloat(value).toFixed(2);

@ -47,19 +47,19 @@
<el-input-number v-model="scope.row.peopleNumber" :min="0" :precision="0" size="small" @change="calculateBudgetSubtotal(scope.row)" style="width: 106px" />
</template>
</el-table-column>
<el-table-column prop="days" label="天数" width="130">
<el-table-column prop="days" label="天数" width="120">
<template #default="scope">
<el-input-number v-model="scope.row.days" :min="0" :precision="0" size="small" @change="calculateBudgetSubtotal(scope.row)" style="width: 116px" />
<el-input-number v-model="scope.row.days" :min="0" :precision="0" size="small" @change="calculateBudgetSubtotal(scope.row)" style="width: 106px" />
</template>
</el-table-column>
<el-table-column prop="stayStandard" label="住宿标准(元)" width="140">
<el-table-column prop="stayStandard" label="住宿标准(元)" width="130">
<template #default="scope">
<el-input-number v-model="scope.row.stayStandard" :min="0" :precision="2" size="small" :step="10" @change="calculateBudgetSubtotal(scope.row)" style="width: 126px" />
<el-input-number v-model="scope.row.stayStandard" :min="0" :precision="2" size="small" :step="10" @change="calculateBudgetSubtotal(scope.row)" style="width: 116px"/>
</template>
</el-table-column>
<el-table-column prop="travelExpenses" label="往返路费(元)" width="140">
<el-table-column prop="travelExpenses" label="往返路费(元)" width="130">
<template #default="scope">
<el-input-number v-model="scope.row.travelExpenses" :min="0" :precision="2" size="small" :step="10" @change="calculateBudgetSubtotal(scope.row)" style="width: 126px" />
<el-input-number v-model="scope.row.travelExpenses" :min="0" :precision="2" size="small" :step="10" @change="calculateBudgetSubtotal(scope.row)" style="width: 116px" />
</template>
</el-table-column>
<el-table-column prop="stayCosts" label="住宿费(元)" width="100">
@ -72,6 +72,16 @@
{{ formatNumber(scope.row.subsidyCosts) }}
</template>
</el-table-column>
<el-table-column prop="highTempSubsidy" label="高温补贴(元)" width="120">
<template #default="scope">
<el-input-number v-model="scope.row.highTempSubsidy" :min="0" :precision="0" size="small" @change="calculateBudgetSubtotal(scope.row)" style="width: 106px" />
</template>
</el-table-column>
<el-table-column prop="hardshipSubsidy" label="艰苦补贴(元)" width="120">
<template #default="scope">
<el-input-number v-model="scope.row.hardshipSubsidy" :min="0" :precision="0" size="small" @change="calculateBudgetSubtotal(scope.row)" style="width: 106px" />
</template>
</el-table-column>
<el-table-column prop="subtotalCosts" label="小计(元)" width="100">
<template #default="scope">
{{ formatNumber(scope.row.subtotalCosts) }}
@ -127,6 +137,17 @@
{{ formatNumber(scope.row.reduceSubsidyCosts) }}
</template>
</el-table-column>
<el-table-column prop="reduceHighTempSubsidy" label="高温补贴(元)" width="120">
<template #default="scope">
<el-input-number v-model="scope.row.reduceHighTempSubsidy" :min="0" :precision="0" size="small" @change="calculateReducedSubtotal(scope.row)" style="width: 106px" />
</template>
</el-table-column>
<el-table-column prop="reduceHardshipSubsidy" label="艰苦补贴(元)" width="120">
<template #default="scope">
<el-input-number v-model="scope.row.reduceHardshipSubsidy" :min="0" :precision="0" size="small" @change="calculateReducedSubtotal(scope.row)" style="width: 106px" />
</template>
</el-table-column>
<el-table-column prop="reduceSubtotalCosts" label="小计(元)" width="100">
<template #default="scope">
{{ formatNumber(scope.row.reduceSubtotalCosts) }}
@ -178,7 +199,7 @@ const selectedRows = ref([]);
const showAddDialog = ref(false);
const addRowCount = ref(1);
// ,
//
const formatNumber = (value: number) => {
if (!value) return '0.00';
return parseFloat(value).toFixed(2);
@ -201,11 +222,11 @@ const calculateBudgetSubtotal = (row: any) => {
// 宿 = × × 宿
row.stayCosts = peopleNumber * days * stayStandard;
// = 50 × ×
row.subsidyCosts = 50 * peopleNumber * days;
// = 90 × ×
row.subsidyCosts = 90 * peopleNumber * days;
// = ( + 宿 + )
row.subtotalCosts = travelExpenses + row.stayCosts + row.subsidyCosts;
row.subtotalCosts = travelExpenses + row.stayCosts + row.subsidyCosts + row.highTempSubsidy + row.hardshipSubsidy;
};
//
@ -219,11 +240,11 @@ const calculateReducedSubtotal = (row: any) => {
// 宿 = × × 宿
row.reduceStayCosts = peopleNumber * days * stayStandard;
// = 50 × ×
row.reduceSubsidyCosts = 50 * peopleNumber * days;
// = 90 × ×
row.reduceSubsidyCosts = 90 * peopleNumber * days;
// = ( + 宿 + )
row.reduceSubtotalCosts = travelExpenses + row.reduceStayCosts + row.reduceSubsidyCosts;
row.reduceSubtotalCosts = travelExpenses + row.reduceStayCosts + row.reduceSubsidyCosts + row.reduceHighTempSubsidy + row.reduceHardshipSubsidy;
};
//
@ -246,10 +267,12 @@ const handleAddRows = () => {
frequency: 0,
peopleNumber: 0,
days: 0,
stayStandard: 0,
stayStandard: 180,
travelExpenses: 0,
stayCosts: 0,
subsidyCosts: 0,
highTempSubsidy: 0,
hardshipSubsidy: 0,
subtotalCosts: 0,
reduceSortOrder: currentSortOrder + i + 1,
reduceTripLocation: '',
@ -257,10 +280,12 @@ const handleAddRows = () => {
reduceFrequency: 0,
reducePeopleNumber: 0,
reduceDayNumber: 0,
reduceStayStandard: 0,
reduceStayStandard: 180,
reduceTravelExpenses: 0,
reduceStayCosts: 0,
reduceSubsidyCosts: 0,
reduceHighTempSubsidy: 0 ,
reduceHardshipSubsidy: 0,
reduceSubtotalCosts: 0,
reduceProposal: ''
});
@ -316,10 +341,14 @@ const getSummaries = (param: any) => {
column.property === 'travelExpenses' ||
column.property === 'stayCosts' ||
column.property === 'subsidyCosts' ||
column.property === 'highTempSubsidy' ||
column.property === 'hardshipSubsidy' ||
column.property === 'subtotalCosts' ||
column.property === 'reduceTravelExpenses' ||
column.property === 'reduceStayCosts' ||
column.property === 'reduceSubsidyCosts' ||
column.property === 'reduceHighTempSubsidy' ||
column.property === 'reduceHardshipSubsidy' ||
column.property === 'reduceSubtotalCosts'
) {
const values = data.map((item: any) => Number(item[column.property]));

Loading…
Cancel
Save