소스 검색

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

wangsisi 1 일 전
부모
커밋
37b91d96a7
3개의 변경된 파일340개의 추가작업 그리고 19개의 파일을 삭제
  1. 71 0
      src/components/popup/qrCodePopup.vue
  2. 192 4
      src/views/old_mini/interaction/index.vue
  3. 77 15
      src/views/old_mini/work_detail/index.vue

+ 71 - 0
src/components/popup/qrCodePopup.vue

@@ -0,0 +1,71 @@
+<template>
+    <popup v-model:show="showValue" round class="qr-code-popup" teleport="body">
+        <div class="qr-code-content">
+            <div class="qr-code-title">
+                <slot name="success"></slot>
+                <div class="title-text">
+                    <div class="text-item">扫码进入 <span class="blue">飞鸟管家</span> 小程序</div>
+                    <div class="text-item">查看农场更多详细信息</div>
+                </div>
+            </div>
+            <div class="qr-code-img">
+                <img src="@/assets/img/home/qrcode.png" alt="">
+            </div>
+            <div class="img-tips">长按图片扫码或保存</div>
+        </div>
+    </popup>
+</template>
+
+<script setup>
+import { ref } from "vue";
+import { Popup } from "vant";
+
+const showValue = ref(false);
+
+function showPopup() {
+    showValue.value = true;
+}
+
+defineExpose({
+    showPopup,
+});
+</script>
+
+<style lang="scss" scoped>
+.qr-code-popup {
+    width: 321px;
+    background: linear-gradient(0deg, #FFFFFF 5%, #FFFFFF 65%, #B2DCFD 123.05%, #2199F8 137.88%);
+    .qr-code-content {
+        display: flex;
+        flex-direction: column;
+        align-items: center;
+        justify-content: center;
+        padding: 20px 20px 28px 20px;
+    }
+    .qr-code-img {
+        width: 212px;
+        img {
+            width: 100%;
+        }
+    }
+    .title-text {
+        text-align: center;
+        padding: 6px 0 8px 0;
+        .text-item {
+            font-size: 20px;
+            color: #000;
+            line-height: 32px;
+            .blue {
+                color: #2199F8;
+                font-weight: 500;
+                padding: 0 2px;
+            }
+        }
+    }
+    .img-tips {
+        font-size: 16px;
+        color: #7A7A7A;
+        padding-top: 28px;
+    }
+}
+</style>

+ 192 - 4
src/views/old_mini/interaction/index.vue

@@ -1,6 +1,6 @@
 <template>
     <div class="interaction-page">
-        <custom-header name="农情互动" :showClose="false" :isGoBack="false" />
+        <custom-header name="农情互动" bgColor="#f2f4f5" :isClose="true" :showClose="false" />
         <div class="interaction-content">
             <!-- 顶部说明 -->
             <div class="intro-card">
@@ -17,9 +17,18 @@
                 <div v-for="variety in crop.varieties" :key="variety.id" class="variety-card">
                     <div class="field-row">
                         <div class="field-value">
-                            <el-select v-model="variety.variety" class="variety-input" placeholder="选择品种">
+                            <el-select 
+                                v-model="variety.variety" 
+                                class="variety-input" 
+                                placeholder="选择品种"
+                            >
                                 <el-option v-for="item in varietyOptions" :key="item.value" :label="item.label"
                                     :value="item.value" />
+                                    <template #footer>
+                                        <el-button text bg @click="onAddOption(variety)">
+                                            + 增加品种
+                                        </el-button>
+                                    </template>
                             </el-select>
                         </div>
                     </div>
@@ -45,12 +54,42 @@
                 </div>
             </div>
         </div>
+
+        <!-- 底部按钮 -->
+        <div class="fixed-btn-wrap">
+            <div class="fixed-btn" @click="handleConfirm">
+                确认信息
+            </div>
+        </div>
     </div>
+
+    <qr-code-popup ref="qrCodePopupRef">
+        <template #success>
+            <div class="success-text">
+                <img class="success-icon" src="@/assets/img/home/right.png" alt="">
+                您的作物信息已完善
+            </div>
+        </template>
+    </qr-code-popup>
+
+
+    <popup class="add-tag-popup" :z-index="2500" round v-model:show="showAddPopup" @update:show="handlePopupClose">
+        <div class="tag-item">
+            <div class="popup-title">新增品种名称</div>
+            <el-input autofocus class="popup-input" v-model="newVarietyName" placeholder="请输入品种名称" size="large" />
+        </div>
+        <div class="popup-button">
+            <div class="cancel" @click="handleCancelAdd">取消</div>
+            <div @click="handleAddVariety">确认</div>
+        </div>
+    </popup>
 </template>
 
 <script setup>
-import { ref } from "vue";
+import { ref, nextTick } from "vue";
+import { Popup } from "vant";
 import customHeader from "@/components/customHeader.vue";
+import qrCodePopup from "@/components/popup/qrCodePopup.vue";
 
 // 简单示例数据,后续可替换为接口返回
 const crops = ref([
@@ -105,6 +144,61 @@ const stageOptions = ref([
     { label: "抽梢期", value: "抽梢期" },
     { label: "坐果期", value: "坐果期" },
 ]);
+
+const qrCodePopupRef = ref(null);
+
+const handleConfirm = () => {
+    qrCodePopupRef.value.showPopup();
+}
+
+const showAddPopup = ref(false);
+const newVarietyName = ref("");
+const currentVariety = ref(null); // 记录当前正在添加品种的 variety 对象
+
+const handleAddVariety = () => {
+    if (!newVarietyName.value.trim()) {
+        return;
+    }
+    const newOption = { label: newVarietyName.value, value: newVarietyName.value };
+    varietyOptions.value.push(newOption);
+    
+    // 如果当前有正在添加品种的 variety,则自动选中新增的品种
+    if (currentVariety.value) {
+        currentVariety.value.variety = newVarietyName.value;
+    }
+    
+    newVarietyName.value = "";
+    showAddPopup.value = false;
+    currentVariety.value = null;
+}
+
+const onAddOption = async (variety) => {
+    // 先关闭下拉菜单
+    if (document.activeElement) {
+        document.activeElement.blur();
+    }
+    
+    // 等待下拉菜单关闭后再显示弹窗
+    await nextTick();
+    
+    // 记录当前 variety
+    currentVariety.value = variety;
+    showAddPopup.value = true;
+}
+
+const handleCancelAdd = () => {
+    newVarietyName.value = "";
+    showAddPopup.value = false;
+    currentVariety.value = null;
+}
+
+const handlePopupClose = (show) => {
+    if (!show) {
+        // 弹窗关闭时清空状态
+        newVarietyName.value = "";
+        currentVariety.value = null;
+    }
+}
 </script>
 
 <style lang="scss" scoped>
@@ -119,7 +213,7 @@ const stageOptions = ref([
 .interaction-content {
     height: calc(100% - 40px);
     overflow: auto;
-    padding: 10px;
+    padding: 12px 10px 70px 10px;
     box-sizing: border-box;
 }
 
@@ -245,6 +339,32 @@ const stageOptions = ref([
     }
 }
 
+
+.fixed-btn-wrap {
+    display: flex;
+    justify-content: center;
+    position: fixed;
+    bottom: 0px;
+    left: 0;
+    right: 0;
+    background: #fff;
+    padding: 10px 12px;
+    box-sizing: border-box;
+    // box-shadow: 0 -2px 8px rgba(15, 35, 52, 0.06);
+    box-shadow: 2px 2px 4.5px 0px #00000066;
+
+    .fixed-btn {
+        min-width: 110px;
+        height: 40px;
+        line-height: 40px;
+        text-align: center;
+        border-radius: 20px;
+        background: linear-gradient(180deg, #70bffe, #2199f8);
+        color: #ffffff;
+        font-size: 14px;
+    }
+}
+
 .date-input {
     height: 32px;
     border-radius: 4px;
@@ -257,4 +377,72 @@ const stageOptions = ref([
     color: #c0c4cc;
     font-size: 14px;
 }
+
+.success-text {
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    font-size: 24px;
+    color: #000;
+    .success-icon {
+        width: 28px;
+        height: 28px;
+        margin-right: 5px;
+    }
+}
+
+
+.add-tag-popup {
+    width: 90%;
+    padding: 24px 16px 20px 16px;
+    background: linear-gradient(360deg, #FFFFFF 74.2%, #D1EBFF 100%);
+
+    .popup-title {
+        font-size: 16px;
+        font-weight: 400;
+        margin-bottom: 12px;
+        color: #000000;
+        .name-text{
+            font-weight: 500;
+            color: #2199F8;
+            padding: 0 2px;
+        }
+    }
+
+    .ml-2 {
+        margin-left: 3px;
+    }
+
+    .popup-input {
+        margin-bottom: 24px;
+    }
+
+    .popup-button {
+        display: flex;
+
+        div {
+            flex: 1;
+            font-size: 16px;
+            padding: 9px;
+            border-radius: 20px;
+            background: #2199F8;
+            color: #fff;
+            text-align: center;
+            cursor: pointer;
+        }
+
+        .cancel {
+            margin-right: 13px;
+            color: #000;
+            background: #fff;
+            border: 1px solid #999999;
+        }
+        .delete {
+            margin-right: 13px;
+            color: #FF3D3D;
+            background: #fff;
+            border: 1px solid rgba(255, 61, 61, 0.4);
+        }
+    }
+}
 </style>

+ 77 - 15
src/views/old_mini/work_detail/index.vue

@@ -4,28 +4,32 @@
 
         <div class="work-detail-content">
             <!-- 顶部状态 -->
-            <div class="content-status">
+            <div class="content-status" :class="'status-' + detail?.flowStatus">
                 <div class="status-l">
                     <div class="status-title">{{ statusText }}</div>
-                    <div class="status-sub" v-if="triggerDateText">
+                    <div class="status-sub" v-if="triggerDateText && detail?.flowStatus === 0">
                         预计触发时间 {{ triggerDateText }}
                     </div>
+                    <div class="status-sub" v-if="detail?.flowStatus === 1">
+                        任务进度:1/2
+                    </div>
                 </div>
             </div>
 
             <div class="work-wrap">
                 <!-- 农事组信息 -->
-                <div class="box-wrap group-info group-box">
+                <!-- <div class="box-wrap group-info group-box">
                     <div class="group-name">
                         农事组:
                         <span class="group-name-text">{{ detail.farmWorkName || detail.farmWorkLibName || "--" }}</span>
                     </div>
-                </div>
+                </div> -->
 
                 <!-- 每一段农事 -->
-                <div v-for="(prescription, index) in stageList" :key="index" class="box-wrap stage-card">
+                <div v-for="(prescription, index) in stageList" :key="index" class="box-wrap stage-card" :class="'status-' + prescription.tagType">
                     <div class="stage-header">
                         <div class="stage-title">{{ getStageTitle(index, prescription) }}</div>
+                        <div class="title-tag" :class="'tag-' + prescription.tagType">{{ prescription.tagType === 0 ? "待完成" : "已完成" }}</div>
                     </div>
 
                     <div class="stage-info">
@@ -110,10 +114,15 @@
                             </span>
                         </div>
                     </div>
+                    <!-- 执行操作 -->
+                    <div class="execute-action" v-if="info?.appType === 1 && prescription.tagType === 0">
+                        <div class="action-item second">稍后执行</div>
+                        <div class="action-item primary">我已完成</div>
+                    </div>
                 </div>
 
                 <!-- 底部按钮 -->
-                <div class="fixed-btn-wrap">
+                <div class="fixed-btn-wrap" v-if="info?.appType === 2">
                     <div class="fixed-btn" @click="handleConvert">
                         转发农事
                     </div>
@@ -131,7 +140,8 @@ import { formatDate } from "@/common/commonFun";
 
 const route = useRoute();
 const router = useRouter();
-
+const info = JSON.parse(localStorage.getItem("localUserInfo") || "{}");
+console.log('info', info);
 const detail = ref({
     "consequenceText": "",
     "id": null,
@@ -144,7 +154,7 @@ const detail = ref({
     "expert": null,
     "orderStatus": null,
     "activeStatus": null,
-    "flowStatus": null,
+    "flowStatus": 1,
     "farmId": null,
     "regionId": null,
     "farmMiniUserId": null,
@@ -215,6 +225,7 @@ const detail = ref({
     "groupList": [
         {
             "name": "蒂蛀虫防治",
+            "tagType": 1,
             "pesticideList": [
                 {
                     "code": "1009",
@@ -295,6 +306,7 @@ const detail = ref({
         },
         {
             "name": "蒂蛀虫防治",
+            "tagType": 0,
             "pesticideList": [
                 {
                     "code": "1009",
@@ -396,8 +408,8 @@ const stageExecutionMethods = ref({});
 
 const statusText = computed(() => {
     // 简单根据 flowStatus 判断,默认“待触发”
-    if (detail.value.flowStatus === 2) return "执行中";
-    if (detail.value.flowStatus === 3) return "已完成";
+    if (detail.value.flowStatus === 1) return "待完成";
+    if (detail.value.flowStatus === 2) return "已完成";
     return "待触发";
 });
 
@@ -456,7 +468,6 @@ const getPesticideParam = (item, stageIndex) => {
 
 const getParamRemark = (item, stageIndex) => {
     const param = getPesticideParam(item, stageIndex);
-    console.log('param', param?.remark);
     return param?.remark || item.remark || "";
 };
 
@@ -500,6 +511,11 @@ const changeExecutionMethod = (stageIndex, value) => {
         // background: #FF953D;
         width: 100%;
     }
+    &.status-1 {
+        &::after {
+            background: #FF953D;
+        }
+    }
 
     .status-l {
         .status-title {
@@ -507,7 +523,6 @@ const changeExecutionMethod = (stageIndex, value) => {
         }
 
         .status-sub {
-            margin-top: 2px;
             font-size: 14px;
         }
     }
@@ -515,7 +530,7 @@ const changeExecutionMethod = (stageIndex, value) => {
 
 .work-wrap {
     position: relative;
-    top: -12px;
+    top: -16px;
     padding: 0 12px 12px;
     z-index: 2;
     margin-bottom: 60px;
@@ -526,6 +541,10 @@ const changeExecutionMethod = (stageIndex, value) => {
     border-radius: 8px;
     padding: 14px 10px 10px 10px;
     box-shadow: 0 2px 8px rgba(15, 35, 52, 0.06);
+    border: 1px solid transparent;
+    &.status-0 {
+        border: 1px solid #FF953D;
+    }
 }
 
 .group-info {
@@ -560,17 +579,35 @@ const changeExecutionMethod = (stageIndex, value) => {
         line-height: 1.5;
     }
 }
-
-.stage-card {
+.stage-card + .stage-card {
     margin-top: 10px;
+}
+.stage-card {
 
     .stage-header {
         padding-bottom: 12px;
+        display: flex;
+        align-items: center;
+        gap: 5px;
 
         .stage-title {
             font-size: 16px;
             color: #000;
         }
+        .title-tag {
+            width: fit-content;
+            font-size: 12px;
+            height: 26px;
+            line-height: 26px;
+            color: #2199F8;
+            background: rgba(33, 153, 248, 0.1);
+            border-radius: 20px;
+            padding: 0 8px;
+        }
+        .tag-0 {
+            color: #FF953D;
+            background: rgba(255, 149, 61, 0.1);
+        }
     }
 
     .stage-info {
@@ -691,6 +728,31 @@ const changeExecutionMethod = (stageIndex, value) => {
     line-height: 21px;
 }
 
+.execute-action {
+    margin-top: 8px;
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    gap: 16px;
+    .action-item {
+        padding: 0 16px;
+        height: 32px;
+        line-height: 32px;
+        border-radius: 16px;
+        box-sizing: border-box;
+        font-size: 14px;
+        &.second {
+            background: #ffffff;
+            border: 0.5px solid rgba(153, 153, 153, 0.5);
+            color: #999999;
+        }
+        &.primary {
+            background: linear-gradient(180deg, #8ACBFF 0%, #2199F8 100%);
+            color: #ffffff;
+        }
+    }
+}
+
 .fixed-btn-wrap {
     display: flex;
     justify-content: center;