Forráskód Böngészése

fix: 报价信息

lxf 3 hete
szülő
commit
65d185aefd

+ 5 - 0
src/api/modules/z_farm_work_pesticide_fertilizer.js

@@ -22,4 +22,9 @@ module.exports = {
         url: url + "/save_v1",
         type: "get",
     },
+    // 药费类型列表
+    typeList: {
+        url: config.base_dev_url + "z_farm_work_pesticide_fertilizer_category/tree",
+        type: "get",
+    },
 }

+ 6 - 0
src/components/chatWindow.vue

@@ -345,6 +345,12 @@ watch(
                         message.linkUrl = `/completed_work?json=${JSON.stringify(jsonParams)}`;
                     }
 
+                    if(params.type === 'reviewWork') {
+                        message.cardType = 'reviewWork';
+                        message.title = '向您分享了农事执行成果'
+                        message.linkUrl = `/review_work?json=${JSON.stringify({id: params.id})}`;
+                    }
+
                     if(params.type === 'remindExecute' || params.type === 'remindUser') {
                         const jsonParams = {
                             id:params.id,

+ 2 - 2
src/components/popup/priceSheetPopup.vue

@@ -154,7 +154,6 @@ const processedPrescriptionList = computed(() => {
 
     // 创建价格映射表,方便快速查找
     const priceMap = new Map();
-    console.log('priceData.value',priceData.value )
     if (priceData.value?.itemsList && Array.isArray(priceData.value.itemsList)) {
         priceData.value.itemsList.forEach(item => {
             priceMap.set(String(item.pesticideFertilizerId), { price: item.price, brand: item.brand, totalPrice: item.totalPrice });
@@ -170,7 +169,8 @@ const processedPrescriptionList = computed(() => {
                 const price = mapped.price || 0;
                 const brand = mapped.brand || item.brand || '';
                 const total = mapped.totalPrice || item.total || '';
-                const muUsage = item.muUsage || 0;
+                const muUsage = quotationData.value.usageMode === "叶面施" ? (item.muUsage2 || item.muUsage) : item.muUsage
+                console.log('muUsage', muUsage)
                 const unit = item.unit || '';
 
                 result.push({

+ 2 - 0
src/router/globalRoutes.js

@@ -214,12 +214,14 @@ export default [
     {
         path: "/offer_price",
         name: "OfferPrice",
+        meta: { keepAlive: true },
         component: () => import("@/views/old_mini/offer_price/index.vue"),
     },
     // 报价维护
     {
         path: "/edit_price",
         name: "EditPrice",
+        meta: { keepAlive: true },
         component: () => import("@/views/old_mini/offer_price/component/editPrice.vue"),
     },
     // 服务维护

+ 2 - 2
src/views/old_mini/modify_work/completedWork.vue

@@ -211,8 +211,8 @@
                             >
                                 <div class="new-table">
                                     <div class="line-l">
-                                        <div class="line-1 title-1">{{ subP.typeName }}</div>
-                                        <div class="line-2">{{ subP.defaultName }}</div>
+                                        <div class="line-1 title-1">{{ prescriptionItem.name }}</div>
+                                        <div class="line-2">{{ subP.defaultName || subP.pesticideFertilizerName }}</div>
                                     </div>
                                     <div
                                         class="line-r"

+ 1 - 1
src/views/old_mini/modify_work/index.vue

@@ -519,7 +519,7 @@ function handlePopupBtn() {
     if (taskPopupType.value === 'warning') {
         // 确认忽略
     } else {
-        router.push({
+        router.replace({
             path: "/completed_work",
             query: {
                 json: JSON.stringify({ id: route.query.id }),

+ 134 - 28
src/views/old_mini/offer_price/component/editPrice.vue

@@ -3,29 +3,25 @@
         <custom-header name="飞鸟管家"></custom-header>
         <div class="edit-form">
             <el-form ref="formRef" :model="form" :rules="rules" label-width="80px">
-                <el-form-item label="药肥名称" prop="name" required>
-                    <el-select v-model="form.name" placeholder="请选择" filterable clearable style="width: 100%">
-                        <el-option v-for="opt in nameOptions" :key="opt" :label="opt" :value="opt" />
+                <el-form-item label="药肥名称" prop="id" required>
+                    <el-select v-model="form.id" placeholder="请选择" filterable clearable style="width: 100%">
+                        <el-option v-for="opt in pesticideOptions" :key="opt.id" :label="opt.name" :value="opt.id" />
                     </el-select>
                 </el-form-item>
 
                 <el-form-item label="药肥品牌" prop="brand" required>
-                    <el-select v-model="form.brand" placeholder="请选择" filterable clearable style="width: 100%">
-                        <el-option v-for="opt in brandOptions" :key="opt" :label="opt" :value="opt" />
-                    </el-select>
+                    <el-input class="has-border" v-model="form.brand" placeholder="请输入" />
                 </el-form-item>
 
-                <el-form-item label="药肥类型" required>
+                <el-form-item label="药肥类型" required prop="typeId">
                     <div class="row-3-selects">
-                        <el-select v-model="form.type1" placeholder="请选择" filterable clearable>
-                            <el-option v-for="opt in type1Options" :key="opt" :label="opt" :value="opt" />
-                        </el-select>
-                        <el-select v-model="form.type2" placeholder="请选择" filterable clearable>
-                            <el-option v-for="opt in type2Options" :key="opt" :label="opt" :value="opt" />
-                        </el-select>
-                        <el-select v-model="form.type3" placeholder="请选择" filterable clearable>
-                            <el-option v-for="opt in type3Options" :key="opt" :label="opt" :value="opt" />
-                        </el-select>
+                        <el-cascader
+                            v-model="form.typeId"
+                            style="width: 100%"
+                            :options="typeOptions"
+                            :props="cascaderProps"
+                            :show-all-levels="false"
+                            />
                     </div>
                 </el-form-item>
 
@@ -68,6 +64,7 @@
                         <el-input v-model.number="form.waterMin" placeholder="请输入兑水量">
                             <template #append>kg</template>
                         </el-input>
+                        <span>-</span>
                         <el-input v-model.number="form.waterMax" placeholder="请输入兑水量">
                             <template #append>kg</template>
                         </el-input>
@@ -97,7 +94,7 @@
 import customHeader from "@/components/customHeader.vue";
 import { ElMessage, ElMessageBox } from 'element-plus'
 import { useRouter, useRoute } from "vue-router";
-import { ref, reactive } from 'vue'
+import { ref, reactive, onMounted, onActivated } from 'vue'
 
 const router = useRouter();
 const route = useRoute();
@@ -128,37 +125,136 @@ const openDelete = () => {
 // 表单模型与选项
 const formRef = ref()
 const form = reactive({
-    name: '',
+    id: '',
+    typeId: null,
     brand: '',
     type1: '',
     type2: '',
     type3: '',
     unit: '克',
-    method: '叶面施',
+    method: '1',
     cost: null,
     price: null,
     stock: null,
     waterMin: null,
     waterMax: null,
-    crops: ['荔枝', '香蕉']
+    crops: []
 })
 
 const rules = {
-    name: [{ required: true, message: '请选择药肥名称', trigger: 'change' }],
+    id: [{ required: true, message: '请选择药肥名称', trigger: 'change' }],
     brand: [{ required: true, message: '请选择药肥品牌', trigger: 'change' }],
+    typeId: [{ required: true, message: '请选择药肥类型', trigger: 'change' }],
     unit: [{ required: true, message: '请选择计量单位', trigger: 'change' }],
     method: [{ required: true, message: '请选择施用方式', trigger: 'change' }],
     cost: [{ required: true, message: '请输入成本', trigger: 'blur' }],
     price: [{ required: true, message: '请输入报价', trigger: 'blur' }],
     stock: [{ required: true, message: '请输入库存', trigger: 'blur' }]
 }
-
-const nameOptions = ['乙烯利乙烯利']
-const brandOptions = ['国光']
-const type1Options = ['农药类', '调节', '肥料']
-const type2Options = ['一级', '二级', '三级']
-const type3Options = ['一级', '二级', '三级']
 const cropOptions = ['荔枝', '香蕉', '龙眼', '芒果']
+
+// 单位转换映射
+const unitMap = {
+    'kg': '千克',
+    'g': '克',
+    'ml': '毫升',
+    'l': '升',
+    '千克': '千克',
+    '克': '克',
+    '毫升': '毫升',
+    '升': '升'
+}
+
+// 施用方式转换映射
+const methodMap = {
+    '叶面施': '1',
+    '根部施': '2'
+}
+
+const cascaderProps = {
+  checkStrictly: true,
+  emitPath: false,
+  value: 'id',
+  label: 'name',
+  children: 'children'
+};
+
+onMounted(() => {
+    fetchPesticideOptions()
+    fetchTypeOptions()
+})
+
+
+// 用途类型选项
+const typeOptions = ref([]);
+function fetchTypeOptions() {
+  if (typeOptions.value.length === 0) {
+    VE_API.z_farm_work_pesticide_fertilizer.typeList().then(res => {
+      if (res.code === 0) {
+        typeOptions.value = res.data || []
+      }
+    })
+  }
+}
+/**
+ * 获取药肥选项
+ */
+ const pesticideOptions = ref([]);
+ function fetchPesticideOptions() {
+  // 每次都重新获取药肥选项,确保数据是最新的
+  VE_API.z_farm_work_pesticide_fertilizer.selectOption().then(res => {
+    if (res.code === 0) {
+      pesticideOptions.value = res.data || [];
+    }
+  }).catch(error => {
+    console.error('获取药肥选项失败:', error);
+  });
+}
+
+// 获取详情数据
+const getDetail = () => {
+    const id = route.query.id;
+    if (!id || isAdd.value) {
+        return;
+    }
+    
+    VE_API.z_farm_work_pesticide_fertilizer.fertilizerDetail({ id }).then(({ data }) => {
+        if (data) {
+            // 赋值表单数据
+            form.id = data.id || '';
+            form.brand = data.brand || '';
+            form.typeId = data.typeId || null;
+            
+            // 转换单位
+            form.unit = unitMap[data.unit] || data.unit || '克';
+            
+            // 转换施用方式
+            if (data.usageModeList && data.usageModeList.length > 0) {
+                const firstMode = data.usageModeList[0];
+                form.method = methodMap[firstMode] || firstMode;
+            }
+            
+            form.cost = data.cost || null;
+            form.price = data.price || null;
+            form.stock = data.stock || null;
+            form.waterMin = data.unitWaterAmount || null;
+            form.waterMax = data.unitWaterAmountMax || null;
+            
+            // 适用品种
+            if (data.speciesList && Array.isArray(data.speciesList) && data.speciesList.length > 0) {
+                form.crops = data.speciesList;
+            } else {
+                form.crops = [];
+            }
+        }
+    }).catch(() => {
+        ElMessage.error('获取详情失败');
+    });
+}
+
+onActivated(() => {
+    getDetail();
+});
 </script>
 
 <style lang="scss" scoped>
@@ -182,8 +278,9 @@ const cropOptions = ['荔枝', '香蕉', '龙眼', '芒果']
             > .el-select { flex: 1; }
         }
         .water-row {
+            color: rgba(0, 0, 0, 0.1);
             display: flex;
-            gap: 12px;
+            gap: 2px;
             > .el-input { flex: 1; }
         }
 
@@ -217,6 +314,15 @@ const cropOptions = ['荔枝', '香蕉', '龙眼', '芒果']
             .el-input__wrapper {
                 box-shadow: none;
             }
+            .el-input__inner {
+                color: #2199F8;
+                --el-input-placeholder-color: rgba(33, 153, 248, 0.43);
+            }
+            .has-border, .el-cascader {
+                .el-input__wrapper {
+                    box-shadow: 0 0 0 1px rgba(33, 153, 248, 0.3) inset;
+                }
+            }
             .el-input-group__append {
                 padding: 0 10px;
                 background: none;

+ 16 - 11
src/views/old_mini/offer_price/component/fertilizerPrice.vue

@@ -30,7 +30,7 @@
                     <div class="info">
                         <div class="row">
                             <span class="label">药物品牌</span>
-                            <span class="value">{{ item.brand }}</span>
+                            <span class="value">{{ item.brand || "--" }}</span>
                         </div>
                         <div class="row">
                             <span class="label">药费类型</span>
@@ -38,7 +38,7 @@
                         </div>
                         <div class="row">
                             <span class="label">施用方式</span>
-                            <span class="value">{{ item.useMode }}</span>
+                            <span class="value">{{ getArrText(item.usageModeList) }}</span>
                         </div>
                         <transition name="collapse">
                             <div class="extra-info" v-show="isExpanded(index)">
@@ -48,13 +48,14 @@
                                 </div>
                                 <div class="row">
                                     <span class="label">单位兑水量</span>
-                                    <span class="value">{{ item.unitUsage }}</span>
+                                    <span class="value">{{ item.unitWaterAmount }}{{ item.unit }}<span>-</span>{{ item.unitWaterAmountMax }}{{ item.unit }}</span>
                                 </div>
                                 <div class="row">
                                     <span class="label">适用品类</span>
-                                    <span class="value tag-group">
-                                        <span class="tag-item">{{ item.unitWaterAmount }}</span>
+                                    <span class="value tag-group" v-if="item.speciesList && item.speciesList.length > 0">
+                                        <span class="tag-item">{{ getArrText(item.speciesList) }}</span>
                                     </span>
+                                    <span class="value" v-else>--</span>
                                 </div>
                             </div>
                         </transition>
@@ -65,15 +66,15 @@
                     </div>
                     <div class="stats">
                         <div class="col">
-                            <div class="num">{{ item.price }}<span class="unit"> 元/{{ item.unit }}</span></div>
+                            <div class="num">{{ item.price }}<span class="unit">元/{{ item.unit }}</span></div>
                             <div class="desc">成本</div>
                         </div>
                         <div class="col">
-                            <div class="num">{{ item.cost }}<span class="unit"> 元/{{ item.unit }}</span></div>
+                            <div class="num">{{ item.cost }}<span class="unit">元/{{ item.unit }}</span></div>
                             <div class="desc">报价</div>
                         </div>
                         <div class="col">
-                            <div class="num">{{ item.stock }}<span class="unit"> {{ item.unit }}</span></div>
+                            <div class="num">{{ item.stock }}<span class="unit">{{ item.unit }}</span></div>
                             <div class="desc">库存</div>
                         </div>
                     </div>
@@ -88,10 +89,9 @@
 
 <script setup>
 import { ref, onMounted } from "vue";
-import { Search } from 'vant';
+import { Search, List } from 'vant';
 import { useRouter } from "vue-router";
 import { ElMessageBox } from 'element-plus'
-import { List } from 'vant';
 
 const router = useRouter();
 const searchVal = ref("");
@@ -134,6 +134,10 @@ const handleEdit = (item) => {
     });
 };
 
+const getArrText = (arr) => {
+    return arr && arr.length > 0 ? arr.map(item => item).join('、') : '--';
+}
+
 const openDelete = () => {
   ElMessageBox.confirm(
     '确认要删除该报价吗?',
@@ -247,6 +251,7 @@ const onLoad = () => {
                 font-size: 14px;
                 .row {
                     display: flex;
+                    align-items: center;
                     padding: 4px 0;
                     .label {
                         width: 80px;
@@ -303,7 +308,7 @@ const onLoad = () => {
                         color: #2199F8;
                         font-weight: 600;
                         font-size: 16px;
-                        .unit { font-size: 12px; font-weight: 400; color: rgba(0, 0, 0, 0.5); }
+                        .unit { padding-left: 2px; font-size: 12px; font-weight: 400; color: rgba(0, 0, 0, 0.5); }
                     }
                     .desc { color: #000; margin-top: 4px; }
                 }

+ 75 - 55
src/views/old_mini/price_detail/index.vue

@@ -22,6 +22,51 @@
                     <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"
+                                >
+                                    <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" 
+                                     v-model="servicePricePerMu" 
+                                     :min="0"
+                                 />
+                                 <!-- <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">
@@ -63,7 +108,7 @@
                             </div>
                             <div class="medicine-item">
                                 <div class="item-name">单亩用量</div>
-                                <div class="item-val">{{ pesticide.muUsage }}{{ pesticide.unit }}</div>
+                                <div class="item-val">{{ getMuUsage(pesticide) }}{{ pesticide.unit }}</div>
                             </div>
                             <div class="medicine-item">
                                 <div class="item-name">亩数</div>
@@ -77,51 +122,6 @@
                     </div>
                 </template>
             </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">
-                                <el-select
-                                    class="select-item"
-                                    v-model="executionMethod"
-                                    placeholder="执行方式"
-                                    style="width: 132px"
-                                >
-                                    <el-option
-                                        v-for="(item, index) in modeList"
-                                        :key="index"
-                                        :label="item.name"
-                                        :value="item.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" 
-                                     v-model="servicePricePerMu" 
-                                     :min="0"
-                                     :precision="2"
-                                 />
-                                 <!-- <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>
         <div class="bottom-btn">
             <div class="bottom-l">
@@ -169,10 +169,10 @@ onActivated(() => {
                         item => item.pesticideFertilizerId === pesticide.pesticideFertilizerId
                     );
                     if (priceItem) {
-                        pesticide.price = priceItem.price || 0;
+                        pesticide.price = Number(priceItem.price) || null;
                         pesticide.brand = priceItem.brand || '';
                     } else {
-                        pesticide.price = 0;
+                        pesticide.price = null;
                         pesticide.brand = '';
                     }
                 });
@@ -182,7 +182,7 @@ onActivated(() => {
     
     // 初始化服务费用
     if (priceData.value.farmWorkServiceCost && detailData.value.area) {
-        servicePricePerMu.value = Number((priceData.value.farmWorkServiceCost / detailData.value.area).toFixed(2));
+        servicePricePerMu.value = priceData.value.farmWorkServiceCost || null;
     }
 });
 
@@ -191,7 +191,7 @@ const clearData = () => {
     executeDate.value = null;
     detailData.value = {};
     priceData.value = {};
-    servicePricePerMu.value = 0;
+    servicePricePerMu.value = null;
     executionMethod.value = null;
 };
 
@@ -204,10 +204,29 @@ 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) => {
-    if (!pesticide.price || !pesticide.muUsage || !detailData.value.area) return '0.00';
-    const total = (pesticide.price * pesticide.muUsage * detailData.value.area).toFixed(2);
+    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;
 }
 
@@ -225,8 +244,9 @@ const getTotalCost = () => {
         detailData.value.prescriptionList.forEach(prescription => {
             if (prescription.pesticideFertilizerList) {
                 prescription.pesticideFertilizerList.forEach(pesticide => {
-                    if (pesticide.price && pesticide.muUsage && detailData.value.area) {
-                        pesticideTotal += pesticide.price * pesticide.muUsage * detailData.value.area;
+                    const muUsage = getMuUsage(pesticide);
+                    if (pesticide.price && muUsage && detailData.value.area) {
+                        pesticideTotal += pesticide.price * muUsage * detailData.value.area;
                     }
                 });
             }
@@ -348,7 +368,7 @@ const confirmPrice = () => {
             padding-left: 5px;
             font-size: 16px;
             color: #000000;
-            font-weight: bold;
+            font-weight: 500;
             padding-bottom: 10px;
         }
         .medicine-item {

+ 1 - 1
src/views/old_mini/task_condition/components/reviewPopup.vue

@@ -119,7 +119,7 @@ const handleShare = () => {
         farmId: quotationData.value.farmId,
         farmWorkName: quotationData.value.farmWorkName,
         id: quotationData.value.id,
-        type: "quotation",
+        type: "reviewWork",
     };
     if (userId) {
         router.push(