Ver Fonte

Merge branch 'master' of http://www.sysuimars.cn:3000/feiniao/feiniao-farm-h5

wangsisi há 3 horas atrás
pai
commit
031cf38456

+ 4 - 0
src/api/modules/container_farm_work_arrange.js

@@ -10,4 +10,8 @@ module.exports = {
         url: url + "/saveComposite",
         type: "post",
     },
+    toggleFollow: {
+        url: url + "/toggleFollow",
+        type: "get",
+    },
 }

+ 9 - 0
src/api/modules/farm.js

@@ -62,4 +62,13 @@ module.exports = {
         url: config.base_dev_url + "z_agricultural_store/page/{page}/{limit}",
         type: "get",
     },
+    // 报价
+    getPriceList: {
+        url: config.base_dev_url + "agricultural_store_pesticide_fertilizer/findBySchemeAndPesticides",
+        type: "post",
+    },
+    updateBatchByScheme: {
+        url: config.base_dev_url + "agricultural_store_pesticide_fertilizer/updateBatchByScheme",
+        type: "post",
+    },
 }

+ 0 - 1
src/components/album_compoents/albumCarouselItem.vue

@@ -217,7 +217,6 @@ const clickPhoto = (photo) => {
 };
 
 const handleSaveImage = () => {
-    console.log('save');
     downloadImage(previewCanvas.value, '执行照片');
 };
 

+ 494 - 285
src/components/album_compoents/albumDrawBox.vue

@@ -1,377 +1,586 @@
 <template>
-  <photo-consumer
-      class="carousel-item"
-      :src="watermark || getPhotoSrc(photo)"
-  >
-    <img
-      v-if="Math.abs(current - index) < 3"
-      crossorigin="anonymous"
-      loading="lazy"
-      @load="drawWatermark($event)"
-      :src="watermark || getPhotoSrc(photo)"
-      style="width: 100%; height: 255px; object-fit: cover; display: block; border-radius: 8px;"
-    />
-    <canvas
-      ref="canvasRef"
-      style="position: absolute; left: 0; top: 0; width: 100%; height: 100%; pointer-events: none;border-radius: 8px;"
-    ></canvas>
-    <div class="tag-box right" v-if="isShowNum" :class="{'leftTop': 'leftTop'}">{{ index+1 }}/{{ length }}</div>
-<!--    <div class="center-mark">mark</div>-->
-  </photo-consumer>
-
+    <photo-consumer class="carousel-item" :src="watermark || getPhotoSrc(photo)">
+        <img
+            v-if="Math.abs(current - index) < 3"
+            crossorigin="anonymous"
+            loading="lazy"
+            @load="drawWatermark($event)"
+            :src="watermark || getPhotoSrc(photo)"
+            style="width: 100%; height: 255px; object-fit: cover; display: block; border-radius: 8px"
+        />
+        <canvas
+            ref="canvasRef"
+            @click="handleClick"
+            style="position: absolute; left: 0; top: 0; width: 100%; height: 100%; border-radius: 8px"
+        ></canvas>
+        <div class="tag-box right" v-if="isShowNum" :class="{ leftTop: 'leftTop' }">{{ index + 1 }}/{{ length }}</div>
+        <!--    <div class="center-mark">mark</div>-->
+    </photo-consumer>
+
+    <popup class="cavans-popup" v-model:show="showPopup">
+        <div class="cavans-content">
+            <img class="current-img" :src="watermarkWithQRCode || watermark" alt="" />
+        </div>
+        <!-- 底部操作按钮 -->
+        <div class="bottom-actions" @click.stop="showPopup = false">
+            <div class="action-buttons">
+                <div class="action-btn green-btn" @click.stop="handleWechat">
+                    <div class="icon-circle">
+                        <img src="@/assets/img/home/wechat.png" alt="" />
+                    </div>
+                    <span class="btn-label">微信</span>
+                </div>
+                <div class="action-btn orange-btn" @click.stop="handleSaveImage">
+                    <div class="icon-circle">
+                        <el-icon :size="24"><Download /></el-icon>
+                    </div>
+                    <span class="btn-label">保存图片</span>
+                </div>
+            </div>
+            <div class="cancel-btn" @click="handleCancel">取消</div>
+        </div>
+    </popup>
 </template>
 
 <script setup>
+import { Popup } from "vant";
 import { ref, onMounted, onBeforeUnmount, defineProps } from "vue";
 import { base_img_url2 } from "@/api/config";
-import {imageCache,loadImage} from "./cacheImg.js"
-import {dateFormat} from "@/utils/date_util.js"
-
-import {drawTextInRect, drawBorderImageInRect, drawImageInRect, drawRectInRect, drawHorizontalTextList} from "./utils"
+import { imageCache, loadImage } from "./cacheImg.js";
+import { dateFormat } from "@/utils/date_util.js";
+
+import {
+    drawTextInRect,
+    drawBorderImageInRect,
+    drawImageInRect,
+    drawRectInRect,
+    drawHorizontalTextList,
+} from "./utils";
 // const resize = "?x-oss-process=image/resize,p_30/format,webp/quality,q_40";
 const resize = "";
 
 const canvasRef = ref(null);
-const watermark = ref(null)
-const baseMapBig = ref(false)
+const watermark = ref(null);
+const baseMapBig = ref(false);
 
 const props = defineProps({
-  photo:{
-    required: true
-  },
-  index:{
-    type: Number,
-    required: true
-  },
-  length:{
-    type: Number,
-    required: true
-  },
-  current:{
-    type: Number,
-    required: true
-  },
-  isShowNum:{
-    type: Number,
-    required: true
-  }
-})
+    photo: {
+        required: true,
+    },
+    index: {
+        type: Number,
+        required: true,
+    },
+    length: {
+        type: Number,
+        required: true,
+    },
+    current: {
+        type: Number,
+        required: true,
+    },
+    isShowNum: {
+        type: Number,
+        required: true,
+    },
+});
 let img = null;
 let ctx = null;
+// 保存原始图片引用,用于重新绘制
+let cachedSourceImg = null;
+let cachedDisplayImg = null;
 
 function getWatermarkKey(photo) {
-  return photo?.resFilename || photo?.cloudFilename || photo
+    return photo?.resFilename || photo?.cloudFilename || photo;
 }
 
 function getPhotoSrc(photo) {
-  const key = photo?.resFilename || photo?.cloudFilename || photo
-  if (typeof key === 'string' && (key.startsWith('http') || key.startsWith('data:'))) {
-    return key + resize
-  }
-  return base_img_url2 + key + resize
+    const key = photo?.resFilename || photo?.cloudFilename || photo;
+    if (typeof key === "string" && (key.startsWith("http") || key.startsWith("data:"))) {
+        return key + resize;
+    }
+    return base_img_url2 + key + resize;
 }
 
+const showPopup = ref(false);
+const watermarkWithQRCode = ref(null); // 带二维码的图片,用于弹窗显示
 
-async function drawWatermark(event) {
-  const displayImg = event.target
+async function handleClick() {
+    // 点击时生成带二维码的图片用于弹窗显示
+    await generateImageWithQRCode();
+    showPopup.value = true;
+}
+
+// 加载二维码图片
+async function loadQRCodeImage() {
+    // 先检查缓存
+    if (imageCache.has("qrcode")) {
+        return imageCache.get("qrcode");
+    }
+    // 使用 loadImage 加载
+    try {
+        await loadImage(require("@/assets/img/home/qrcode.png"), "qrcode");
+        return imageCache.get("qrcode");
+    } catch (error) {
+        console.error("加载二维码失败:", error);
+        // 如果 require 失败,尝试直接创建图片
+        return new Promise((resolve, reject) => {
+            const img = new Image();
+            img.crossOrigin = "anonymous";
+            img.onload = () => {
+                imageCache.set("qrcode", img);
+                resolve(img);
+            };
+            img.onerror = reject;
+            img.src = require("@/assets/img/home/qrcode.png");
+        });
+    }
+}
+
+// 生成带二维码的图片(用于弹窗显示,不影响原图)
+async function generateImageWithQRCode() {
+    if (!cachedSourceImg || !cachedDisplayImg) return;
+    
+    try {
+        // 加载二维码图片
+        const qrCodeImg = await loadQRCodeImage();
+        
+        // 获取显示图片的尺寸
+        const rect = cachedDisplayImg.getBoundingClientRect();
+        const w = rect.width;
+        const h = rect.height;
+        
+        // 创建一个临时的 canvas 用于生成带二维码的图片
+        const tempCanvas = document.createElement("canvas");
+        const tempCtx = tempCanvas.getContext("2d");
+        
+        const dpr = window.devicePixelRatio || 1;
+        
+        // 设置 canvas 尺寸
+        tempCanvas.width = w * dpr;
+        tempCanvas.height = h * dpr;
+        
+        tempCtx.setTransform(dpr, 0, 0, dpr, 0, 0);
+        tempCtx.imageSmoothingEnabled = true;
+        tempCtx.imageSmoothingQuality = "high";
+        
+        // 清空 canvas
+        tempCtx.clearRect(0, 0, w, h);
+        
+        // 重新绘制图片
+        drawImageCoverByNatural(tempCtx, cachedSourceImg, w, h);
+        
+        // 绘制底部遮罩和文字
+        drawBottomMask(tempCtx, w, h);
+        drawBottomTextOverlay(tempCtx, w, h);
+        
+        // 二维码尺寸和位置(参考 albumCarouselItem 的样式)
+        const qrSize = 40;
+        const qrX = w - qrSize - 12; // 距离右边 12px
+        const qrY = 12; // 距离顶部 12px
+        
+        // 绘制二维码到右上角
+        tempCtx.drawImage(qrCodeImg, qrX, qrY, qrSize, qrSize);
+        
+        // 保存为带二维码的图片(不影响原来的 watermark)
+        watermarkWithQRCode.value = tempCanvas.toDataURL("image/jpeg", 0.85);
+    } catch (error) {
+        console.error("生成带二维码的图片失败:", error);
+        // 如果失败,使用原来的 watermark
+        watermarkWithQRCode.value = watermark.value;
+    }
+}
 
-  const key = getWatermarkKey(props.photo)
-  if (watermarkCache.has(key)) {
-    watermark.value = watermarkCache.get(key)
-    return
-  }
+async function drawWatermark(event) {
+    const displayImg = event.target;
+
+    const key = getWatermarkKey(props.photo);
+    if (watermarkCache.has(key)) {
+        watermark.value = watermarkCache.get(key);
+        // 从缓存中恢复图片引用
+        const cachedData = watermarkCache.get(key + "_refs");
+        if (cachedData) {
+            cachedSourceImg = cachedData.sourceImg;
+            cachedDisplayImg = cachedData.displayImg;
+        }
+        return;
+    }
 
-  // ✅ 用原始图片重新创建一个 Image
-  const sourceImg = await loadOriginalImage(displayImg.src)
+    // ✅ 用原始图片重新创建一个 Image
+    const sourceImg = await loadOriginalImage(displayImg.src);
+    
+    // 保存引用
+    cachedSourceImg = sourceImg;
+    cachedDisplayImg = displayImg;
 
-  drawWatermark2(sourceImg, displayImg)
+    drawWatermark2(sourceImg, displayImg);
 
-  watermarkCache.set(key, watermark.value)
+    watermarkCache.set(key, watermark.value);
+    // 同时保存图片引用
+    watermarkCache.set(key + "_refs", { sourceImg, displayImg });
 }
 
-const watermarkCache = new Map()
-
+const watermarkCache = new Map();
 
 function loadOriginalImage(src) {
-  return new Promise((resolve) => {
-    const img = new Image()
-    img.crossOrigin = 'anonymous'
-    img.onload = () => resolve(img)
-    img.src = src
-  })
+    return new Promise((resolve) => {
+        const img = new Image();
+        img.crossOrigin = "anonymous";
+        img.onload = () => resolve(img);
+        img.src = src;
+    });
 }
 
 function drawWatermark2(sourceImg, displayImg) {
-  const canvas = canvasRef.value
-  const ctx = canvas.getContext('2d')
+    const canvas = canvasRef.value;
+    const ctx = canvas.getContext("2d");
 
-  const rect = displayImg.getBoundingClientRect()
-  const w = rect.width
-  const h = rect.height
+    const rect = displayImg.getBoundingClientRect();
+    const w = rect.width;
+    const h = rect.height;
 
-  const dpr = window.devicePixelRatio || 1
+    const dpr = window.devicePixelRatio || 1;
 
-  canvas.width = w * dpr
-  canvas.height = h * dpr
-  canvas.style.width = w + 'px'
-  canvas.style.height = h + 'px'
+    canvas.width = w * dpr;
+    canvas.height = h * dpr;
+    canvas.style.width = w + "px";
+    canvas.style.height = h + "px";
 
-  ctx.setTransform(dpr, 0, 0, dpr, 0, 0)
-  ctx.imageSmoothingEnabled = true
-  ctx.imageSmoothingQuality = 'high'
+    ctx.setTransform(dpr, 0, 0, dpr, 0, 0);
+    ctx.imageSmoothingEnabled = true;
+    ctx.imageSmoothingQuality = "high";
 
-  ctx.clearRect(0, 0, w, h)
+    ctx.clearRect(0, 0, w, h);
 
-  // ✅ 用「原始像素图」做 cover
-  drawImageCoverByNatural(ctx, sourceImg, w, h)
+    // ✅ 用「原始像素图」做 cover
+    drawImageCoverByNatural(ctx, sourceImg, w, h);
 
-  drawBottomMask(ctx, w, h)
-  drawBottomTextOverlay(ctx, w, h)
+    drawBottomMask(ctx, w, h);
+    drawBottomTextOverlay(ctx, w, h);
 
-  watermark.value = canvas.toDataURL('image/jpeg', 0.85)
+    watermark.value = canvas.toDataURL("image/jpeg", 0.85);
 }
 function drawImageCoverByNatural(ctx, img, w, h) {
-  const imgRatio = img.naturalWidth / img.naturalHeight
-  const canvasRatio = w / h
-
-  let sx, sy, sw, sh
-
-  if (imgRatio > canvasRatio) {
-    sh = img.naturalHeight
-    sw = sh * canvasRatio
-    sx = (img.naturalWidth - sw) / 2
-    sy = 0
-  } else {
-    sw = img.naturalWidth
-    sh = sw / canvasRatio
-    sx = 0
-    sy = (img.naturalHeight - sh) / 2
-  }
-
-  ctx.drawImage(img, sx, sy, sw, sh, 0, 0, w, h)
+    const imgRatio = img.naturalWidth / img.naturalHeight;
+    const canvasRatio = w / h;
+
+    let sx, sy, sw, sh;
+
+    if (imgRatio > canvasRatio) {
+        sh = img.naturalHeight;
+        sw = sh * canvasRatio;
+        sx = (img.naturalWidth - sw) / 2;
+        sy = 0;
+    } else {
+        sw = img.naturalWidth;
+        sh = sw / canvasRatio;
+        sx = 0;
+        sy = (img.naturalHeight - sh) / 2;
+    }
+
+    ctx.drawImage(img, sx, sy, sw, sh, 0, 0, w, h);
 }
 
 function drawImageCover(ctx, img, w, h) {
-  const imgRatio = img.naturalWidth / img.naturalHeight
-  const canvasRatio = w / h
-
-  let sx, sy, sw, sh
-
-  if (imgRatio > canvasRatio) {
-    sh = img.naturalHeight
-    sw = sh * canvasRatio
-    sx = (img.naturalWidth - sw) / 2
-    sy = 0
-  } else {
-    sw = img.naturalWidth
-    sh = sw / canvasRatio
-    sx = 0
-    sy = (img.naturalHeight - sh) / 2
-  }
-
-  ctx.drawImage(img, sx, sy, sw, sh, 0, 0, w, h)
+    const imgRatio = img.naturalWidth / img.naturalHeight;
+    const canvasRatio = w / h;
+
+    let sx, sy, sw, sh;
+
+    if (imgRatio > canvasRatio) {
+        sh = img.naturalHeight;
+        sw = sh * canvasRatio;
+        sx = (img.naturalWidth - sw) / 2;
+        sy = 0;
+    } else {
+        sw = img.naturalWidth;
+        sh = sw / canvasRatio;
+        sx = 0;
+        sy = (img.naturalHeight - sh) / 2;
+    }
+
+    ctx.drawImage(img, sx, sy, sw, sh, 0, 0, w, h);
 }
 function drawBottomTextOverlay(ctx, w, h) {
-  const paddingX = 12
-  const paddingBottom = 8
-  const lineHeight = 16
-
-  ctx.textBaseline = 'alphabetic'
-  ctx.fillStyle = '#fff'
-  ctx.shadowColor = 'rgba(0,0,0,0.6)'
-  ctx.shadowBlur = 2
-
-  // ⬇️ 从底部开始,一行一行往上
-  let y = h - paddingBottom
-
-  // 第三行(最底)
-  ctx.font = '10px sans-serif'
-  console.log('paddingX', paddingX, y)
-  ctx.drawImage(imageCache.get("address"), paddingX, y - 9, 9, 10);
-  ctx.fillText(
-    '荔博园(广东省广州市从化区)',
-    paddingX + 12,
-    y
-  )
-
-  // 第二行
-  y -= 15
-  ctx.font = '16px PangMenZhengDao'
-  const workNameText = '梢期杀虫'
-  const prescriptionText = '药物处方:乙烯利'
-  ctx.fillText(
-    workNameText,
-    paddingX,
-    y
-  )
-  ctx.font = '10px sans-serif'
-  ctx.fillText(
-    prescriptionText,
-    paddingX + workNameText.length * 20,
-    y
-  )
-
-  // 第一行(最上)
-  y -= 17
-  ctx.font = '12px PangMenZhengDao'
-  const timeText = '2025.12.25'
-  ctx.fillText(timeText, paddingX, y)
-  const executorText = '执行人:张三李四'
-  ctx.font = '10px sans-serif'
-  ctx.fillText(executorText, paddingX + 80, y)
-
-  ctx.shadowBlur = 0
+    const paddingX = 12;
+    const paddingBottom = 8;
+    const lineHeight = 16;
+
+    ctx.textBaseline = "alphabetic";
+    ctx.fillStyle = "#fff";
+    ctx.shadowColor = "rgba(0,0,0,0.6)";
+    ctx.shadowBlur = 2;
+
+    // ⬇️ 从底部开始,一行一行往上
+    let y = h - paddingBottom;
+
+    // 第三行(最底)
+    ctx.font = "10px sans-serif";
+    console.log("paddingX", paddingX, y);
+    ctx.drawImage(imageCache.get("address"), paddingX, y - 9, 9, 10);
+    ctx.fillText("荔博园(广东省广州市从化区)", paddingX + 12, y);
+
+    // 第二行
+    y -= 15;
+    ctx.font = "16px PangMenZhengDao";
+    const workNameText = "梢期杀虫";
+    const prescriptionText = "药物处方:乙烯利";
+    ctx.fillText(workNameText, paddingX, y);
+    ctx.font = "10px sans-serif";
+    ctx.fillText(prescriptionText, paddingX + workNameText.length * 20, y);
+
+    // 第一行(最上)
+    y -= 17;
+    ctx.font = "12px PangMenZhengDao";
+    const timeText = "2025.12.25";
+    ctx.fillText(timeText, paddingX, y);
+    const executorText = "执行人:张三李四";
+    ctx.font = "10px sans-serif";
+    ctx.fillText(executorText, paddingX + 80, y);
+
+    ctx.shadowBlur = 0;
 }
 
-
 function drawBottomMask(ctx, w, h) {
-  const maskHeight = 60  // 和 3 行文字 + padding 精确匹配
-
-  ctx.fillStyle = 'rgba(0,0,0,0.45)'
-  ctx.fillRect(
-    0,
-    h - maskHeight, // ✅ 绝对贴底
-    w,
-    maskHeight
-  )
+    const maskHeight = 60; // 和 3 行文字 + padding 精确匹配
+
+    ctx.fillStyle = "rgba(0,0,0,0.45)";
+    ctx.fillRect(
+        0,
+        h - maskHeight, // ✅ 绝对贴底
+        w,
+        maskHeight
+    );
 }
 
-
-
-
 const showTagBox = ref(true); // 控制 tag-box 的显示状态
 const hideTagBox = (event) => {
-  event.stopPropagation();
-  showTagBox.value = false; // 隐藏 tag-box
+    event.stopPropagation();
+    showTagBox.value = false; // 隐藏 tag-box
 };
 
 const formatDate = (date) => {
-  const year = date.getFullYear();
-  const month = String(date.getMonth() + 1).padStart(2, '0'); // 月份从0开始,需要加1
-  const day = String(date.getDate()).padStart(2, '0');
-  return `${(year+"").substring(2)}${month}${day}`;
+    const year = date.getFullYear();
+    const month = String(date.getMonth() + 1).padStart(2, "0"); // 月份从0开始,需要加1
+    const day = String(date.getDate()).padStart(2, "0");
+    return `${(year + "").substring(2)}${month}${day}`;
 };
 
+const handleSaveImage = () => {
+    // 保存带二维码的图片
+    downloadImage(watermarkWithQRCode.value || watermark.value, "执行照片");
+};
 
+const handleWechat = () => {
+    // 微信分享功能(可以后续实现)
+    console.log("微信分享");
+};
 
+const handleCancel = () => {
+    showPopup.value = false;
+};
 
+function downloadImage(dataUrl, filename) {
+    const link = document.createElement("a");
+    link.href = dataUrl;
+    link.download = filename;
+    document.body.appendChild(link);
+    link.click();
+    document.body.removeChild(link);
+}
 </script>
 
 <style lang="scss" scoped>
 .canvas-container {
-  width: 100%;
-  height: 100%;
-  display: flex;
-  justify-content: center;
+    width: 100%;
+    height: 100%;
+    display: flex;
+    justify-content: center;
 }
 .carousel-item {
-  min-width: 100%;
-  max-height: 100%;
-  flex-shrink: 0;
-  width: 100%;
-  pointer-events: auto;
-  position: relative;
-  .tag-box {
-    position: absolute;
-    bottom: 30%;
-    left: 50%;
-    transform: translate(-50%, 50%); // 确保在高二分之一的位置水平居中
-    height: 18px;
-    padding: 0 6px;
-    background: rgba(108, 108, 108, 0.67);
-    border-radius: 10px;
-    display: flex;
-    align-items: center;
-    color: #FFFFFF;
-    font-size: 12px;
-
-    &.right {
-      left: auto;
-      right: 10px;
+    min-width: 100%;
+    max-height: 100%;
+    flex-shrink: 0;
+    width: 100%;
+    pointer-events: auto;
+    position: relative;
+    .tag-box {
+        position: absolute;
+        bottom: 30%;
+        left: 50%;
+        transform: translate(-50%, 50%); // 确保在高二分之一的位置水平居中
+        height: 18px;
+        padding: 0 6px;
+        background: rgba(108, 108, 108, 0.67);
+        border-radius: 10px;
+        display: flex;
+        align-items: center;
+        color: #ffffff;
+        font-size: 12px;
+
+        &.right {
+            left: auto;
+            right: 10px;
+        }
+        &.leftTop {
+            height: 25px;
+            line-height: 26px;
+            padding: 0 8px;
+            border-radius: 16px;
+            background: rgba(0, 0, 0, 0.6);
+            bottom: auto;
+            top: 6px;
+        }
     }
-    &.leftTop {
-      height: 25px;
-      line-height: 26px;
-      padding: 0 8px;
-      border-radius: 16px;
-      background: rgba(0, 0, 0, 0.6);
-      bottom: auto;
-      top: 6px;
+    .tag-text {
+        position: absolute;
+        bottom: 31%;
+        left: 50%;
+        width: 80%;
+        transform: translate(-50%, 50%); // 确保在高二分之一的位置水平居中
+        height: 24px;
+        padding: 10px 0px 10px 0px;
+        background: rgba(0, 0, 0, 0.67);
+        border-radius: 6px;
+        display: flex;
+        align-items: center;
+        justify-content: center;
+        text-align: center;
+        color: #ffffff;
+        font-size: 12px;
     }
-  }
-  .tag-text {
-    position: absolute;
-    bottom: 31%;
-    left: 50%;
-    width: 80%;
-    transform: translate(-50%, 50%); // 确保在高二分之一的位置水平居中
-    height: 24px;
-    padding: 10px 0px 10px 0px;
-    background: rgba(0, 0, 0, 0.67);
-    border-radius: 6px;
-    display: flex;
-    align-items: center;
-    justify-content: center;
-    text-align: center;
-    color: #FFFFFF;
-    font-size: 12px;
-  }
 
-  .center-mark {
-    position: absolute;
-    bottom: 10px;
-    left: 50%;
-    transform: translateX(-50%);
-    color: #36402c;
-    font-size: rpx(24);
-    font-weight: bold;
-    padding: rpx(14) rpx(30);
-    background: linear-gradient(
+    .center-mark {
+        position: absolute;
+        bottom: 10px;
+        left: 50%;
+        transform: translateX(-50%);
+        color: #36402c;
+        font-size: rpx(24);
+        font-weight: bold;
+        padding: rpx(14) rpx(30);
+        background: linear-gradient(
             90deg,
             rgba(255, 255, 255, 0) 0%,
             rgba(255, 255, 255, 0.6) 24%,
             rgba(255, 255, 255, 0.6) 76%,
             rgba(255, 255, 255, 0) 100%
-    );
-  }
+        );
+    }
 }
 .carousel-item img {
-  width: 100%;
-  display: block;
+    width: 100%;
+    display: block;
 }
 canvas {
-  position: absolute;
+    position: absolute;
 }
 .close-button {
-  background: transparent;
-  border: none;
-  color: #FFFFFF;
-  cursor: pointer;
-  font-size: 10px; // 可以根据需求调整大小
-  position: absolute;
-  top: -1px;
-  right: -9px; // 调整为合适的间距
-  transform: translateY(-50%);
+    background: transparent;
+    border: none;
+    color: #ffffff;
+    cursor: pointer;
+    font-size: 10px; // 可以根据需求调整大小
+    position: absolute;
+    top: -1px;
+    right: -9px; // 调整为合适的间距
+    transform: translateY(-50%);
 }
 
 .floating-img {
-  position: absolute;
-  bottom: 0;
-  right: 0;
-  width: auto !important;
-  height: 25% !important;
+    position: absolute;
+    bottom: 0;
+    right: 0;
+    width: auto !important;
+    height: 25% !important;
 }
 .floating-img-big {
-  position: fixed !important;
-  z-index: 99999 !important;
-  top: 50% !important;
-  left: 50% !important;
-  width: auto !important;
-  height: 100% !important;
-  transform: translate(-50%, -50%) !important;
+    position: fixed !important;
+    z-index: 99999 !important;
+    top: 50% !important;
+    left: 50% !important;
+    width: auto !important;
+    height: 100% !important;
+    transform: translate(-50%, -50%) !important;
 }
 
+.cavans-popup {
+    width: 100%;
+    max-width: 100%;
+    max-height: 90vh;
+    background: none;
+    border-radius: 12px;
+    overflow: auto;
+    display: flex;
+    flex-direction: column;
+    backdrop-filter: 4px;
+    .cavans-content {
+        text-align: center;
+        padding: 16px;
+        .current-img {
+            border-radius: 8px;
+            width: 100%;
+        }
+    }
 
-
-
+    // 底部操作按钮
+    .bottom-actions {
+        flex-shrink: 0;
+
+        .action-buttons {
+            padding: 16px;
+            display: flex;
+            justify-content: space-around;
+
+            .action-btn {
+                display: flex;
+                flex-direction: column;
+                align-items: center;
+                cursor: pointer;
+
+                .icon-circle {
+                    width: 48px;
+                    height: 48px;
+                    border-radius: 50%;
+                    display: flex;
+                    align-items: center;
+                    justify-content: center;
+                    color: #fff;
+                    margin-bottom: 4px;
+
+                    .el-icon {
+                        color: #fff;
+                    }
+                    img {
+                        width: 50px;
+                    }
+                }
+
+                &.blue-btn .icon-circle {
+                    background: #2199f8;
+                }
+
+                &.green-btn .icon-circle {
+                    background: #07c160;
+                }
+
+                &.orange-btn .icon-circle {
+                    background: #ff790b;
+                }
+
+                .btn-label {
+                    font-size: 12px;
+                    color: #fff;
+                }
+            }
+        }
+
+        .cancel-btn {
+            text-align: center;
+            font-size: 18px;
+            color: #fff;
+            cursor: pointer;
+        }
+    }
+}
 </style>

+ 200 - 292
src/views/old_mini/modify_work/modify.vue

@@ -50,12 +50,12 @@
                         </el-form-item>
                         <el-form-item label-width="70px" class="form-item text-item" label="服务亩数">
                             <div class="info-text">
-                                {{ detailData?.area ? formatArea(detailData?.area) + "亩" : "--" }}
+                                {{ detailData?.farm?.mianji ? formatArea(detailData?.farm?.mianji) + "亩" : "--" }}
                             </div>
                         </el-form-item>
                         <el-form-item label-width="70px" class="form-item text-item" label="服务区域">
                             <div class="info-text">
-                                {{ detailData?.serviceRegion || "--" }}
+                                {{ detailData?.farm?.address || "--" }}
                             </div>
                         </el-form-item>
                         <el-form-item
@@ -98,7 +98,12 @@
 
                 <template v-if="isEdit">
                     <div class="farm-card prescription-content common-inputs">
-                        <div class="card-title pb-12">药物处方</div>
+                        <div class="card-title pb-12 between">
+                            药物处方
+                            <div class="add-tag" @click="addDomain()">
+                                <el-icon color="#2199F8"><Plus /></el-icon>新增药物
+                            </div>
+                        </div>
                         <el-form-item label-width="82px" class="form-item" prop="usageMode" label="施用方式">
                             <el-select
                                 v-model="dynamicValidateForm.usageMode"
@@ -113,20 +118,35 @@
                                 />
                             </el-select>
                         </el-form-item>
+                        <el-form-item v-if="dynamicValidateForm.usageMode === '叶面施'" label-width="82px" class="form-item" prop="executeStyle" label="执行方式">
+                            
+                            <el-select
+                                    class="select-item"
+                                    v-model="dynamicValidateForm.executeStyle"
+                                    placeholder="执行方式"
+                                    @change="handleExecutionMethodChange"
+                                >
+                                    <el-option
+                                        v-for="(item, index) in modeList"
+                                        :key="index"
+                                        :label="item.name"
+                                        :value="item.value"
+                                    />
+                                </el-select>
+                        </el-form-item>
+
+                        <el-form-item v-if="dynamicValidateForm.usageMode === '根部施'" label-width="82px" class="form-item" prop="executeStyle" label="执行方式">
+                            <div class="info-text">人工</div>
+                        </el-form-item>
+                        
                         <div v-if="dynamicValidateForm.usageMode !== '人工农事'">
                             <el-form-item
-                                v-for="(domain, index) in dynamicValidateForm.prescriptionList"
+                                v-for="(domain, index) in dynamicValidateForm.prescription.pesticideFertilizerList"
                                 :key="index"
-                                :prop="'prescriptionList.' + index + '.value'"
+                                :prop="'prescription.pesticideFertilizerList.' + index + '.value'"
                                 class="prescription-item"
                             >
                                 <div class="recipe-item">
-                                    <div class="sub-title">
-                                        <div>{{ domain.name }}处方</div>
-                                        <div class="add-tag" @click="addDomain(index)">
-                                            <el-icon color="#2199F8"><Plus /></el-icon>新增药物
-                                        </div>
-                                    </div>
                                     <div class="recipe-form">
                                         <!-- <el-form-item
                                             v-for="(domain, index) in prescriptionItem.pesticideFertilizerList"
@@ -147,7 +167,7 @@
                                                         <el-select
                                                             filterable
                                                             @change="
-                                                                handlePesticideFertilizerChange(prescriptionI, index)
+                                                                handlePesticideFertilizerChange(index)
                                                             "
                                                             v-model="domain.code"
                                                             placeholder="请选择"
@@ -162,75 +182,8 @@
                                                         </el-select>
                                                     </div>
                                                 </div>
-                                                <div class="box-item">
-                                                    <div class="form-l">执行方式</div>
-                                                    <div
-                                                        class="form-r item-val"
-                                                        v-if="dynamicValidateForm.usageMode === '叶面施'"
-                                                    >
-                                                        <el-select
-                                                            class="select-item"
-                                                            v-model="domain.executionMethod"
-                                                            placeholder="执行方式"
-                                                            style="width: 150px"
-                                                            @change="
-                                                                (val) =>
-                                                                    handleExecutionMethodChange(
-                                                                        prescriptionI,
-                                                                        index,
-                                                                        val
-                                                                    )
-                                                            "
-                                                        >
-                                                            <el-option
-                                                                v-for="(item, index) in modeList"
-                                                                :key="index"
-                                                                :label="item.name"
-                                                                :value="item.value"
-                                                            />
-                                                        </el-select>
-                                                    </div>
-                                                    <div class="form-r r-text" v-else>人工</div>
-                                                </div>
 
-                                                <div class="mt-8" v-if="domain.executionMethod === 1">
-                                                    <div class="box-item sub-item">
-                                                        <div class="form-l has-sub">
-                                                            <div class="main-name">亩兑水量</div>
-                                                            <div class="sub-name">(药剂:兑水量)</div>
-                                                        </div>
-                                                        <div class="form-r input-box text-center">
-                                                            <el-input
-                                                                v-model="domain.ratio2"
-                                                                type="number"
-                                                                step="0.01"
-                                                                style="width: 150px"
-                                                                placeholder="请输入"
-                                                            >
-                                                                <template #append>{{ domain.unit }}</template>
-                                                            </el-input>
-                                                        </div>
-                                                    </div>
-                                                    <div class="box-item sub-item">
-                                                        <div class="form-l has-sub">
-                                                            <div class="main-name">单亩用量</div>
-                                                            <div class="sub-name">(亩数:药剂)</div>
-                                                        </div>
-                                                        <div class="form-r input-box text-center">
-                                                            <el-input
-                                                                v-model="domain.muUsage2"
-                                                                type="number"
-                                                                step="0.01"
-                                                                style="width: 150px"
-                                                                placeholder="请输入"
-                                                            >
-                                                                <template #append>{{ domain.unit }}</template>
-                                                            </el-input>
-                                                        </div>
-                                                    </div>
-                                                </div>
-
-                                                <div class="mt-8" v-else>
+                                                <div class="mt-8">
                                                     <div class="box-item sub-item">
                                                         <div class="form-l has-sub">
                                                             <div class="main-name">亩兑水量</div>
@@ -308,19 +261,17 @@
                         <div class="card-title">处方报价</div>
                         <div class="medicine-wrap">
                             <template
-                                v-for="(prescription, pIndex) in dynamicValidateForm.prescriptionList"
-                                :key="pIndex"
+                                v-for="(pesticide, mIndex) in dynamicValidateForm.prescription.pesticideFertilizerList"
+                                :key="mIndex"
                             >
                                 <div
                                     class="medicine-box"
-                                    v-for="(pesticide, mIndex) in prescription.pesticideFertilizerList"
-                                    :key="mIndex"
                                 >
                                     <div class="form-index">药肥{{ mIndex + 1 }}</div>
                                     <div class="box-wrap">
                                         <div class="medicine-item">
                                             <div class="item-name">药肥名称</div>
-                                            <div class="item-val">{{ pesticide.pesticideFertilizerName }}</div>
+                                            <div class="item-val">{{ pesticide.name }}</div>
                                         </div>
                                         <div class="medicine-item">
                                             <div class="item-name">药肥品牌</div>
@@ -348,11 +299,11 @@
                                         </div>
                                         <div class="medicine-item">
                                             <div class="item-name">单亩用量</div>
-                                            <div class="item-val">{{ getMuUsage(pesticide) }}{{ pesticide.unit }}</div>
+                                            <div class="item-val">{{ pesticide.dosage }}{{ pesticide.unit }}</div>
                                         </div>
                                         <div class="medicine-item">
                                             <div class="item-name">服务亩数</div>
-                                            <div class="item-val">{{ formatArea(detailData?.area) }}亩</div>
+                                            <div class="item-val">{{ detailData?.farm?.mianji ? formatArea(detailData?.farm?.mianji) + "亩": "" }}</div>
                                         </div>
                                         <div class="medicine-item">
                                             <div class="item-total">总计:</div>
@@ -382,7 +333,7 @@
                                     </div>
                                     <div class="medicine-item">
                                         <div class="item-name">服务亩数</div>
-                                        <div class="item-val">{{ formatArea(detailData?.area) }}亩</div>
+                                        <div class="item-val">{{ detailData?.farm?.mianji ? formatArea(detailData?.farm?.mianji) + "亩" : "" }}</div>
                                     </div>
                                     <div class="medicine-item">
                                         <div class="item-total">总计:</div>
@@ -420,7 +371,7 @@
                             </div>
                             <div
                                 class="new-table-wrap"
-                                v-for="(subP, prescriptionI) in detailData?.prescriptionList"
+                                v-for="(subP, prescriptionI) in detailData?.prescription?.pesticideFertilizerList || []"
                                 :key="prescriptionI"
                             >
                                 <!-- <div
@@ -461,7 +412,7 @@
                             </div>
                         </div>
                         <div class="info-content-wrap">
-                            <price-table :prescriptionData="quotationData.prescriptionList">
+                            <price-table :prescriptionData="dynamicValidateForm.prescription.prescriptionList">
                                 <template #bottomContent>
                                     <div class="price-bottom">
                                         <div class="info-title-wrap">
@@ -471,7 +422,7 @@
                                                     quotationData?.farmWorkServiceCost
                                                         ? getServiceCost(
                                                               quotationData.farmWorkServiceCost,
-                                                              quotationData.area
+                                                              quotationData.farm?.mianji
                                                           )
                                                         : "--"
                                                 }}<span class="unit-text">元</span>
@@ -480,7 +431,7 @@
                                         <div class="price-info">
                                             <div class="info-l">
                                                 执行方式<span class="main-text">{{
-                                                    quotationData.executionMethodName || "人工"
+                                                    dynamicValidateForm.executionMethodName || "人工"
                                                 }}</span>
                                             </div>
                                             <div class="info-c">
@@ -494,7 +445,7 @@
                                             </div>
                                             <div class="info-r">
                                                 亩数<span class="main-text">{{
-                                                    quotationData.area ? formatArea(quotationData.area) + "亩" : "--"
+                                                    quotationData.farm?.mianji ? formatArea(quotationData.farm?.mianji) + "亩" : "--"
                                                 }}</span>
                                             </div>
                                         </div>
@@ -545,35 +496,33 @@ const store = useStore();
 const router = useRouter();
 const route = useRoute();
 
-const actionType = ref([]);
 
-const isEdit = ref(false);
+const isEdit = ref(true);
 
 onActivated(() => {
-    isEdit.value = route.query.isEdit ? true : false;
+    // isEdit.value = route.query.isEdit ? true : false;
     if (route.query.farmWorkId) {
         getDetail();
     }
     window.scrollTo(0, 0);
-    if (route.query.data) {
-        actionType.value = JSON.parse(route.query.data);
-    } else {
-        actionType.value = ["生长异常"];
+    // 初始化 prescription 对象
+    if (!route.query.farmWorkId) {
+        dynamicValidateForm.prescription = {
+            usageMode: "",
+            pesticideFertilizerList: [
+                {
+                    code: "",
+                    name: "",
+                    dosage: "",
+                    ratio: "",
+                    typeName: "",
+                    muPrice: 0,
+                    executeStyle: 1,
+                    unit: "",
+                },
+            ],
+        };
     }
-    dynamicValidateForm.prescriptionList = actionType.value.map((name) => ({
-        name,
-        pesticideFertilizerList: [
-            {
-                key: 1,
-                typeName: "",
-                muUsage: "",
-                muUsage2: "",
-                ratio: "",
-                ratio2: "",
-                remark: "",
-            },
-        ],
-    }));
 });
 
 const priceSheetPopupRef = ref(null);
@@ -583,112 +532,48 @@ const showPriceSheetPopup = () => {
 
 const detailData = ref({});
 const getDetail = async () => {
-    const { data, code } = await VE_API.farm.getFarmWorkLib({ id: route.query.farmWorkId });
+    const { data, code } = await VE_API.farm.getFarmWorkLib({ id: route.query.farmWorkId, farmId: route.query.farmId });
     if(code === 0) {
         detailData.value = data;
         dynamicValidateForm.executeDate = data.executeDate;
-        dynamicValidateForm.usageMode = data.usageMode;
-        data.prescriptionList = data.prescription?.pesticideFertilizerList || [];
-    
-        dynamicValidateForm.prescriptionList = data.prescriptionList;
+        dynamicValidateForm.usageMode = data.prescription.usageMode;
+        // 从 prescription 获取数据
+        dynamicValidateForm.prescription = data.prescription || {
+            usageMode: "",
+            pesticideFertilizerList: [],
+        };
         servicePricePerMu.value = detailData.value.farmWorkServiceCost || null;
-    
-        // getQuotationData();
+        const pesticideFertilizerCodes = data.prescription.pesticideFertilizerList.map(item => item.code);
+        getPriceList(data.schemeId, pesticideFertilizerCodes);
     }
 };
 
+const getPriceList = async (schemeId, pesticideFertilizerCodes) => {
+    const { data } = await VE_API.farm.getPriceList({ schemeId, pesticideFertilizerCodes });
+    if (!data || !Array.isArray(data)) return;
+
+    dynamicValidateForm.prescription.pesticideFertilizerList.forEach((item) => {
+        const priceInfo = data.find((p) => p.pesticideFertilizerCode === item.code);
+        if (!priceInfo) return;
+        item.price = priceInfo.price ?? item.price;
+        item.brand = priceInfo.brand ?? item.brand;
+    });
+};
+
 const toEditPrescription = () => {
     isEdit.value = true;
 };
 
 const quotationData = ref({});
 
-const getQuotationData = async () => {
-    let priceDataObj = {};
-    const { data } = await VE_API.z_farm_work_record_cost.getByRecordId({ farmWorkRecordId: detailData.value.id });
-    priceDataObj = data;
-    if (priceDataObj && Object.keys(priceDataObj).length > 0) {
-        // 合并外层字段
-        quotationData.value = {
-            ...detailData.value,
-            ...priceDataObj,
-            agriculturalId: priceDataObj.agriculturalId,
-        };
-
-        // 根据 itemsList 的 pesticideFertilizerId 匹配并赋值品牌和价格
-        if (priceDataObj.itemsList && Array.isArray(priceDataObj.itemsList) && detailData.value.prescriptionList) {
-            // 创建价格映射表
-            const priceMap = new Map();
-            priceDataObj.itemsList.forEach((item) => {
-                priceMap.set(String(item.pesticideFertilizerId), {
-                    brand: item.brand || "",
-                    price: item.price || 0,
-                    totalPrice: item.totalPrice || null,
-                });
-            });
-
-            // 遍历处方列表,赋值品牌和价格,并计算格式化字段供 price-table 使用
-            quotationData.value.prescriptionList = detailData.value.prescriptionList.map((prescription) => {
-                return {
-                    ...prescription,
-                    pesticideFertilizerList: prescription.pesticideFertilizerList.map((pesticide) => {
-                        const pesticideId = String(pesticide.pesticideFertilizerId || "");
-                        const priceInfo = priceMap.get(pesticideId);
-
-                        if (priceInfo) {
-                            const price = priceInfo.price || 0;
-                            const muUsage = pesticide.muUsage || 0;
-                            const unit = pesticide.unit || "";
-                            const area = detailData.value.area || 0;
-
-                            // 计算总价:优先使用 totalPrice,否则计算 price * muUsage * area
-                            const total = priceInfo.totalPrice ? priceInfo.totalPrice : price * muUsage * area;
-
-                            return {
-                                ...pesticide,
-                                brand: priceInfo.brand || "--",
-                                totalPrice: priceInfo.totalPrice,
-                                // 格式化字段供 price-table 组件使用
-                                price: price > 0 ? `${price}元/${unit}` : "--", // 格式化单价显示
-                                dosage: muUsage > 0 ? `${muUsage}${unit}` : "--", // 格式化用量显示
-                                total: total > 0 ? total.toFixed(2) : "--", // 格式化总价显示
-                            };
-                        }
-                        return pesticide;
-                    }),
-                };
-            });
-        }
-    }
-};
-
-// 根据执行方式获取单亩用量:1=无人机用muUsage2,2=人工用muUsage
-const getMuUsage = (pesticide) => {
-    if (!pesticide) return 0;
-    // 如果是叶面施且有执行方式选择,根据执行方式判断
-    if (
-        detailData.value?.usageMode === "叶面施" &&
-        dynamicValidateForm.executionMethod !== null &&
-        dynamicValidateForm.executionMethod !== undefined
-    ) {
-        // 1 = 无人机,使用 muUsage2
-        if (dynamicValidateForm.executionMethod == 1) {
-            return pesticide.muUsage2 || pesticide.muUsage || 0;
-        }
-        // 2 = 人工,使用 muUsage
-        if (dynamicValidateForm.executionMethod == 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 "--";
-    const total = (pesticide.price * muUsage * detailData.value.area).toFixed(2);
+    const price = Number(pesticide.price || 0);
+    const dosage = Number(pesticide.dosage || 0); // 单亩用量
+    const area = Number(detailData.value.farm?.mianji || 0); // 农场面积
+    if (!price || !dosage || !area) return "--";
+    const total = (price * dosage * area).toFixed(2);
     return total;
 };
 
@@ -717,25 +602,27 @@ const clearData = () => {
     dynamicValidateForm.executeDate = dayjs().format("YYYY-MM-DD");
     dynamicValidateForm.checkDay = "";
     dynamicValidateForm.usageMode = "";
-    dynamicValidateForm.prescriptionList = [
-        {
-            name: "",
-            pesticideFertilizerList: [
-                {
-                    key: 1,
-                    typeName: "",
-                    muUsage: "",
-                    muUsage2: "",
-                    ratio: "",
-                    ratio2: "",
-                    remark: "",
-                },
-            ],
-        },
-    ];
-
-    // 清空其他数据
-    actionType.value = [];
+    dynamicValidateForm.prescription = {
+        id: "",
+        usageMode: "",
+        farmWorkLibCode: "",
+        expertId: "",
+        phenology: "",
+        soil: "",
+        speed: null,
+        pesticideFertilizerList: [
+            {
+                code: "",
+                name: "",
+                dosage: "",
+                ratio: "",
+                typeName: "",
+                muPrice: 0,
+                executeStyle: 1,
+                unit: "",
+            },
+        ],
+    };
 };
 
 onDeactivated(() => {
@@ -765,11 +652,8 @@ const modeList = ref([
     { name: "人工", value: 2 },
 ]);
 
-const handleExecutionMethodChange = (parentIndex, index, val) => {
-    const domain = dynamicValidateForm.prescriptionList[parentIndex].pesticideFertilizerList[index];
+const handleExecutionMethodChange = (index, val) => {
     if (val == 1) {
-        domain.muUsage = domain.muUsage2;
-        domain.ratio = domain.ratio2;
         servicePricePerMu.value = detailData.value.uavServicePrice;
     } else {
         servicePricePerMu.value = detailData.value.manualServicePrice;
@@ -785,23 +669,30 @@ const dynamicValidateForm = reactive({
     executeDate: dayjs().format("YYYY-MM-DD"),
     checkDay: "",
     usageMode: "",
+    executeStyle: 2,
     executionMethod: 2,
-    prescriptionList: [
-        {
-            name: "",
-            pesticideFertilizerList: [
-                {
-                    key: 1,
-                    typeName: "",
-                    muUsage: "",
-                    muUsage2: "",
-                    ratio: "",
-                    ratio2: "",
-                    remark: "",
-                },
-            ],
-        },
-    ],
+    prescription: {
+        id: "",
+        usageMode: "",
+        farmWorkLibCode: "",
+        expertId: "",
+        phenology: "",
+        soil: "",
+        speed: null,
+        pesticideFertilizerList: [
+            {
+                code: "",
+                id: "",
+                name: "",
+                dosage: "",
+                ratio: "",
+                typeName: "",
+                muPrice: 0,
+                executeStyle: 1,
+                unit: "",
+            },
+        ],
+    },
 });
 
 const rules = {
@@ -835,15 +726,20 @@ const rules = {
     ],
 };
 
-const addDomain = (parentIndex) => {
-    dynamicValidateForm.prescriptionList[parentIndex].pesticideFertilizerList.unshift({
-        key: Date.now(),
-        muUsage: "",
-        muUsage2: "",
+const addDomain = () => {
+    if (!dynamicValidateForm.prescription.pesticideFertilizerList) {
+        dynamicValidateForm.prescription.pesticideFertilizerList = [];
+    }
+    dynamicValidateForm.prescription.pesticideFertilizerList.unshift({
+        code: "",
+        name: "",
+        dosage: "",
         ratio: "",
-        ratio2: "",
-        remark: "",
-        executionMethod: 2, // 默认人工
+        typeName: "",
+        muPrice: 0,
+        id: "",
+        executeStyle: 1,
+        unit: "",
     });
 };
 
@@ -858,43 +754,45 @@ const allUsageModeList = ["叶面施", "根部施", "人工农事"];
  * 选择药肥的时候修改订单中药肥pesticideFertilizerId 以外其他数据
  * @param index
  */
-const handlePesticideFertilizerChange = (parentIndex, index) => {
+const handlePesticideFertilizerChange = (index) => {
+    const currentItem = dynamicValidateForm.prescription.pesticideFertilizerList[index];
     let obj = pesticideFertilizersOptions.value.filter(
-        (item) =>
-            dynamicValidateForm.prescriptionList[parentIndex].pesticideFertilizerList[index].pesticideFertilizerId ===
-            item.id
+        (item) => currentItem.code === item.pesticideFertilizerCode
     )[0];
-    dynamicValidateForm.prescriptionList[parentIndex].pesticideFertilizerList[index] = {
-        ...dynamicValidateForm.prescriptionList[parentIndex].pesticideFertilizerList[index],
-        typeName: obj.typeName,
-        unit: obj.unit,
-        defaultRatio: obj.defaultRatio,
-        usageModeList: obj.usageModeList,
-        executionMethod: obj.executionMethod || 2, // 默认人工
-        ratio: obj.defaultRatio,
-        defaultName: obj.defaultName,
-        pesticideFertilizerName: obj.name,
-        pesticideFertilizerCode: obj.pesticideFertilizerCode,
-    };
+    if (obj) {
+        dynamicValidateForm.prescription.pesticideFertilizerList[index] = {
+            ...currentItem,
+            code: obj.pesticideFertilizerCode,
+            id: obj.id,
+            name: obj.name || obj.defaultName,
+            typeName: obj.typeName,
+            unit: obj.unit,
+            ratio: obj.defaultRatio || currentItem.ratio,
+            executeStyle: obj.executionMethod || 1,
+        };
+    }
 };
 
-const removeDomain = (parentIndex, item) => {
-    const index = dynamicValidateForm.prescriptionList[parentIndex].pesticideFertilizerList.indexOf(item);
-    if (index !== -1) {
-        dynamicValidateForm.prescriptionList[parentIndex].pesticideFertilizerList.splice(index, 1);
+const removeDomain = (index) => {
+    if (index !== -1 && dynamicValidateForm.prescription.pesticideFertilizerList) {
+        dynamicValidateForm.prescription.pesticideFertilizerList.splice(index, 1);
     }
 };
 
-const resetItemForm = (parentIndex, index) => {
-    dynamicValidateForm.prescriptionList[parentIndex].pesticideFertilizerList[index] = {
-        typeName: "",
-        muUsage: "",
-        muUsage2: "",
-        ratio: "",
-        ratio2: "",
-        remark: "",
-        executionMethod: 2, // 默认人工
-    };
+const resetItemForm = (index) => {
+    if (dynamicValidateForm.prescription.pesticideFertilizerList) {
+        dynamicValidateForm.prescription.pesticideFertilizerList[index] = {
+            code: "",
+            id: "",
+            name: "",
+            dosage: "",
+            ratio: "",
+            typeName: "",
+            muPrice: 0,
+            executeStyle: 1,
+            unit: "",
+        };
+    }
 };
 
 const servicePricePerMu = ref(null);
@@ -921,17 +819,26 @@ const submit = () => {
     const data = {
         id: route.query.farmWorkId,
         ...dynamicValidateForm,
-        prescription:{
-            ...detailData.value.prescription,
-            pesticideFertilizerList:dynamicValidateForm.prescriptionList
-        }
+        prescription: dynamicValidateForm.prescription
     };
-    VE_API.monitor.saveFarmWorkLib(data).then(async (res) => {
+    VE_API.monitor.saveFarmWorkLib(data);
+
+    // 保存报价信息
+    const priceList = {
+        schemeId: detailData.value.schemeId,
+        pesticideFertilizerInfos: dynamicValidateForm.prescription.pesticideFertilizerList.map(item => {
+            return {
+                pesticideFertilizerId: item.id,
+                price: item.price,
+                brand: item.brand,
+            }
+        }),
+    }
+    VE_API.farm.updateBatchByScheme(priceList).then(async (res) => {
         if (res.code === 0) {
             await getDetail();
             ElMessage.success("保存成功");
             isEdit.value = false;
-            // showPriceSheetPopup();
         }
     });
     // VE_API.z_farm_work_record.issueFarmWorkRecord(data).then(async (res) => {
@@ -1128,12 +1035,12 @@ const handleEditInteract = (item) => {
         .add-tag {
             font-size: 12px;
             color: #2199f8;
-            padding: 4px 8px;
-            background: rgba(33, 153, 248, 0.16);
-            border-radius: 20px;
+            padding: 0px 11px;
+            border: 1px solid #2199F8;
+            border-radius: 5px;
             font-weight: normal;
-            height: 25px;
-            line-height: 25px;
+            height: 28px;
+            line-height: 28px;
         }
         .type-tag {
             margin-left: 5px;
@@ -1640,6 +1547,7 @@ const handleEditInteract = (item) => {
             border-radius: 6px;
             padding: 20px 10px;
             width: 100%;
+            box-sizing: border-box;
             position: relative;
             // background: rgb(209, 235, 255, 0.3);
             // margin-bottom: 12px;

+ 1 - 1
src/views/old_mini/monitor/subPages/plan.vue

@@ -377,7 +377,7 @@ const handleRowClick = (item) => {
     curFarmObj.value = item;
     router.push({
         path: "/modify",
-        query: { id: item.id, farmWorkId: item.farmWorkId, containerSpaceTimeId: item.containerSpaceTimeId },
+        query: { id: item.id, farmId: route.query.farmId, farmWorkId: item.farmWorkId, containerSpaceTimeId: item.containerSpaceTimeId },
     });
 };