|
@@ -1,494 +1,328 @@
|
|
|
<template>
|
|
<template>
|
|
|
- <popup
|
|
|
|
|
- v-model:show="showValue"
|
|
|
|
|
- round
|
|
|
|
|
- class="farm-info-popup"
|
|
|
|
|
- :close-on-click-overlay="true"
|
|
|
|
|
- teleport="body"
|
|
|
|
|
- >
|
|
|
|
|
- <!-- 第一步:农场信息填写 -->
|
|
|
|
|
- <template v-if="currentStep === 1">
|
|
|
|
|
- <!-- 标题 -->
|
|
|
|
|
- <div class="popup-title">{{ $t('完善以下信息,生成智能种植方案') }}</div>
|
|
|
|
|
-
|
|
|
|
|
- <!-- 表单区域 -->
|
|
|
|
|
- <el-form ref="formRef" :model="formData" :rules="rules" class="farm-form">
|
|
|
|
|
- <!-- 农场位置 -->
|
|
|
|
|
- <el-form-item :label="$t('农场位置')" prop="address">
|
|
|
|
|
- <el-input v-model="formData.address" :placeholder="$t('请输入农场位置')" clearable />
|
|
|
|
|
- </el-form-item>
|
|
|
|
|
-
|
|
|
|
|
- <!-- 农场品种 -->
|
|
|
|
|
- <el-form-item :label="$t('农场品种')" prop="speciesId">
|
|
|
|
|
- <el-select
|
|
|
|
|
- v-model="formData.speciesId"
|
|
|
|
|
- :placeholder="$t('请选择')"
|
|
|
|
|
- @change="handleSpecieChange"
|
|
|
|
|
- >
|
|
|
|
|
- <el-option
|
|
|
|
|
- v-for="item in specieList"
|
|
|
|
|
- :key="item.id"
|
|
|
|
|
- :label="item.name"
|
|
|
|
|
- :value="item.id"
|
|
|
|
|
- />
|
|
|
|
|
- </el-select>
|
|
|
|
|
- </el-form-item>
|
|
|
|
|
-
|
|
|
|
|
- <!-- 农场品类 -->
|
|
|
|
|
- <el-form-item :label="$t('农场品类')" prop="typeIds">
|
|
|
|
|
- <el-select
|
|
|
|
|
- v-model="formData.typeIds"
|
|
|
|
|
- multiple
|
|
|
|
|
- collapse-tags
|
|
|
|
|
- :placeholder="$t('请选择')"
|
|
|
|
|
- :disabled="!formData.speciesId"
|
|
|
|
|
- @change="handleFruitsChange"
|
|
|
|
|
- >
|
|
|
|
|
- <el-option
|
|
|
|
|
- v-for="item in fruitsList"
|
|
|
|
|
- :key="item.id"
|
|
|
|
|
- :label="item.name"
|
|
|
|
|
- :value="item.id"
|
|
|
|
|
- />
|
|
|
|
|
- </el-select>
|
|
|
|
|
- </el-form-item>
|
|
|
|
|
-
|
|
|
|
|
- <!-- 农场亩数 -->
|
|
|
|
|
- <el-form-item :label="$t('农场亩数')" prop="mu">
|
|
|
|
|
- <el-input v-model="formData.mu" :placeholder="$t('请输入')" type="number">
|
|
|
|
|
- <template #suffix>
|
|
|
|
|
- <span class="unit">{{ $t('亩') }}</span>
|
|
|
|
|
|
|
+ <Popup v-model:show="show" :overlay-style="{ zIndex: 9999 }" teleport="body" class="farm-info-popup" closeable>
|
|
|
|
|
+ <div class="popup-content-box">
|
|
|
|
|
+ <div class="popup-title">{{ $t('基本信息') }}</div>
|
|
|
|
|
+ <div class="popup-content">
|
|
|
|
|
+ <!-- <div class="map-box">
|
|
|
|
|
+ <div class="map" ref="mapContainer"></div>
|
|
|
|
|
+ </div> -->
|
|
|
|
|
+ <cell-group inset class="cell-group">
|
|
|
|
|
+ <field v-model="farmInfo.subjectName" :label="$t('农场名称')" />
|
|
|
|
|
+ <field readonly :label="$t('农场面积')">
|
|
|
|
|
+ <template #input>
|
|
|
|
|
+ <span>{{ farmInfo.farmArea }}亩</span>
|
|
|
</template>
|
|
</template>
|
|
|
- </el-input>
|
|
|
|
|
- </el-form-item>
|
|
|
|
|
-
|
|
|
|
|
- <!-- 农场名称 -->
|
|
|
|
|
- <el-form-item :label="$t('农场名称')" prop="name">
|
|
|
|
|
- <el-input
|
|
|
|
|
- v-model="formData.name"
|
|
|
|
|
- :placeholder="$t('请输入农场名称')"
|
|
|
|
|
- clearable
|
|
|
|
|
- @input="handleNameInput"
|
|
|
|
|
- />
|
|
|
|
|
- </el-form-item>
|
|
|
|
|
- </el-form>
|
|
|
|
|
- </template>
|
|
|
|
|
-
|
|
|
|
|
- <!-- 第二步:物候期起始时间填写 -->
|
|
|
|
|
- <template v-else>
|
|
|
|
|
- <!-- 提示文字 -->
|
|
|
|
|
- <div class="popup-title">{{ $t('为了精准匹配种植方案,完善物候信息') }}</div>
|
|
|
|
|
-
|
|
|
|
|
- <!-- 物候期表单 -->
|
|
|
|
|
- <el-form ref="phenologyFormRef" :model="phenologyData" label-width="92px" :rules="phenologyRules" class="farm-form">
|
|
|
|
|
- <!-- 物候期选择器 -->
|
|
|
|
|
- <el-form-item
|
|
|
|
|
- :label="$t('当下物候期')"
|
|
|
|
|
- prop="phenologyId"
|
|
|
|
|
- >
|
|
|
|
|
- <el-select
|
|
|
|
|
- v-model="phenologyData.phenologyId"
|
|
|
|
|
- :placeholder="$t('选择物候期')"
|
|
|
|
|
- style="width: 100%"
|
|
|
|
|
- @change="handlePhenologyChange"
|
|
|
|
|
- >
|
|
|
|
|
- <el-option
|
|
|
|
|
- v-for="phenology in phenologyList"
|
|
|
|
|
- :key="phenology.phenologyId"
|
|
|
|
|
- :label="phenology.phenologyName"
|
|
|
|
|
- :value="phenology.phenologyId"
|
|
|
|
|
- />
|
|
|
|
|
- </el-select>
|
|
|
|
|
- </el-form-item>
|
|
|
|
|
-
|
|
|
|
|
- <!-- 日期选择器 -->
|
|
|
|
|
- <el-form-item
|
|
|
|
|
- :label="$t('起始时间')"
|
|
|
|
|
- prop="phenologyStartDate"
|
|
|
|
|
- >
|
|
|
|
|
- <el-date-picker
|
|
|
|
|
- v-model="phenologyData.phenologyStartDate"
|
|
|
|
|
- type="date"
|
|
|
|
|
- :placeholder="$t('选择时间')"
|
|
|
|
|
- format="YYYY-MM-DD"
|
|
|
|
|
- value-format="YYYY-MM-DD"
|
|
|
|
|
- style="width: 100%"
|
|
|
|
|
|
|
+ </field>
|
|
|
|
|
+ <field readonly :label="$t('种植作物')" class="crop-field">
|
|
|
|
|
+ <template #input>
|
|
|
|
|
+ <template v-if="farmInfo.regionList && farmInfo.regionList.length">
|
|
|
|
|
+ <template v-for="(item, index) in farmInfo.regionList" :key="index">
|
|
|
|
|
+ <span>{{ item.regionName }}</span>
|
|
|
|
|
+ <span v-if="index !== farmInfo.regionList.length - 1">、</span>
|
|
|
|
|
+ </template>
|
|
|
|
|
+ </template>
|
|
|
|
|
+ <template v-else>
|
|
|
|
|
+ <span>-</span>
|
|
|
|
|
+ </template>
|
|
|
|
|
+ </template>
|
|
|
|
|
+ </field>
|
|
|
|
|
+ <field v-model="farmInfo.contactName" :label="$t('联系人')" />
|
|
|
|
|
+ <field
|
|
|
|
|
+ ref="contactPhoneFieldRef"
|
|
|
|
|
+ v-model="farmInfo.contactPhone"
|
|
|
|
|
+ :label="$t('联系电话')"
|
|
|
|
|
+ type="tel"
|
|
|
|
|
+ maxlength="11"
|
|
|
|
|
+ :rules="contactPhoneRules"
|
|
|
/>
|
|
/>
|
|
|
- </el-form-item>
|
|
|
|
|
- </el-form>
|
|
|
|
|
- </template>
|
|
|
|
|
-
|
|
|
|
|
- <!-- 确认按钮 -->
|
|
|
|
|
- <div class="btn-confirm" @click="handleConfirm">{{ $t('确认信息') }}</div>
|
|
|
|
|
- </popup>
|
|
|
|
|
|
|
+ <field class="address-field" v-model="farmInfo.farmAddress" readonly :label="$t('农场位置')" />
|
|
|
|
|
+ <!-- <field :label="$t('基地类别')" class="base-type-field">
|
|
|
|
|
+ <template #input>
|
|
|
|
|
+ <el-select
|
|
|
|
|
+ v-model="farmInfo.baseType"
|
|
|
|
|
+ :placeholder="$t('请选择')"
|
|
|
|
|
+ class="base-type-select"
|
|
|
|
|
+ autocomplete="off"
|
|
|
|
|
+ teleported
|
|
|
|
|
+ popper-class="farm-info-base-type-popper"
|
|
|
|
|
+ >
|
|
|
|
|
+ <el-option
|
|
|
|
|
+ v-for="opt in baseTypeOptions"
|
|
|
|
|
+ :key="opt.id"
|
|
|
|
|
+ :label="opt.name"
|
|
|
|
|
+ :value="opt.id"
|
|
|
|
|
+ />
|
|
|
|
|
+ </el-select>
|
|
|
|
|
+ </template>
|
|
|
|
|
+ </field> -->
|
|
|
|
|
+ </cell-group>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div class="popup-footer">
|
|
|
|
|
+ <div class="footer-btn no-btn" @click="handleCancel">{{ $t('取消') }}</div>
|
|
|
|
|
+ <div class="footer-btn yes-btn" @click="handleEdit">{{ $t('确认修改') }}</div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </Popup>
|
|
|
</template>
|
|
</template>
|
|
|
|
|
|
|
|
<script setup>
|
|
<script setup>
|
|
|
-import { Popup } from "vant";
|
|
|
|
|
-import { computed, ref, watch, nextTick ,onMounted} from "vue";
|
|
|
|
|
-import { ElMessage } from "element-plus";
|
|
|
|
|
-import { convertPointToArray } from "@/utils/index";
|
|
|
|
|
|
|
+import { Popup, Field, CellGroup, Checkbox } from "vant";
|
|
|
|
|
+import { ref, nextTick } from "vue";
|
|
|
|
|
+import { useRouter } from "vue-router";
|
|
|
|
|
+// import IndexMap from "../map/index.js";
|
|
|
import { useStore } from "vuex";
|
|
import { useStore } from "vuex";
|
|
|
|
|
+import { ElMessage } from "element-plus";
|
|
|
|
|
|
|
|
-const store = useStore();
|
|
|
|
|
-
|
|
|
|
|
-const props = defineProps({
|
|
|
|
|
- // 控制弹窗显示/隐藏
|
|
|
|
|
- show: {
|
|
|
|
|
- type: Boolean,
|
|
|
|
|
- default: false,
|
|
|
|
|
- },
|
|
|
|
|
- // 是否在点击遮罩层后关闭弹窗
|
|
|
|
|
- closeOnClickOverlay: {
|
|
|
|
|
- type: Boolean,
|
|
|
|
|
- default: false,
|
|
|
|
|
- },
|
|
|
|
|
- // 初始表单数据
|
|
|
|
|
- initialData: {
|
|
|
|
|
- type: Object,
|
|
|
|
|
- default: () => ({}),
|
|
|
|
|
- },
|
|
|
|
|
- expertMiniUserId: {
|
|
|
|
|
- type: [String, Number],
|
|
|
|
|
- default: "",
|
|
|
|
|
|
|
+/** 与 create_farm 联系电话规则一致 */
|
|
|
|
|
+const contactPhoneRules = [
|
|
|
|
|
+ { required: true, message: "请输入联系电话" },
|
|
|
|
|
+ {
|
|
|
|
|
+ pattern: /^1[3-9]\d{9}$/,
|
|
|
|
|
+ message: "请输入正确的手机号码",
|
|
|
},
|
|
},
|
|
|
- oldUser: {
|
|
|
|
|
- type: Boolean,
|
|
|
|
|
- default: false,
|
|
|
|
|
- },
|
|
|
|
|
-});
|
|
|
|
|
-
|
|
|
|
|
-const city = ref("");
|
|
|
|
|
-const MAP_KEY = "CZLBZ-LJICQ-R4A5J-BN62X-YXCRJ-GNBUT";
|
|
|
|
|
-function getLocationName(location) {
|
|
|
|
|
- const params = {
|
|
|
|
|
- key: MAP_KEY,
|
|
|
|
|
- location,
|
|
|
|
|
- };
|
|
|
|
|
- VE_API.old_mini_map.location(params).then(({ result }) => {
|
|
|
|
|
- const add = result.formatted_addresses?.recommend ? result.formatted_addresses.recommend : result.address + "";
|
|
|
|
|
- formData.value.address = add;
|
|
|
|
|
- city.value = result.address_component?.city + result.address_component?.district || "";
|
|
|
|
|
- });
|
|
|
|
|
-}
|
|
|
|
|
|
|
+];
|
|
|
|
|
|
|
|
-onMounted(() => {
|
|
|
|
|
- const arr = convertPointToArray(store.state.home.miniUserLocationPoint);
|
|
|
|
|
- getLocationName(`${arr[1]},${arr[0]}`);
|
|
|
|
|
- getSpecieList();
|
|
|
|
|
-});
|
|
|
|
|
-
|
|
|
|
|
-function getSpecieList() {
|
|
|
|
|
- return VE_API.farm.fetchSpecieList({ point: store.state.home.miniUserLocationPoint }).then(({ data }) => {
|
|
|
|
|
- specieList.value = data || [];
|
|
|
|
|
|
|
+const baseTypeOptions = ref([]);
|
|
|
|
|
+function getBaseTypeList() {
|
|
|
|
|
+ return VE_API.farm.fetchBaseTypeList().then(({ data }) => {
|
|
|
|
|
+ baseTypeOptions.value = data || [];
|
|
|
return data;
|
|
return data;
|
|
|
});
|
|
});
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-function getFruitsList(parentId) {
|
|
|
|
|
- VE_API.farm.fruitsTypeItemList({ parentId }).then(({ data }) => {
|
|
|
|
|
- fruitsList.value = data;
|
|
|
|
|
- });
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-const emit = defineEmits(["update:show"]);
|
|
|
|
|
-
|
|
|
|
|
-// 处理v-model双向绑定
|
|
|
|
|
-const showValue = computed({
|
|
|
|
|
- get: () => props.show,
|
|
|
|
|
- set: (value) => emit("update:show", value),
|
|
|
|
|
|
|
+const props = defineProps({
|
|
|
|
|
+ farmId: {
|
|
|
|
|
+ type: [Number, String],
|
|
|
|
|
+ default: null,
|
|
|
|
|
+ },
|
|
|
});
|
|
});
|
|
|
|
|
|
|
|
-const formRef = ref(null);
|
|
|
|
|
-const phenologyFormRef = ref(null);
|
|
|
|
|
-
|
|
|
|
|
-// 当前步骤:1-填写农场信息,2-填写物候期时间
|
|
|
|
|
-const currentStep = ref(1);
|
|
|
|
|
-
|
|
|
|
|
-// 用户是否手动修改过农场名称
|
|
|
|
|
-const isNameEdited = ref(false);
|
|
|
|
|
|
|
+const store = useStore();
|
|
|
|
|
+const router = useRouter();
|
|
|
|
|
+const show = ref(false);
|
|
|
|
|
+const mapContainer = ref(null);
|
|
|
|
|
+const contactPhoneFieldRef = ref(null);
|
|
|
|
|
+// const indexMap = new IndexMap();
|
|
|
|
|
+
|
|
|
|
|
+// 农场信息
|
|
|
|
|
+const farmInfo = ref();
|
|
|
|
|
+const handleShow = () => {
|
|
|
|
|
+ VE_API.basic_farm.fetchFarmSubjectDetail({ subjectId: props.farmId }).then((res) => {
|
|
|
|
|
+ if (res.code === 0) {
|
|
|
|
|
+ farmInfo.value = res.data;
|
|
|
|
|
+ getBaseTypeList();
|
|
|
|
|
+ show.value = true;
|
|
|
|
|
+ // nextTick(() => {
|
|
|
|
|
+ // const point = farmInfo.value.farmLocation;
|
|
|
|
|
+ // let geometryArr = [];
|
|
|
|
|
+
|
|
|
|
|
+ // if (Array.isArray(farmInfo.value.regionList) && farmInfo.value.regionList.length > 0) {
|
|
|
|
|
+ // farmInfo.value.regionList.forEach((item) => {
|
|
|
|
|
+ // if (item?.geom) {
|
|
|
|
|
+ // geometryArr.push(item?.geom)
|
|
|
|
|
+ // }
|
|
|
|
|
+ // });
|
|
|
|
|
+ // }
|
|
|
|
|
+
|
|
|
|
|
+ // console.log('geometryArr', geometryArr);
|
|
|
|
|
+ // // 如果地图已经初始化,则更新中心点和地块;否则初始化地图
|
|
|
|
|
+ // if (indexMap.kmap) {
|
|
|
|
|
+ // indexMap.updateCenter(point);
|
|
|
|
|
+ // // 如果有地块数据,则添加地块
|
|
|
|
|
+ // if (geometryArr && geometryArr.length > 0) {
|
|
|
|
|
+ // indexMap.setAreaGeometry([geometryArr]);
|
|
|
|
|
+ // }
|
|
|
|
|
+ // } else {
|
|
|
|
|
+ // indexMap.initMap(point, mapContainer.value);
|
|
|
|
|
+ // // 初始化地图后,如果有地块数据,则添加地块
|
|
|
|
|
+ // if (geometryArr && geometryArr.length > 0) {
|
|
|
|
|
+ // indexMap.setAreaGeometry([geometryArr]);
|
|
|
|
|
+ // }
|
|
|
|
|
+ // }
|
|
|
|
|
+ // });
|
|
|
|
|
+ }
|
|
|
|
|
+ });
|
|
|
|
|
+};
|
|
|
|
|
|
|
|
-// 表单数据
|
|
|
|
|
-const formData = ref({
|
|
|
|
|
- address: "",
|
|
|
|
|
- speciesId: "",
|
|
|
|
|
- typeIds: [],
|
|
|
|
|
- mu: "",
|
|
|
|
|
- name: "",
|
|
|
|
|
-});
|
|
|
|
|
|
|
+const emit = defineEmits(['success']);
|
|
|
|
|
|
|
|
-// 物候期列表
|
|
|
|
|
-const phenologyList = ref([]);
|
|
|
|
|
|
|
+const handleEdit = async () => {
|
|
|
|
|
+ const phoneErr = await contactPhoneFieldRef.value?.validate();
|
|
|
|
|
+ if (phoneErr?.message) {
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+ const paramsData = {
|
|
|
|
|
+ id: props.farmId,
|
|
|
|
|
+ name: farmInfo.value.subjectName,
|
|
|
|
|
+ fzr: farmInfo.value.contactName,
|
|
|
|
|
+ tel: farmInfo.value.contactPhone,
|
|
|
|
|
+ baseType: farmInfo.value.baseType,
|
|
|
|
|
+ expertMiniUserId: 81881,
|
|
|
|
|
+ }
|
|
|
|
|
+ VE_API.basic_farm.saveBasicFarmInfoByExpertV3(paramsData).then((res) => {
|
|
|
|
|
+ if (res.code === 0) {
|
|
|
|
|
+ ElMessage.success('修改成功');
|
|
|
|
|
+ show.value = false;
|
|
|
|
|
+ emit('success', {
|
|
|
|
|
+ id: props.farmId,
|
|
|
|
|
+ name: farmInfo.value.subjectName,
|
|
|
|
|
+ });
|
|
|
|
|
+ }
|
|
|
|
|
+ });
|
|
|
|
|
+ // setTimeout(() => {
|
|
|
|
|
+ // show.value = false;
|
|
|
|
|
+ // }, 150);
|
|
|
|
|
+
|
|
|
|
|
+ // // 在跳转前,将当前农场的地块数据存储到store中
|
|
|
|
|
+ // if (farmInfo.value.geomWkt) {
|
|
|
|
|
+ // const polygonData = {
|
|
|
|
|
+ // geometryArr: [farmInfo.value.geomWkt],
|
|
|
|
|
+ // mianji: farmInfo.value.mianji,
|
|
|
|
|
+ // isConfirmed: true, // 编辑模式下标记为已确认
|
|
|
|
|
+ // };
|
|
|
|
|
+ // store.commit("home/SET_FARM_POLYGON", polygonData);
|
|
|
|
|
+ // }
|
|
|
|
|
+
|
|
|
|
|
+ // // 将农场数据存储到store中,供编辑页面使用
|
|
|
|
|
+ // store.commit("home/SET_EDIT_FARM_DATA", farmInfo.value);
|
|
|
|
|
+
|
|
|
|
|
+ // const from = props.showEditBtn ? "details" : "monitor";
|
|
|
|
|
+ // router.push(`/create_farm?type=edit&farmId=${props.farmId}&from=${from}`);
|
|
|
|
|
+};
|
|
|
|
|
|
|
|
-// 物候期表单数据
|
|
|
|
|
-const phenologyData = ref({});
|
|
|
|
|
|
|
+const handleCancel = () => {
|
|
|
|
|
+ show.value = false;
|
|
|
|
|
+};
|
|
|
|
|
|
|
|
-const specieList = ref([]);
|
|
|
|
|
-const fruitsList = ref([]);
|
|
|
|
|
|
|
+defineExpose({ handleShow });
|
|
|
|
|
+</script>
|
|
|
|
|
|
|
|
-// 规范化多选品种 typeId(支持字符串/数组),确保最终一定是数组
|
|
|
|
|
-const normalizeTypeId = (value) => {
|
|
|
|
|
- if (Array.isArray(value)) return value;
|
|
|
|
|
- if (value === null || value === undefined || value === "") return [];
|
|
|
|
|
- return [value];
|
|
|
|
|
-};
|
|
|
|
|
|
|
+<style lang="scss" scoped>
|
|
|
|
|
+.farm-info-popup {
|
|
|
|
|
+ width: 100%;
|
|
|
|
|
+ border-radius: 8px;
|
|
|
|
|
+ z-index: 9999 !important;
|
|
|
|
|
+ overflow: hidden;
|
|
|
|
|
|
|
|
-// 自定义验证器:验证农场品种(只校验 speciesId)
|
|
|
|
|
-const validateSpeciesId = (rule, value, callback) => {
|
|
|
|
|
- if (!value) {
|
|
|
|
|
- callback(new Error("请选择农场品种"));
|
|
|
|
|
- } else {
|
|
|
|
|
- callback();
|
|
|
|
|
|
|
+ .popup-content-box {
|
|
|
|
|
+ background: url("@/assets/img/home/popup-mask.png") no-repeat center left / 100% 100%;
|
|
|
|
|
+ padding: 20px;
|
|
|
}
|
|
}
|
|
|
-};
|
|
|
|
|
|
|
|
|
|
-// 自定义验证器:验证农场品类(只校验 typeIds)
|
|
|
|
|
-const validateTypeIds = (rule, value, callback) => {
|
|
|
|
|
- const hasType =
|
|
|
|
|
- Array.isArray(value)
|
|
|
|
|
- ? value.length > 0
|
|
|
|
|
- : !!value;
|
|
|
|
|
- if (!hasType) {
|
|
|
|
|
- callback(new Error("请选择农场品类"));
|
|
|
|
|
- } else {
|
|
|
|
|
- callback();
|
|
|
|
|
|
|
+ ::v-deep {
|
|
|
|
|
+ .van-popup__close-icon {
|
|
|
|
|
+ color: #000;
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
-};
|
|
|
|
|
|
|
|
|
|
-// 表单验证规则
|
|
|
|
|
-const rules = {
|
|
|
|
|
- address: [{ required: true, message: "请输入农场位置", trigger: "blur" }],
|
|
|
|
|
- speciesId: [{ required: true, validator: validateSpeciesId, trigger: "change" }],
|
|
|
|
|
- typeIds: [{ required: true, validator: validateTypeIds, trigger: "change" }],
|
|
|
|
|
- mu: [
|
|
|
|
|
- { required: true, message: "请输入农场亩数", trigger: "blur" },
|
|
|
|
|
- { pattern: /^\d+(\.\d+)?$/, message: "请输入有效的数字", trigger: "blur" },
|
|
|
|
|
- ],
|
|
|
|
|
- name: [{ required: true, message: "请输入农场名称", trigger: "blur" }],
|
|
|
|
|
-};
|
|
|
|
|
|
|
+ .popup-title {
|
|
|
|
|
+ text-align: center;
|
|
|
|
|
+ font-size: 24px;
|
|
|
|
|
+ font-family: "PangMenZhengDao";
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
-// 物候期表单验证规则
|
|
|
|
|
-const phenologyRules = {
|
|
|
|
|
- phenologyId: [{ required: true, message: "请选择物候期", trigger: "change" }],
|
|
|
|
|
- phenologyStartDate: [{ required: true, message: "请选择起始时间", trigger: "change" }],
|
|
|
|
|
-};
|
|
|
|
|
|
|
+ .popup-content {
|
|
|
|
|
+ margin: 12px 0;
|
|
|
|
|
|
|
|
-// 监听初始数据变化
|
|
|
|
|
-watch(
|
|
|
|
|
- () => props.initialData,
|
|
|
|
|
- (newData) => {
|
|
|
|
|
- if (newData && Object.keys(newData).length > 0) {
|
|
|
|
|
- Object.assign(formData.value, newData);
|
|
|
|
|
- formData.value.typeIds = normalizeTypeId(formData.value.typeIds);
|
|
|
|
|
- }
|
|
|
|
|
- },
|
|
|
|
|
- { immediate: true, deep: true }
|
|
|
|
|
-);
|
|
|
|
|
-
|
|
|
|
|
-// 无论选择几个品类,始终保证 formData.typeIds 为数组
|
|
|
|
|
-watch(
|
|
|
|
|
- () => formData.value.typeIds,
|
|
|
|
|
- (newVal) => {
|
|
|
|
|
- // 仅在不是数组时进行规范化,避免死循环
|
|
|
|
|
- if (!Array.isArray(newVal)) {
|
|
|
|
|
- formData.value.typeIds = normalizeTypeId(newVal);
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
-);
|
|
|
|
|
-
|
|
|
|
|
-// 监听弹窗显示状态,重置表单
|
|
|
|
|
-watch(
|
|
|
|
|
- () => props.show,
|
|
|
|
|
- (newVal) => {
|
|
|
|
|
- if (newVal) {
|
|
|
|
|
- // 重置物候期列表和表单数据
|
|
|
|
|
- phenologyList.value = [];
|
|
|
|
|
- phenologyData.value = {};
|
|
|
|
|
- // 重置名称编辑状态
|
|
|
|
|
- isNameEdited.value = false;
|
|
|
|
|
- // 弹窗打开时,如果有初始数据则使用,否则使用默认值
|
|
|
|
|
- if (props.initialData && Object.keys(props.initialData).length > 0) {
|
|
|
|
|
- Object.assign(formData.value, props.initialData);
|
|
|
|
|
- formData.value.typeIds = normalizeTypeId(formData.value.typeIds);
|
|
|
|
|
- } else {
|
|
|
|
|
- formData.value = {
|
|
|
|
|
- address: "",
|
|
|
|
|
- speciesId: "",
|
|
|
|
|
- typeIds: [],
|
|
|
|
|
- mu: "",
|
|
|
|
|
- name: "",
|
|
|
|
|
- };
|
|
|
|
|
|
|
+ .map-box {
|
|
|
|
|
+ width: 100%;
|
|
|
|
|
+ height: 150px;
|
|
|
|
|
+ position: relative;
|
|
|
|
|
+
|
|
|
|
|
+ .map {
|
|
|
|
|
+ width: 100%;
|
|
|
|
|
+ height: 100%;
|
|
|
|
|
+ clip-path: inset(0px round 5px);
|
|
|
|
|
+ pointer-events: none;
|
|
|
}
|
|
}
|
|
|
- // 清除验证状态
|
|
|
|
|
- nextTick(() => {
|
|
|
|
|
- formRef.value?.clearValidate();
|
|
|
|
|
- phenologyFormRef.value?.clearValidate();
|
|
|
|
|
- });
|
|
|
|
|
|
|
|
|
|
- if(props.oldUser){
|
|
|
|
|
- currentStep.value = 2;
|
|
|
|
|
- getCurrentAndNextPhenology()
|
|
|
|
|
- }else{
|
|
|
|
|
- currentStep.value = 1;
|
|
|
|
|
|
|
+ .map-text {
|
|
|
|
|
+ position: absolute;
|
|
|
|
|
+ right: 6px;
|
|
|
|
|
+ bottom: 8px;
|
|
|
|
|
+ font-size: 12px;
|
|
|
|
|
+ color: #ffffff;
|
|
|
|
|
+ padding: 8px 12px;
|
|
|
|
|
+ border-radius: 20px;
|
|
|
|
|
+ background: rgba(0, 0, 0, 0.5);
|
|
|
|
|
+ border: 1px solid rgba(255, 255, 255, 0.5);
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
- }
|
|
|
|
|
-);
|
|
|
|
|
-
|
|
|
|
|
-// 品种1变化时,重置品种2并触发验证
|
|
|
|
|
-const handleSpecieChange = (val) => {
|
|
|
|
|
- formData.value.typeIds = [];
|
|
|
|
|
- const specie = specieList.value.find(item => item.id === val);
|
|
|
|
|
- // 只有在用户没有手动修改名称时,才自动带出默认名称
|
|
|
|
|
- if (specie && !isNameEdited.value) {
|
|
|
|
|
- formData.value.name = city.value + specie.name + "农场";
|
|
|
|
|
- }
|
|
|
|
|
- getFruitsList(val);
|
|
|
|
|
- // 触发品种验证
|
|
|
|
|
- nextTick(() => {
|
|
|
|
|
- formRef.value?.validateField("speciesId");
|
|
|
|
|
- });
|
|
|
|
|
-};
|
|
|
|
|
|
|
|
|
|
-// 品种2变化时,触发验证
|
|
|
|
|
-const handleFruitsChange = () => {
|
|
|
|
|
- nextTick(() => {
|
|
|
|
|
- // 只校验当前字段(农场品类)
|
|
|
|
|
- formRef.value?.validateField("typeIds");
|
|
|
|
|
- });
|
|
|
|
|
-};
|
|
|
|
|
|
|
+ .cell-group {
|
|
|
|
|
+ margin: 12px 0 0;
|
|
|
|
|
|
|
|
-// 农场名称输入时,标记为用户已手动修改
|
|
|
|
|
-const handleNameInput = () => {
|
|
|
|
|
- isNameEdited.value = true;
|
|
|
|
|
-};
|
|
|
|
|
|
|
+ .crop-field {
|
|
|
|
|
+ ::v-deep {
|
|
|
|
|
+ .van-field__control--custom {
|
|
|
|
|
+ flex-wrap: wrap;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
-// 确认信息
|
|
|
|
|
-const handleConfirm = async () => {
|
|
|
|
|
- // 第一步:验证农场信息表单
|
|
|
|
|
- if (currentStep.value === 1) {
|
|
|
|
|
- if (!formRef.value) return;
|
|
|
|
|
- try {
|
|
|
|
|
- await formRef.value.validate();
|
|
|
|
|
-
|
|
|
|
|
- // 验证通过,获取物候期数据并切换到第二步
|
|
|
|
|
- await getCurrentAndNextPhenology();
|
|
|
|
|
- currentStep.value = 2;
|
|
|
|
|
- } catch (error) {
|
|
|
|
|
- console.log("表单验证失败", error);
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
- // 第二步:验证物候期表单并关闭弹窗
|
|
|
|
|
- else {
|
|
|
|
|
- if (!phenologyFormRef.value) return;
|
|
|
|
|
- try {
|
|
|
|
|
- await phenologyFormRef.value.validate();
|
|
|
|
|
- // 验证通过,提交所有数据并关闭弹窗
|
|
|
|
|
- const params = {
|
|
|
|
|
- ...formData.value,
|
|
|
|
|
- ...phenologyData.value,
|
|
|
|
|
- wkt: store.state.home.miniUserLocationPoint,
|
|
|
|
|
- expertMiniUserId: props.expertMiniUserId,
|
|
|
|
|
- containerId: specieList.value.find(item => item.id === formData.value.speciesId)?.defaultContainerId,
|
|
|
|
|
|
|
+ .base-type-field {
|
|
|
|
|
+ ::v-deep {
|
|
|
|
|
+ .el-select {
|
|
|
|
|
+ width: 100%;
|
|
|
|
|
+ }
|
|
|
|
|
+ .el-select__wrapper {
|
|
|
|
|
+ min-height: 24px;
|
|
|
|
|
+ box-shadow: none;
|
|
|
|
|
+ padding-left: 0;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
- if(!props.oldUser){
|
|
|
|
|
- const { code, msg } = await VE_API.farm.saveFarm(params);
|
|
|
|
|
- if (code === 0) {
|
|
|
|
|
- ElMessage.success("农场信息确认成功");
|
|
|
|
|
- emit("update:show", false);
|
|
|
|
|
- } else {
|
|
|
|
|
- ElMessage.error(msg || '农场信息确认失败');
|
|
|
|
|
|
|
+
|
|
|
|
|
+ .address-field {
|
|
|
|
|
+ position: relative;
|
|
|
|
|
+
|
|
|
|
|
+ &::before {
|
|
|
|
|
+ position: absolute;
|
|
|
|
|
+ box-sizing: border-box;
|
|
|
|
|
+ content: " ";
|
|
|
|
|
+ pointer-events: none;
|
|
|
|
|
+ right: 16px;
|
|
|
|
|
+ bottom: 0;
|
|
|
|
|
+ left: 16px;
|
|
|
|
|
+ border-bottom: 1px solid #ebedf0;
|
|
|
|
|
+ transform: scaleY(0.5);
|
|
|
}
|
|
}
|
|
|
- }else{
|
|
|
|
|
- ElMessage.success("农场信息确认成功");
|
|
|
|
|
- emit("update:show", false);
|
|
|
|
|
}
|
|
}
|
|
|
- } catch (error) {
|
|
|
|
|
- console.log("物候期表单验证失败", error);
|
|
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
-};
|
|
|
|
|
-
|
|
|
|
|
-// 获取当前日期(YYYY-MM-DD格式)
|
|
|
|
|
-const getTodayDate = () => {
|
|
|
|
|
- const today = new Date();
|
|
|
|
|
- const year = today.getFullYear();
|
|
|
|
|
- const month = String(today.getMonth() + 1).padStart(2, "0");
|
|
|
|
|
- const day = String(today.getDate()).padStart(2, "0");
|
|
|
|
|
- return `${year}-${month}-${day}`;
|
|
|
|
|
-};
|
|
|
|
|
|
|
|
|
|
-// 物候期变化时,更新日期为对应物候期的 startDate
|
|
|
|
|
-const handlePhenologyChange = (phenologyId) => {
|
|
|
|
|
- const selectedPhenology = phenologyList.value.find(item => item.phenologyId === phenologyId);
|
|
|
|
|
- if (selectedPhenology && selectedPhenology.startDate) {
|
|
|
|
|
- phenologyData.value.phenologyStartDate = selectedPhenology.startDate;
|
|
|
|
|
|
|
+ .checkbox {
|
|
|
|
|
+ pointer-events: none;
|
|
|
|
|
+ padding: 12px 14px;
|
|
|
}
|
|
}
|
|
|
-};
|
|
|
|
|
-
|
|
|
|
|
-// 获取当前和下一个物候期
|
|
|
|
|
-const getCurrentAndNextPhenology = async () => {
|
|
|
|
|
- try {
|
|
|
|
|
- const { data } = await VE_API.home.getCurrentAndNextPhenology({
|
|
|
|
|
- expertMiniUserId: props.expertMiniUserId,
|
|
|
|
|
- containerId: specieList.value.find(item => item.id === formData.value.speciesId)?.defaultContainerId || '26',
|
|
|
|
|
- });
|
|
|
|
|
- if (data && Array.isArray(data)) {
|
|
|
|
|
- phenologyList.value = data;
|
|
|
|
|
- // 初始化物候期表单数据,日期使用第一个物候期的 startDate
|
|
|
|
|
- const firstPhenology = data[0];
|
|
|
|
|
- phenologyData.value = {
|
|
|
|
|
- phenologyId: firstPhenology?.phenologyId || "",
|
|
|
|
|
- phenologyStartDate: firstPhenology?.startDate || getTodayDate(),
|
|
|
|
|
- };
|
|
|
|
|
- }
|
|
|
|
|
- } catch (error) {
|
|
|
|
|
- console.error("获取物候期数据失败", error);
|
|
|
|
|
- ElMessage.error("获取物候期数据失败");
|
|
|
|
|
- }
|
|
|
|
|
-};
|
|
|
|
|
-</script>
|
|
|
|
|
-
|
|
|
|
|
-<style scoped lang="scss">
|
|
|
|
|
-.farm-info-popup {
|
|
|
|
|
- width: 100%;
|
|
|
|
|
- padding: 20px 16px;
|
|
|
|
|
- border-radius: 12px;
|
|
|
|
|
|
|
|
|
|
- .popup-title {
|
|
|
|
|
- font-size: 16px;
|
|
|
|
|
- color: #121212;
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ .popup-footer {
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ gap: 13px;
|
|
|
|
|
|
|
|
- .farm-form {
|
|
|
|
|
- margin: 16px 0;
|
|
|
|
|
- background: rgba(33, 153, 248, 0.05);
|
|
|
|
|
- padding: 10px;
|
|
|
|
|
- border-radius: 5px;
|
|
|
|
|
- border: 1px solid rgba(33, 153, 248, 0.2);
|
|
|
|
|
- :deep(.el-form-item__label) {
|
|
|
|
|
- color: #1d2129;
|
|
|
|
|
- }
|
|
|
|
|
- .variety-select-wrap {
|
|
|
|
|
- display: flex;
|
|
|
|
|
- gap: 10px;
|
|
|
|
|
- width: 100%;
|
|
|
|
|
|
|
+ .footer-btn {
|
|
|
|
|
+ text-align: center;
|
|
|
|
|
+ flex: 1;
|
|
|
|
|
+ padding: 8px 0;
|
|
|
|
|
+ border-radius: 25px;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- .unit {
|
|
|
|
|
- color: #666;
|
|
|
|
|
- font-size: 14px;
|
|
|
|
|
- padding-right: 8px;
|
|
|
|
|
|
|
+ .no-btn {
|
|
|
|
|
+ color: #666666;
|
|
|
|
|
+ border: 1px solid #999999;
|
|
|
}
|
|
}
|
|
|
- }
|
|
|
|
|
|
|
|
|
|
- .btn-confirm {
|
|
|
|
|
- padding: 10px;
|
|
|
|
|
- background: #2199f8;
|
|
|
|
|
- color: #ffffff;
|
|
|
|
|
- border-radius: 4px;
|
|
|
|
|
- font-size: 16px;
|
|
|
|
|
- text-align: center;
|
|
|
|
|
|
|
+ .yes-btn {
|
|
|
|
|
+ background: #2199f8;
|
|
|
|
|
+ color: #fff;
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
</style>
|
|
</style>
|
|
|
|
|
+
|
|
|
|
|
+<!-- 下拉挂载在 body,需非 scoped 才能盖住 van-popup(z-index: 9999) -->
|
|
|
|
|
+<style lang="scss">
|
|
|
|
|
+.farm-info-base-type-popper {
|
|
|
|
|
+ z-index: 10050 !important;
|
|
|
|
|
+}
|
|
|
|
|
+</style>
|