| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502 |
- <template>
- <div class="price-detail">
- <custom-header name="报价详情"></custom-header>
- <div class="price-content">
- <div class="box-wrap">
- <div class="price-info">
- <div class="info-title">执行时间</div>
- <div class="info-val">
- <el-date-picker
- class="item-input"
- style="width: 132px"
- value-format="YYYY-MM-DD"
- v-model="executeDate"
- type="date"
- :clearable="false"
- placeholder="选择日期"
- :editable="false"
- />
- </div>
- </div>
- <div class="price-info">
- <div class="info-title">施肥方式</div>
- <div class="info-val">{{ detailData?.usageMode }}</div>
- </div>
- </div>
- <div class="service-wrap">
- <div class="medicine-box">
- <div class="item-title">服务费用</div>
- <div class="box-wrap">
- <div class="medicine-item">
- <div class="item-name">执行方式</div>
- <div class="item-val" v-if="detailData?.usageMode === '叶面施'">
- <el-select
- class="select-item"
- v-model="executionMethod"
- placeholder="执行方式"
- style="width: 132px"
- @change="handleExecutionMethodChange"
- >
- <el-option
- v-for="(item, index) in modeList"
- :key="index"
- :label="item.name"
- :value="item.value"
- />
- </el-select>
- </div>
- <div class="item-val" v-else>人工</div>
- </div>
- <div class="medicine-item mt-8">
- <div class="item-name">亩单价</div>
- <div class="item-val">
- <el-input-number
- style="width: 132px"
- placeholder="服务单价"
- v-model="servicePricePerMu"
- :min="0.0001"
- />
- <!-- <span class="price-unit">元/亩</span> -->
- </div>
- </div>
- <div class="medicine-item">
- <div class="item-name">亩数</div>
- <div class="item-val">{{ formatArea(detailData?.area) }}亩</div>
- </div>
- <div class="medicine-item">
- <div class="item-total">总计:</div>
- <div class="item-price">{{ getServiceTotal() }}<span class="item-unit">元</span></div>
- </div>
- </div>
- </div>
- </div>
- <div class="medicine-wrap">
- <template v-for="(prescription, pIndex) in detailData?.prescriptionList" :key="pIndex">
- <div class="medicine-box" v-for="(pesticide, mIndex) in prescription.pesticideFertilizerList" :key="mIndex">
- <div class="item-title">肥药{{ mIndex + 1 }}</div>
- <div class="box-wrap">
- <div class="medicine-item">
- <div class="item-name">肥药名称</div>
- <div class="item-val">{{ pesticide.pesticideFertilizerName }}</div>
- </div>
- <div class="medicine-item">
- <div class="item-name">肥药品牌</div>
- <div class="item-val">
- <el-input v-model="pesticide.brand" placeholder="肥药品牌" style="width: 132px" />
- <!-- <el-select
- class="select-item"
- v-model="pesticide.brand"
- placeholder="肥药品牌"
- style="width: 132px"
- >
- <el-option
- v-for="(brand, bIndex) in brandList"
- :key="bIndex"
- :label="brand.name"
- :value="brand.value"
- />
- </el-select> -->
- </div>
- </div>
- <div class="medicine-item mt-8">
- <div class="item-name">肥药单价</div>
- <div class="item-val">
- <el-input-number
- style="width: 132px"
- placeholder="单价"
- v-model="pesticide.price"
- :min="0.0000000001"
- />
- <!-- <span class="price-unit">元/{{ pesticide.unit }}</span> -->
- </div>
- </div>
- <div class="medicine-item">
- <div class="item-name">单亩用量</div>
- <div class="item-val">{{ getMuUsage(pesticide) }}{{ pesticide.unit }}</div>
- </div>
- <div class="medicine-item">
- <div class="item-name">亩数</div>
- <div class="item-val">{{ formatArea(detailData?.area) }}亩</div>
- </div>
- <div class="medicine-item">
- <div class="item-total">总计:</div>
- <div class="item-price">{{ getPesticideTotal(pesticide) }}<span class="item-unit">元</span></div>
- </div>
- </div>
- </div>
- </template>
- </div>
- </div>
- <div class="bottom-btn">
- <div class="bottom-l">
- 合计:<span class="main-val">{{ getTotalCost() }}</span>元
- </div>
- <div class="bottom-r" @click="confirmPrice">确认报价</div>
- </div>
- </div>
- </template>
- <script setup>
- import customHeader from "@/components/customHeader.vue";
- import { ElMessage } from "element-plus";
- import { ref, onMounted, onActivated, onBeforeUnmount, onDeactivated } from "vue";
- import { useRoute, useRouter } from "vue-router";
- import { formatArea } from "@/common/commonFun";
- const router = useRouter();
- const executeDate = ref(null);
- let query = useRoute().query;
- const detailData = ref(JSON.parse(query.data));
- const priceData = ref({});
- const servicePricePerMu = ref(null);
- const executionMethod = ref(null);
- const modeList = ref([
- {name: "无人机", value: 1},
- {name: "人工", value: 2},
- ])
- // 初始化数据
- onActivated(() => {
- query = useRoute().query;
- detailData.value = JSON.parse(query.data);
- executeDate.value = detailData.value.executeDate;
- if (detailData.value.usageMode === "根部施") {
- executionMethod.value = 2;
- }
- priceData.value = JSON.parse(query?.priceData || '{}');
-
- // 从 priceData 中匹配价格和品牌到对应的药肥
- if (priceData.value?.itemsList && detailData.value?.prescriptionList) {
- executionMethod.value = priceData.value.executionMethod;
- if (detailData.value.usageMode === "根部施") {
- executionMethod.value = 2;
- }
- detailData.value.prescriptionList.forEach(prescription => {
- if (prescription.pesticideFertilizerList) {
- prescription.pesticideFertilizerList.forEach(pesticide => {
- const priceItem = priceData.value.itemsList.find(
- item => item.pesticideFertilizerId === pesticide.pesticideFertilizerId
- );
- if (priceItem) {
- pesticide.price = Number(priceItem.price) || null;
- pesticide.brand = priceItem.brand || '';
- } else {
- pesticide.price = null;
- pesticide.brand = '';
- }
- });
- }
- });
- }
-
- // 初始化服务费用
- if (priceData.value?.farmWorkServiceCost && detailData.value?.area) {
- servicePricePerMu.value = priceData.value.farmWorkServiceCost || null;
- }
- });
- // 清空数据
- const clearData = () => {
- executeDate.value = null;
- detailData.value = {};
- priceData.value = {};
- servicePricePerMu.value = null;
- executionMethod.value = null;
- };
- // 离开页面时清空数据
- onBeforeUnmount(() => {
- clearData();
- });
- onDeactivated(() => {
- clearData();
- });
- // 根据执行方式获取单亩用量:1=无人机用muUsage2,2=人工用muUsage
- const getMuUsage = (pesticide) => {
- if (!pesticide) return 0;
- // 如果是叶面施且有执行方式选择,根据执行方式判断
- if (detailData.value?.usageMode === '叶面施' && executionMethod.value !== null && executionMethod.value !== undefined) {
- // 1 = 无人机,使用 muUsage2
- if (executionMethod.value == 1) {
- return pesticide.muUsage2 || pesticide.muUsage || 0;
- }
- // 2 = 人工,使用 muUsage
- if (executionMethod.value == 2) {
- return pesticide.muUsage || 0;
- }
- }
- // 默认使用 muUsage(非叶面施的情况)
- return pesticide.muUsage || 0;
- }
- // 计算单个药肥的总计:单价 * 单亩用量 * 亩数
- const getPesticideTotal = (pesticide) => {
- const muUsage = getMuUsage(pesticide);
- if (!pesticide.price || !muUsage || !detailData.value.area) return '0.00';
- const total = (pesticide.price * muUsage * detailData.value.area).toFixed(2);
- return total;
- }
- // 计算服务费用总计:亩单价 * 亩数
- const getServiceTotal = () => {
- if (!servicePricePerMu.value || !detailData.value.area) return '0.00';
- const total = (servicePricePerMu.value * detailData.value.area).toFixed(2);
- return total;
- }
- // 计算总合计:所有药肥总计 + 服务费用总计
- const getTotalCost = () => {
- let pesticideTotal = 0;
- if (detailData.value.prescriptionList) {
- detailData.value.prescriptionList.forEach(prescription => {
- if (prescription.pesticideFertilizerList) {
- prescription.pesticideFertilizerList.forEach(pesticide => {
- const muUsage = getMuUsage(pesticide);
- if (pesticide.price && muUsage && detailData.value.area) {
- pesticideTotal += pesticide.price * muUsage * detailData.value.area;
- }
- });
- }
- });
- }
-
- const serviceTotal = servicePricePerMu.value && detailData.value.area
- ? servicePricePerMu.value * detailData.value.area
- : 0;
-
- return (pesticideTotal + serviceTotal).toFixed(2);
- }
- const confirmPrice = () => {
- if (!executionMethod.value) {
- ElMessage.error("请选择执行方式");
- return;
- }
-
- // 检查服务费用是否有价格
- if (!servicePricePerMu.value || servicePricePerMu.value <= 0) {
- ElMessage.error("请填写服务费用");
- return;
- }
-
- // 检查是否所有药肥都有价格和品牌
- if (detailData.value?.prescriptionList) {
- const emptyItems = [];
- detailData.value.prescriptionList.forEach(prescription => {
- (prescription.pesticideFertilizerList || []).forEach(pesticide => {
- const pesticideName = pesticide.pesticideFertilizerName || '药肥';
- const hasPrice = pesticide.price && pesticide.price > 0;
- const hasBrand = pesticide.brand && pesticide.brand.trim() !== '';
-
- if (!hasPrice || !hasBrand) {
- let errorMsg = '';
- if (!hasPrice && !hasBrand) {
- errorMsg = `${pesticideName}的品牌和单价`;
- } else if (!hasPrice) {
- errorMsg = `${pesticideName}的单价`;
- } else if (!hasBrand) {
- errorMsg = `${pesticideName}的品牌`;
- }
- emptyItems.push(errorMsg);
- }
- });
- });
-
- if (emptyItems.length > 0) {
- ElMessage.error(`请填写${emptyItems[0]}`);
- return;
- }
- }
-
- const pesticideFertilizerQuoteList = [];
- if (detailData.value?.prescriptionList) {
- detailData.value.prescriptionList.forEach(prescription => {
- (prescription.pesticideFertilizerList || []).forEach(pesticide => {
- pesticideFertilizerQuoteList.push({
- pesticideFertilizerId: pesticide.pesticideFertilizerId,
- price: Number(pesticide.price || 0),
- brand: pesticide.brand || ''
- });
- })
- })
- }
- const payload = {
- farmWorkRecordId: detailData.value?.id,
- pesticideFertilizerQuoteList,
- executeDate: executeDate.value,
- servicePrice: servicePricePerMu.value,
- executionMethod: executionMethod.value,
- };
- VE_API.z_farm_work_record.acceptFarmWorkRecord(payload).then(({ data, code, msg }) => {
- if (code === 0) {
- ElMessage.success("确认报价成功");
- // router.push({
- // path: "/task_condition",
- // });
- router.back();
- } else {
- ElMessage.error(msg);
- }
- })
- }
- const handleExecutionMethodChange = (val) => {
- if (val == 1) {
- servicePricePerMu.value = priceData.value.uavServicePrice
- } else {
- servicePricePerMu.value = priceData.value.manualServicePrice
- }
- }
- </script>
- <style lang="scss" scoped>
- .price-detail {
- height: 100vh;
- position: relative;
- font-size: 14px;
- background: #f2f3f5;
- color: #000;
- .price-content {
- padding: 12px;
- box-sizing: border-box;
- height: calc(100% - 40px - 74px);
- overflow: auto;
- ::v-deep {
- .el-input__wrapper, .el-select__wrapper {
- box-shadow: 0 0 0 1px rgba(33, 153, 248, 0.3) inset;
- }
- .el-input__inner {
- color: #2199f8;
- text-align: center;
- }
- .el-select__placeholder {
- color: #2199f8;
- &.is-transparent {
- color: rgba(33, 153, 248, 0.6);
- }
- text-align: center;
- }
- .el-input__prefix {
- color: #2199f8;
- }
- .el-select__caret {
- color: #2199f8;
- }
- .el-input {
- --el-input-placeholder-color: rgba(33, 153, 248, 0.6);
- }
- .el-input-number__decrease, .el-input-number__increase {
- display: none;
- }
- .el-input-number .el-input__wrapper {
- padding-left: 12px;
- padding-right: 12px;
- }
- }
- }
- .box-wrap {
- background: #fff;
- padding: 10px;
- border-radius: 8px;
- }
- .price-info {
- height: 32px;
- display: flex;
- align-items: center;
- justify-content: space-between;
- .info-val {
- color: #474747;
- width: 132px;
- text-align: center;
- }
- }
- .price-info + .price-info {
- padding-top: 6px;
- }
- .medicine-box {
- padding-top: 10px;
- .item-title {
- padding-left: 5px;
- font-size: 16px;
- color: #000000;
- font-weight: 500;
- padding-bottom: 10px;
- }
- .medicine-item {
- display: flex;
- align-items: center;
- justify-content: space-between;
- height: 32px;
- .item-name {
- color: rgba(0, 0, 0, 0.4);
- }
- .item-val {
- min-width: 142px;
- text-align: center;
- color: #474747;
- display: flex;
- align-items: center;
- justify-content: center;
- gap: 4px;
- .price-unit {
- font-size: 12px;
- color: rgba(0, 0, 0, 0.4);
- white-space: nowrap;
- }
- }
- .item-total {
- font-size: 16px;
- color: #000;
- }
- .item-price {
- color: #2199F8;
- font-size: 20px;
- font-weight: bold;
- .item-unit {
- font-size: 14px;
- font-weight: normal;
- padding-left: 2px;
- color: #474747;
- }
- }
- }
- .medicine-item + .medicine-item {
- padding-top: 2px;
- }
- .mt-8 {
- margin-top: 8px;
- }
- }
- .bottom-btn {
- height: 74px;
- display: flex;
- align-items: center;
- justify-content: space-between;
- background: #fff;
- padding: 12px;
- box-sizing: border-box;
- box-shadow: 0 -1px 11px rgba(0, 0, 0, 0.1);
- .bottom-l {
- color: #000000;
- font-size: 16px;
- .main-val {
- color: #2199F8;
- font-size: 24px;
- font-weight: bold;
- padding-right: 4px;
- }
- }
- .bottom-r {
- background: linear-gradient(136deg, #9FD5FF, #2199F8);
- padding: 8px 32px;
- border-radius: 20px;
- color: #fff;
- }
- }
- }
- </style>
|