瀏覽代碼

fix: 基本信息增删改查,弹窗

lxf 1 天之前
父節點
當前提交
42eec2343f

+ 35 - 0
src/api/modules/basic_farm.js

@@ -0,0 +1,35 @@
+const config = require("../config")
+const url = config.base_dev_url + "v2/farm/basicInfo"
+
+module.exports = {
+    // 获取农场基本信息表单数据
+    fetchBasicFarmFormData: {
+        url: url + "/formData",
+        type: "get",
+    },
+    // 保存农场基本信息
+    saveBasicFarmInfo: {
+        url: url + "/save",
+        type: "post",
+    },
+    // 保存草稿
+    saveDraft: {
+        url: url + "/saveDraft",
+        type: "post",
+    },
+    // 新增自定义选项
+    addCustomOption: {
+        url: url + "/option/add",
+        type: "post",
+    },
+    // 删除自定义选项
+    deleteCustomOption: {
+        url: url + "/option/delete",
+        type: "get",
+    },
+    // 更新自定义选项
+    updateCustomOption: {
+        url: url + "/option/update",
+        type: "post",
+    },
+}

二進制
src/assets/img/home/checked-bg.png


+ 3 - 2
src/styles/common.scss

@@ -301,13 +301,14 @@ div {
     right: 0;
     display: flex;
     align-items: center;
-    justify-content: space-between;
+    // justify-content: space-between;
+    justify-content: center;
     padding: 10px 12px;
     background: #ffffff;
     box-shadow: 2px 2px 4.5px rgba(0, 0, 0, 0.4);
     z-index: 100;
     .bottom-btn {
-        padding: 10px 20px;
+        padding: 10px 40px;
         border-radius: 25px;
         text-align: center;
         &.secondary-btn {

+ 75 - 12
src/views/old_mini/agri_record/subPages/statusDetail.vue

@@ -5,19 +5,34 @@
         <div class="detail-content" :class="{ 'has-group': isLocked }">
             <!-- 橙色状态头部 -->
             <div class="status-header" :class="'status-' + status">
-                <div class="status-left">
+                <div class="status-left" v-show="status === 0">
                     <div class="status-text">
-                        <div class="status-icon">
+                        <!-- <div class="status-icon">
                             <el-icon :size="24" color="#fff">
                                 <Warning />
                             </el-icon>
-                        </div>
-                        <span v-show="status === 0">未执行</span>
-                        <span v-show="status === 1">已激活</span>
-                        <span v-show="status === 2">已完成</span>
-                        <span v-show="status === 3">未激活</span>
+                        </div> -->
+                        <span>未执行</span>
+                    </div>
+                    <div class="status-sub-text">执行时间已过去 7 天</div>
+                </div>
+                <div class="status-left" v-show="status === 1">
+                    <div class="status-text">
+                        <span>已激活</span>
+                    </div>
+                    <div class="status-sub-text">距离执行时间还差 一 天</div>
+                </div>
+                <div class="status-left" v-show="status === 2">
+                    <div class="status-text">
+                        <span>已完成</span>
                     </div>
-                    <div class="status-sub-text">距离执行时间还差一天</div>
+                    <div class="status-sub-text">执行时间:2025.05.06</div>
+                </div>
+                <div class="status-left" v-show="status === 3">
+                    <div class="status-text">
+                        <span>未激活</span>
+                    </div>
+                    <div class="status-sub-text">预计激活时间 2025.06.07</div>
                 </div>
             </div>
 
@@ -29,7 +44,7 @@
                             <div class="card-title">{{ prescriptionData.title }}</div>
                             <div class="type-tag">{{ prescriptionData.type }}</div>
                         </div>
-                        <div class="forward-link" @click="handleForward">转发处方</div>
+                        <!-- <div class="forward-link" @click="handleForward">转发处方</div> -->
                     </div>
 
                     <div class="card-info">
@@ -130,7 +145,7 @@
                         <div class="card-title-wrap">
                             <div class="card-title">执行操作</div>
                         </div>
-                        <div class="forward-link" @click="handleForward">转发操作指南</div>
+                        <!-- <div class="forward-link" @click="handleForward">转发操作指南</div> -->
                     </div>
                     <div class="video-wrap">
                         <photo-provider :photo-closable="true">
@@ -202,6 +217,11 @@
                     </photo-provider>
                 </div>
              </div>
+
+             <!-- 我已执行 -->
+             <div class="bottom-btn-wrap">
+                <div class="bottom-btn" @click="selectExecuteTime">我已执行</div>
+             </div>
         </div>
 
         <!-- 二维码弹窗 -->
@@ -230,6 +250,9 @@
         <!-- 处方卡片 -->
         <detail-dialog ref="detailDialogRef" />
     </div>
+
+    <!-- 确认执行时间 -->
+    <calendar v-model:show="showCalendar" title="执行日期" @confirm="onConfirmExecuteTime" :min-date="minDate" :max-date="maxDate" />
 </template>
 
 <script setup>
@@ -242,7 +265,8 @@ import { Warning } from "@element-plus/icons-vue";
 import upload from "@/components/upload";
 import detailDialog from "@/components/detailDialog.vue";
 import MapInfo from "@/views/old_mini/agri_record/components/mapInfo.vue";
-import { Popup } from "vant";
+import { Popup, Calendar } from "vant";
+import { formatDate } from "@/common/commonFun";
 
 const router = useRouter();
 const route = useRoute();
@@ -267,6 +291,19 @@ const handleClose = () => {
 const guideSrc = ref("https://birdseye-img-ali-cdn.sysuimars.com/2d75eb9c-822a-46e1-a5da-8ac0823619bb/a9e5dcdf-ab88-4098-8a1a-51873c9afe2d/DJI_202511290800_001_a9e5dcdf-ab88-4098-8a1a-51873c9afe2d/DJI_20251129081259_0112_V_code-ws0gefzht1u7.jpeg?x-oss-process=image/resize,p_50/format,webp/quality,q_50");
 const groupSrc = ref(require("@/assets/img/home/qrcode.png"));
 
+const showCalendar = ref(false);
+const minDate = ref(new Date(2025, 0, 1));
+const maxDate = ref(new Date());
+
+const onConfirmExecuteTime = (date) => {
+    showCalendar.value = false;
+    console.log(formatDate(date) );
+};
+/* 选择执行时间 */
+const selectExecuteTime = () => {
+    showCalendar.value = true;
+};
+
 const handleForward = async () => {
     // 转发处方:复制处方链接到剪贴板
     const url = `${window.location.origin}/#/prescription_page?id=${prescriptionData.value.id}`;
@@ -798,9 +835,15 @@ const isLocked = ref(false);
 
     .video-wrap {
         padding-top: 4px;
+        ::v-deep {
+            .PhotoConsumer {
+                width: 100%;
+            }
+        }
         .video-img {
             width: 100%;
-            height: 100%;
+            // height: 100%;
+            height: 146px;
             object-fit: cover;
             border-radius: 5px;
         }
@@ -844,6 +887,26 @@ const isLocked = ref(false);
     padding-top: 12px;
 }
 
+.bottom-btn-wrap {
+    position: fixed;
+    bottom: 0;
+    left: 0;
+    width: 100%;
+    height: 60px;
+    background: #fff;
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    .bottom-btn {
+        height: 40px;
+        line-height: 40px;
+        padding: 0 26px;
+        border-radius: 20px;
+        font-size: 14px;
+        background: #2199F8;
+        color: #fff;
+    }
+}
 .group-wrap {
     position: fixed;
     bottom: 30px;

+ 2 - 2
src/views/old_mini/home/components/farmInfoPopup.vue

@@ -33,10 +33,10 @@
                     <field v-model="farmInfo.tel" readonly label="联系电话" />
                     <field class="address-field" v-model="farmInfo.address" readonly label="农场位置" />
                     
-                    <field v-model="farmInfo.userType" readonly label="基地类型">
+                    <field v-model="farmInfo.baseType" readonly label="基地类型">
                         <template #input>
                             <!-- <span>{{ userTypeMap[farmInfo.userType] }}</span> -->
-                            <span>农业企业</span>
+                            <span>{{ farmInfo?.baseType }}</span>
                         </template>
                     </field>
                     <checkbox

+ 497 - 109
src/views/old_mini/home/subPages/prescriptionPage.vue

@@ -6,28 +6,66 @@
             <div class="title-desc">请认真核对一下内容</div>
         </div>
         <div class="prescription-box">
-            <div class="box-title">
+            <!-- <div class="box-title">
                 <img src="@/assets/img/home/label-icon.png" />
                 农场情况
-            </div>
+            </div> -->
             <div class="box-content">
-                <div class="box-item" v-for="(group, i) in productList" :key="i">
+                <div class="box-item">
                     <div class="item-name">
-                        <span class="required-icon">*</span>
-                        <span>{{ group.name }}</span>
+                        <span>请选择您的果园土壤类型</span>
                     </div>
-                    <div class="tips">{{ group.subName }}</div>
+                    <div class="tips">土壤类型确认最佳施肥策略</div>
                     <div class="item-checkbox">
-                        <el-radio-group v-model="group.checked">
-                            <el-radio-button
-                                v-for="(item, index) in group.items"
-                                :key="index"
-                                :label="item.name"
-                                :value="item.name"
-                            />
+                        <el-radio-group v-model="basicForm.soilTypes">
+                            <el-radio-button v-for="(item, index) in basicFarmFormData.soilTypes" :key="index"
+                                :label="item.name" :value="item.code" />
                         </el-radio-group>
                     </div>
                 </div>
+                <div class="box-item">
+                    <div class="item-name">
+                        <span>请选择您的灌溉方式</span>
+                        <span class="sub-name"> (可多选)</span>
+                    </div>
+                    <div class="tips">灌溉方式确认药肥最佳配比</div>
+                    <div class="item-checkbox">
+                        <div class="tag-group add-tag-group">
+                            <div class="tag-item" :class="{ self: item.custom === true, selected: item.selected }"
+                                @click="handleSelect('irrigationMethods', idx, item.custom)"
+                                v-for="(item, idx) in basicFarmFormData.irrigationMethods" :key="'ce-' + idx">
+                                <span class="text">{{ item.name }}</span>
+                            </div>
+                            <div class="tag-item last-add" @click="handleAdd('irrigationMethods')"><el-icon class="add-icon">
+                                    <Plus />
+                                </el-icon>其它方式</div>
+                        </div>
+                    </div>
+                </div>
+                <div class="box-item">
+                    <div class="item-name">
+                        <span>请选择您的农机设备</span>
+                        <span class="sub-name"> (可多选)</span>
+                    </div>
+                    <div class="tips">农闲时可将闲置农机加入农事服务联盟,获取额外服务收益</div>
+                    <div class="item-checkbox">
+                        <div class="tag-group add-tag-group">
+                            <div class="tag-item" :class="{ self: item.custom === true, selected: item.selected }"
+                                @click="handleMachinerySelect('machinery', idx, item)"
+                                v-for="(item, idx) in basicFarmFormData.machinery" :key="'nj-' + idx">
+                                <span class="text">{{ item.name }}</span>
+                                <span class="quantity-text" v-show="item.quantity">{{ item.quantity }}</span>
+                            </div>
+                            <div class="tag-item last-add" @click="handleMachineryAdd('machinery', item)"><el-icon class="add-icon">
+                                    <Plus />
+                                </el-icon>其它设备</div>
+                        </div>
+                        <!-- <el-checkbox-group v-model="basicForm.machineryWithQuantity">
+                            <el-checkbox-button v-for="(item, index) in basicFarmFormData.machinery" :key="index"
+                                :label="item.name" :value="item.code" />
+                        </el-checkbox-group> -->
+                    </div>
+                </div>
                 <!-- 农场规模 -->
                 <div class="farm-scale-header">
                     <div class="farm-scale-title">请填写您的农场规模</div>
@@ -36,103 +74,112 @@
                 <div class="farm-scale-form">
                     <div class="farm-scale-item">
                         <label class="farm-scale-label">一般长工人数</label>
-                        <el-input
-                            v-model="farmScale.longTermWorker"
-                            placeholder="请输入人数"
-                            class="farm-scale-input"
-                        >
+                        <el-input v-model="farmScale.regularWorkerCount" placeholder="请输入人数" class="farm-scale-input">
                             <template #append>人</template>
                         </el-input>
                     </div>
                     <div class="farm-scale-item">
                         <label class="farm-scale-label">植保技能人数</label>
-                        <el-input
-                            v-model="farmScale.plantProtection"
-                            placeholder="请输入人数"
-                            class="farm-scale-input"
-                        >
+                        <el-input v-model="farmScale.plantProtectionWorkerCount" placeholder="请输入人数" class="farm-scale-input">
                             <template #append>人</template>
                         </el-input>
                     </div>
                     <div class="farm-scale-item">
                         <label class="farm-scale-label">剪枝技能人数</label>
-                        <el-input
-                            v-model="farmScale.pruning"
-                            placeholder="请输入人数"
-                            class="farm-scale-input"
-                        >
+                        <el-input v-model="farmScale.pruningWorkerCount" placeholder="请输入人数" class="farm-scale-input">
+                            <template #append>人</template>
+                        </el-input>
+                    </div>
+                    <div class="farm-scale-item">
+                        <label class="farm-scale-label">农忙时可调度人数</label>
+                        <el-input v-model="farmScale.tempDispatchWorkerCount" placeholder="请输入人数" class="farm-scale-input">
                             <template #append>人</template>
                         </el-input>
                     </div>
                 </div>
-                <div class="box-item" v-for="(group, i) in farmScaleList" :key="i">
+                <div class="box-item">
                     <div class="item-name">
-                        <span class="required-icon">*</span>
-                        <span>{{ group.name }}</span>
+                        <span>希望专家帮助解决的种植难题</span>
+                        <span class="sub-name"> (可多选)</span>
                     </div>
-                    <div class="tips">{{ group.subName }}</div>
                     <div class="item-checkbox">
-                        <el-radio-group v-model="group.checked">
-                            <el-radio-button
-                                v-for="(item, index) in group.items"
-                                :key="index"
-                                :label="item.name"
-                                :value="item.name"
-                            />
-                        </el-radio-group>
+                        
+                        <div class="tag-group add-tag-group">
+                            <div class="tag-item" :class="{ self: item.custom === true, selected: item.selected }"
+                                @click="handleSelect('improvementAreas', idx, item.custom)"
+                                v-for="(item, idx) in basicFarmFormData.improvementAreas" :key="'wt-' + idx">
+                                <span class="text">{{ item.name }}</span>
+                            </div>
+                        </div>
+                        <!-- <el-checkbox-group v-model="basicForm.improvementAreas">
+                            <el-checkbox-button v-for="(item, index) in basicFarmFormData.improvementAreas" :key="index"
+                                :label="item.name" :value="item.code" />
+                        </el-checkbox-group> -->
                     </div>
                 </div>
-            </div>
-        </div>
-        
-        <!-- <div class="prescription-box">
-            <div class="box-title">
-                <img src="@/assets/img/home/label-icon.png" />
-                过往出现过的灾害 (多选)
-            </div>
-            <div class="box-content">
-                <div class="box-item" style="padding-top: 0">
+                <div class="box-item">
+                    <div class="item-name">
+                        <span>您最希望得到哪位荔枝专家的农事处方</span>
+                    </div>
                     <div class="item-checkbox">
-                        <el-checkbox-group v-model="outputVal">
-                            <el-checkbox-button v-for="(item, index) in outputList" :key="index" :value="item.name">
-                                {{ item.name }}
-                            </el-checkbox-button>
-                        </el-checkbox-group>
+                        <!-- <div class="tag-group add-tag-group">
+                            <div class="tag-item" :class="{ self: item.custom === true, selected: item.selected }"
+                                @click="handleSelect('expertOptions', idx, item.custom)"
+                                v-for="(item, idx) in basicFarmFormData.expertOptions" :key="'zj-' + idx">
+                                <span class="text">{{ item.name }}</span>
+                            </div>
+                        </div> -->
+                            <el-radio-group v-model="basicForm.expertOptions">
+                                <el-radio-button v-for="(item, index) in basicFarmFormData.expertOptions" :key="index"
+                                    :label="item.name" :value="item.code" />
+                            </el-radio-group>
+                        <!-- <el-checkbox-group v-model="basicForm.improvementAreas">
+                            <el-checkbox-button v-for="(item, index) in basicFarmFormData.improvementAreas" :key="index"
+                                :label="item.name" :value="item.code" />
+                        </el-checkbox-group> -->
                     </div>
                 </div>
             </div>
-            <div class="disaster-desc-box">
-                <span>其它异常</span>
-                <el-input
-                    v-model="disasterDesc"
-                    :autosize="{ minRows: 2, maxRows: 4 }"
-                    type="textarea"
-                    placeholder="请简单描述一下异常情况"
-                />
-            </div>
-        </div> -->
+        </div>
 
         <!-- 按钮 -->
         <div class="custom-bottom-fixed-btns">
-            <div class="bottom-btn secondary-btn" @click="handlePage">跳过</div>
+            <!-- <div class="bottom-btn secondary-btn" @click="handlePage">跳过</div> -->
             <div class="bottom-btn primary-btn" @click="handlePage">确认信息</div>
         </div>
     </div>
+
+    <popup class="add-tag-popup" round v-model:show="showAddPopup">
+        <div class="tag-item" v-if="addTypeKey !== 'machinery' || (addTypeKey === 'machinery' && isMachineSelf)">
+            <div class="popup-title">编辑<span class="name-text">{{ formNameObj[addTypeKey] }}</span><span class="ml-2">名称</span></div>
+            <el-input class="popup-input" v-model="popupInputVal" :placeholder="'请输入' + formNameObj[addTypeKey]" size="large" />
+        </div>
+        <div class="device-item" v-if="addTypeKey === 'machinery'">
+            <div class="popup-title">编辑
+                <span class="name-text" v-show="isMachineSelf">{{ formNameObj[addTypeKey] }}</span>
+                <span class="name-text" v-show="!isMachineSelf">{{ popupInputVal }}</span>
+                <span class="ml-2">数量</span>
+            </div>
+            <el-input class="popup-input" v-model="popupInputNum" :placeholder="'请输入' + formNameObj[addTypeKey]+'数量'" size="large">
+                <template #append>{{ machineryUnit || '辆/架' }}</template>
+            </el-input>
+        </div>
+        <div class="popup-button">
+            <div class="delete" v-if="isEditPopup" @click="handleDelete">删除</div>
+            <div class="cancel" v-else @click="showAddPopup = false">取消</div>
+            <div @click="handleConfirm">确认</div>
+        </div>
+    </popup>
 </template>
 
 <script setup>
 import { ref, onActivated } from "vue";
+import { ElMessage } from "element-plus";
 import { useRouter, useRoute } from "vue-router";
+import { Popup } from "vant";
 const router = useRouter();
 const route = useRoute();
-const productList = ref([
-    { name: "请选择您的果园土壤类型", subName:'土壤类型确认最佳施肥策略',items: [{ name: "砂质土" }, { name: "黏质土" }, { name: "壤土" }] },
-    { name: "请选择您的灌溉方式",subName:'处方执行方式,根据您的灌溉设施确定', items: [{ name: "人工浇灌" }, { name: "人工喷灌" }, { name: "微喷灌" },{name:'滴灌'}] },
-    { name: "请选择您的农机设备",subName:'农机可以加入农机租赁库,在农闲时获取额外收益', items: [{ name: "植保无人机" }, { name: "骑乘式割草机" },{name:'乘坐式喷药机'},{name:'果园运输车'},{name:'果园碎枝机'},{name:'农用吊运无人机'}] },
-]);
-const farmScaleList = ref([
-    { name: "您最想改善的方向",items: [{ name: "病虫防治" }, { name: "树势不良" }, { name: "土壤板结" },{name:'保花保果'},{name:'品种改良'},{name:'树体剪枝'},{name:'果园规划'}] },
-]);
+
 const outputList = ref([
     { name: "低温冻害" },
     { name: "干旱" },
@@ -145,28 +192,149 @@ const outputVal = ref([]);
 const disasterDesc = ref("");
 // 农场规模
 const farmScale = ref({
-    longTermWorker: "",
-    plantProtection: "",
-    pruning: "",
+    regularWorkerCount: "",
+    plantProtectionWorkerCount: "",
+    pruningWorkerCount: "",
+    tempDispatchWorkerCount: "",
 });
 // 初始化默认选中第一项
 onActivated(() => {
-    // outputVal.value = outputList.value.length >= 2
-    //     ? [outputList.value[0].name, outputList.value[1].name]
-    //     : outputList.value.length === 1
-    //     ? [outputList.value[0].name]
-    //     : []
-    if (route.query.speciesName === '籼稻') {
-        productList.value[0].items = [{ name: "黏质土" }, { name: "壤土" }, { name: "冲积土" }];
-        productList.value[1].items = [{ name: "漫灌" }, { name: "间歇灌溉" }, { name: "喷灌" }];
-    }
+    getBasicFarmFormData();
     // 为 productList 的每个 group 设置默认选中第一项
-    productList.value.forEach((group) => {
-        if (group.items && group.items.length > 0 && !group.checked) {
-            group.checked = group.items[0].name;
-        }
+});
+
+const basicForm = ref({
+    soilTypes: "",
+    irrigationMethods: [],
+    machineryWithQuantity: [],
+    improvementAreas: [],
+});
+
+const basicFarmFormData = ref({});
+const getBasicFarmFormData = () => {
+    VE_API.basic_farm.fetchBasicFarmFormData({ farmId: 766 }).then(({ data }) => {
+        basicFarmFormData.value = data;
     });
+}
+
+const formNameObj = ref({
+    irrigationMethods: '灌溉方式',
+    crops: '作物',
+    machinery: '农机设备',
+    improvementAreas: '希望专家帮助解决的种植难题',
+    soilTypes: '土壤类型',
 });
+const showAddPopup = ref(false);
+const addTypeKey = ref("");
+const popupInputVal = ref("");
+// 农机设备数量
+const popupInputNum = ref("");
+const machineryUnit = ref("");
+const isEditPopup = ref(false);
+const currentEditIndex = ref(-1);
+function handleAdd(type) {
+    isEditPopup.value = false;
+    showAddPopup.value = true;
+    addTypeKey.value = type;
+    popupInputVal.value = "";
+    popupInputNum.value = "";
+}
+
+function handleMachineryAdd(type) {
+    handleAdd(type);
+    isMachineSelf.value = true;
+}
+
+function handleSelect(type, index, custom) {
+    if (custom === true) {
+        showAddPopup.value = true;
+        isEditPopup.value = true;
+        addTypeKey.value = type;
+        popupInputVal.value = basicFarmFormData.value[type][index].name;
+        currentEditIndex.value = index;
+    }
+    basicFarmFormData.value[type][index].selected = !basicFarmFormData.value[type][index].selected;
+}
+
+// 农机设备
+const isMachineSelf = ref(false);
+function handleMachinerySelect(type, index, item) {
+    showAddPopup.value = true;
+    isMachineSelf.value = item.custom;
+    isEditPopup.value = item.selected || item.custom;
+    addTypeKey.value = type;
+    popupInputVal.value = item.name;
+    popupInputNum.value = item.quantity;
+    machineryUnit.value = item.unit;
+    currentEditIndex.value = index;
+}
+
+function handleConfirm() {
+    if (addTypeKey.value === 'machinery') {
+        if (!popupInputNum.value.trim()) {
+            return;
+        }
+        if (isMachineSelf.value && !isEditPopup.value) {
+            
+            saveCustomOption(popupInputVal.value);
+        } else {
+            basicFarmFormData.value[addTypeKey.value][currentEditIndex.value].name = popupInputVal.value;
+            basicFarmFormData.value[addTypeKey.value][currentEditIndex.value].quantity = popupInputNum.value;
+            basicFarmFormData.value[addTypeKey.value][currentEditIndex.value].selected = true;
+            // 更新名称
+            console.log('更新名称', basicFarmFormData.value[addTypeKey.value][currentEditIndex.value]);
+            updateCustomOption(popupInputVal.value, basicFarmFormData.value[addTypeKey.value][currentEditIndex.value].id);
+        }
+        currentEditIndex.value = -1;
+        isEditPopup.value = false;
+        showAddPopup.value = false;
+        return;
+    }
+    if (!popupInputVal.value.trim()) {
+        return;
+    }
+    if (isEditPopup.value) {
+        basicFarmFormData.value[addTypeKey.value][currentEditIndex.value].name = popupInputVal.value;
+        currentEditIndex.value = -1;
+        isEditPopup.value = false;
+        showAddPopup.value = false;
+        updateCustomOption(popupInputVal.value, basicFarmFormData.value[addTypeKey.value][currentEditIndex.value].id);
+        return;
+    }
+    basicFarmFormData.value[addTypeKey.value].push({ name: popupInputVal.value, code: popupInputVal.value, selected: true, custom: true });
+    saveCustomOption(popupInputVal.value);
+
+    showAddPopup.value = false;
+}
+
+const configTypeObj = {
+    irrigationMethods: 'IRRIGATION',
+    machinery: 'MACHINERY',
+}
+function saveCustomOption(name) {
+    VE_API.basic_farm.addCustomOption({ configType: configTypeObj[addTypeKey.value], name: name }).then(({ data }) => {
+        console.log(data);
+        ElMessage.success('保存成功');
+        basicFarmFormData.value[addTypeKey.value].push({ id: data.id, name: popupInputVal.value, code: popupInputVal.value, selected: true, custom: true, quantity: popupInputNum.value });
+    });
+}
+
+function updateCustomOption(name, id) {
+    VE_API.basic_farm.updateCustomOption({ id, configType: configTypeObj[addTypeKey.value], name: name }).then(({ data }) => {
+        console.log(data);
+        ElMessage.success('保存成功');
+    });
+}
+
+function handleDelete() {
+    const option = basicFarmFormData.value[addTypeKey.value][currentEditIndex.value]
+    VE_API.basic_farm.deleteCustomOption({ optionId: option.id || option.code }).then(({ data }) => {
+        ElMessage.success('删除成功');
+        basicFarmFormData.value[addTypeKey.value].splice(currentEditIndex.value, 1);
+        currentEditIndex.value = -1;
+        showAddPopup.value = false;
+    });
+}
 
 const goBack = () => {
     // router.go(-1);
@@ -175,7 +343,7 @@ const goBack = () => {
 
 const handlePage = () => {
 
-    if(route.query.type === 'farmer'){
+    if (route.query.type === 'farmer') {
         router.push('/agri_record')
         return
     }
@@ -184,14 +352,14 @@ const handlePage = () => {
     const queryParams = {
         containerId: route.query.containerId,
     };
-    
+
     // 如果存在 from 参数,继续传递
     if (route.query.from) {
         queryParams.from = route.query.from;
     }
-    
+
     // 传递所有农场相关的参数,以便在 agricultural_plan 页面创建农场
-    const farmParams = ['wkt', 'speciesId', 'containerId', 'agriculturalCreate', 'geom', 'address', 'mu', 'name', 'fzr', 'tel', 'defaultFarm', 'typeId', 'speciesName','userType'];
+    const farmParams = ['wkt', 'speciesId', 'containerId', 'agriculturalCreate', 'geom', 'address', 'mu', 'name', 'fzr', 'tel', 'defaultFarm', 'typeId', 'speciesName', 'userType'];
     farmParams.forEach(key => {
         if (route.query[key] !== undefined) {
             queryParams[key] = route.query[key];
@@ -212,26 +380,31 @@ const handlePage = () => {
     overflow: auto;
     box-sizing: border-box;
     background: linear-gradient(to left, #e6f2ff, #8fc5fe);
+
     .prescription-title {
         padding: 16px 14px;
         background: url("@/assets/img/home/page-bg.png") no-repeat bottom right / 149px 116px;
         background-position-y: 30px;
+
         img {
             width: 24px;
         }
+
         .title-name {
             font-size: 22px;
             color: #2e2e2e;
             text-shadow: 0px 1px 1px rgba(0, 0, 0, 0.05);
-            font-weight: 800;
+            font-weight: 500;
             padding: 21px 0 4px 6px;
         }
+
         .title-desc {
             font-size: 14px;
             color: rgba(49, 49, 49, 0.56);
             padding-left: 6px;
         }
     }
+
     .prescription-box {
         background: #ffffff;
         box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.1);
@@ -239,6 +412,7 @@ const handlePage = () => {
         margin: 0 10px 10px;
         box-sizing: border-box;
         padding-bottom: 10px;
+
         .box-title {
             margin: 0 10px;
             box-sizing: border-box;
@@ -247,43 +421,183 @@ const handlePage = () => {
             font-size: 18px;
             color: #222222;
             padding: 15px 0 10px;
+
             img {
                 width: 14px;
                 height: 9px;
             }
         }
+
+        .pt-16 {
+            padding-top: 16px;
+        }
+
         .box-content {
             padding: 0 10px;
+
             .box-item {
-                padding-top: 10px;
+                padding-top: 16px;
+
                 .item-name {
                     display: flex;
                     align-items: center;
-                    font-size: 15px;
+                    font-size: 14px;
                     color: rgba(0, 0, 0, 0.9);
                     font-weight: 500;
+
                     .required-icon {
                         color: #ff0000;
                         font-size: 16px;
                         margin-right: 4px;
                     }
+
+                    .sub-name {
+                        font-size: 12px;
+                        font-weight: 400;
+                    }
                 }
-                .tips{
-                    margin-left: 10px;
+
+                .tips {
+                    // margin-left: 10px;
                     font-size: 12px;
                     color: rgba(0, 0, 0, 0.4);
                 }
+
                 .item-checkbox {
+                    .tag-group {
+                        display: grid;
+                        grid-template-columns: repeat(3, 1fr);
+                        gap: 0 7px;
+                        font-size: 14px;
+
+                        .tag-item {
+                            margin-top: 10px;
+                            position: relative;
+                            border-radius: 4px;
+                            color: #2199f8;
+                            // padding: 0 4px;
+                            box-sizing: border-box;
+                            // min-width: 26vw;
+                            height: 40px;
+                            text-align: center;
+                            line-height: 40px;
+                            cursor: pointer;
+                            transition: all 0.3s;
+                            .quantity-text {
+                                font-size: 10px;
+                                color: #fff;
+                                position: absolute;
+                                right: -7px;
+                                top: -7px;
+                                width: 14px;
+                                text-align: center;
+                                line-height: 14px;
+                                height: 14px;
+                                border-radius: 50%;
+                                background: #2199F8;
+                            }
+
+                            .text {
+                                display: inline-flex;
+                                align-items: center;
+                            }
+
+                            .edit-icon {
+                                margin-left: 8px;
+                            }
+
+                            .del-icon {
+                                position: absolute;
+                                right: -8px;
+                                top: -8px;
+                                background: #2199F8;
+                                border-radius: 50%;
+                                width: 16px;
+                                height: 16px;
+                                font-size: 10px;
+                                display: flex;
+                                align-items: center;
+                                justify-content: center;
+                                color: #fff;
+                            }
+
+                            &.selected {
+                                border: 1px solid #2199F8;
+                                background: #E8F5FF;
+                                color: #2199F8;
+                                &::after {
+                                    content: "";
+                                    position: absolute;
+                                    z-index: 9;
+                                    bottom: -1px;
+                                    right: 0;
+                                    width: 18px;
+                                    height: 13px;
+                                    background: url("@/assets/img/home/checked-bg.png") no-repeat bottom right / 18px 13px;
+                                }
+                            }
+                        }
+
+                        &.add-tag-group {
+                            .tag-item {
+                                color: #000000;
+                                background: rgba(241, 241, 241, 0.12);
+                                border: 1px solid #EBEBEB;
+                                cursor: pointer;
+
+                                &.self {
+                                    border: 1px solid #2199F8;
+                                    background: #E8F5FF;
+                                    color: #2199F8;
+                                    &::after {
+                                        content: "";
+                                        position: absolute;
+                                        z-index: 9;
+                                        bottom: -1px;
+                                        right: 0;
+                                        width: 18px;
+                                        height: 13px;
+                                        background: url("@/assets/img/home/checked-bg.png") no-repeat bottom right / 18px 13px;
+                                    }
+                                }
+
+                                &.selected {
+                                    border: 1px solid #2199F8;
+                                    background: #E8F5FF;
+                                    color: #2199F8;
+                                }
+
+                                &.last-add {
+                                    // background: #F7F7F7;
+                                    // color: #343434;
+                                    // border: none;
+                                    display: flex;
+                                    align-items: center;
+                                    justify-content: center;
+                                    cursor: pointer;
+
+                                    .add-icon {
+                                        font-size: 14px;
+                                        font-weight: bold;
+                                        margin-right: 3px;
+                                    }
+                                }
+                            }
+                        }
+                    }
+
                     ::v-deep {
+
                         .el-radio-button,
                         .el-checkbox-button {
                             margin: 10px 0 0 7px;
+
                             .el-radio-button__inner,
                             .el-checkbox-button__inner {
                                 border: none;
                                 border-radius: 6px;
                                 // padding: 13px 21px;
-                                height: 43px;
+                                height: 40px;
                                 width: 107px;
                                 display: flex;
                                 align-items: center;
@@ -293,19 +607,20 @@ const handlePage = () => {
                                 background: rgba(241, 241, 241, 0.12);
                                 font-weight: 400;
                             }
+
                             &.is-active,
                             &.is-checked {
                                 &::after {
                                     content: "";
                                     position: absolute;
                                     z-index: 9;
-                                    bottom: 0;
+                                    bottom: -0.5px;
                                     right: 0;
                                     width: 18px;
-                                    height: 16px;
-                                    background: url("@/assets/img/home/checked-bg.png") no-repeat bottom right / 18px
-                                        16px;
+                                    height: 13px;
+                                    background: url("@/assets/img/home/checked-bg.png") no-repeat bottom right / 18px 13px;
                                 }
+
                                 .el-radio-button__inner,
                                 .el-checkbox-button__inner {
                                     background: rgba(33, 153, 248, 0.1) !important;
@@ -314,8 +629,9 @@ const handlePage = () => {
                                     box-shadow: none;
                                 }
                             }
+
                             &.is-active {
-                                .el-radio-button__original-radio:not(:disabled) + .el-radio-button__inner {
+                                .el-radio-button__original-radio:not(:disabled)+.el-radio-button__inner {
                                     background: rgba(33, 153, 248, 0.1) !important;
                                     color: #2199f8 !important;
                                     border: 1px solid #2199f8 !important;
@@ -323,8 +639,9 @@ const handlePage = () => {
                                     font-weight: 500;
                                 }
                             }
+
                             &.is-checked {
-                                .el-checkbox-button__original-checkbox:not(:disabled) + .el-checkbox-button__inner {
+                                .el-checkbox-button__original-checkbox:not(:disabled)+.el-checkbox-button__inner {
                                     background: rgba(33, 153, 248, 0.1) !important;
                                     color: #2199f8 !important;
                                     border: 1px solid #2199f8 !important;
@@ -334,44 +651,57 @@ const handlePage = () => {
                             }
                         }
 
-                        .el-radio-button:nth-child(3n-2){
+                        .el-radio-button:nth-child(3n-2) {
                             margin-left: 0;
                         }
                     }
                 }
             }
         }
+
         /* 农场规模(与农场情况同一卡片内) */
         .farm-scale-header {
             margin-top: 16px;
+
             .farm-scale-title {
                 font-size: 15px;
                 font-weight: 500;
                 color: rgba(0, 0, 0, 0.9);
             }
+
             .farm-scale-desc {
                 font-size: 13px;
                 color: rgba(0, 0, 0, 0.4);
             }
         }
+
         .farm-scale-form {
             margin-top: 10px;
+            border: 0.5px solid rgba(33, 153, 248, 0.5);
+            border-radius: 8px;
+            padding: 10px;
+
             .farm-scale-item {
                 display: flex;
                 align-items: center;
                 margin-bottom: 14px;
+
                 &:last-child {
                     margin-bottom: 0;
                 }
+
                 .farm-scale-label {
                     flex-shrink: 0;
-                    width: 110px;
+                    width: 116px;
                     font-size: 14px;
                     color: rgba(0, 0, 0, 0.9);
-                    margin-right: 12px;
+                    text-align: right;
+                    margin-right: 10px;
                 }
+
                 .farm-scale-input {
                     flex: 1;
+
                     ::v-deep .el-input-group__append {
                         padding: 0 12px;
                         background: #f5f7fa;
@@ -379,6 +709,7 @@ const handlePage = () => {
                         border-color: #dcdfe6;
                         border-radius: 0 4px 4px 0;
                     }
+
                     ::v-deep .el-input__inner {
                         border-radius: 4px 0 0 4px;
                     }
@@ -386,10 +717,12 @@ const handlePage = () => {
             }
         }
     }
+
     .disaster-desc-box {
         padding: 10px;
         display: flex;
         align-items: center;
+
         span {
             font-size: 14px;
             color: rgba(0, 0, 0, 0.9);
@@ -397,4 +730,59 @@ const handlePage = () => {
         }
     }
 }
+
+
+.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>