|
|
@@ -6,63 +6,115 @@
|
|
|
:close-on-click-overlay="true"
|
|
|
teleport="body"
|
|
|
>
|
|
|
- <!-- 标题 -->
|
|
|
- <div class="popup-title">为了更方便分析农场问题,请先完善您的农场信息</div>
|
|
|
-
|
|
|
- <!-- 表单区域 -->
|
|
|
- <el-form ref="formRef" :model="formData" :rules="rules" class="farm-form">
|
|
|
- <!-- 农场位置 -->
|
|
|
- <el-form-item label="农场位置" prop="location">
|
|
|
- <el-input v-model="formData.location" placeholder="请输入农场位置" clearable />
|
|
|
- </el-form-item>
|
|
|
-
|
|
|
- <!-- 农场品种 -->
|
|
|
- <el-form-item label="农场品种" prop="variety">
|
|
|
- <div class="variety-select-wrap">
|
|
|
- <el-select
|
|
|
- v-model="formData.variety1"
|
|
|
- placeholder="请选择"
|
|
|
- class="variety-select"
|
|
|
- @change="handleVariety1Change"
|
|
|
- >
|
|
|
- <el-option
|
|
|
- v-for="item in variety1List"
|
|
|
- :key="item.value"
|
|
|
- :label="item.label"
|
|
|
- :value="item.value"
|
|
|
- />
|
|
|
- </el-select>
|
|
|
+ <!-- 第一步:农场信息填写 -->
|
|
|
+ <template v-if="currentStep === 1">
|
|
|
+ <!-- 标题 -->
|
|
|
+ <div class="popup-title">为了更方便分析农场问题,请先完善您的农场信息</div>
|
|
|
+
|
|
|
+ <!-- 表单区域 -->
|
|
|
+ <el-form ref="formRef" :model="formData" :rules="rules" class="farm-form">
|
|
|
+ <!-- 农场位置 -->
|
|
|
+ <el-form-item label="农场位置" prop="address">
|
|
|
+ <el-input v-model="formData.address" placeholder="请输入农场位置" clearable />
|
|
|
+ </el-form-item>
|
|
|
+
|
|
|
+ <!-- 农场品种 -->
|
|
|
+ <el-form-item label="农场品种" prop="speciesId">
|
|
|
+ <div class="variety-select-wrap">
|
|
|
+ <el-select
|
|
|
+ v-model="formData.speciesId"
|
|
|
+ placeholder="请选择"
|
|
|
+ class="variety-select"
|
|
|
+ @change="handleSpecieChange"
|
|
|
+ >
|
|
|
+ <el-option
|
|
|
+ v-for="item in specieList"
|
|
|
+ :key="item.id"
|
|
|
+ :label="item.name"
|
|
|
+ :value="item.id"
|
|
|
+ />
|
|
|
+ </el-select>
|
|
|
+ <el-select
|
|
|
+ v-model="formData.typeId"
|
|
|
+ placeholder="请选择"
|
|
|
+ class="variety-select"
|
|
|
+ :disabled="!formData.speciesId"
|
|
|
+ @change="handleFruitsChange"
|
|
|
+ >
|
|
|
+ <el-option
|
|
|
+ v-for="item in fruitsList"
|
|
|
+ :key="item.id"
|
|
|
+ :label="item.name"
|
|
|
+ :value="item.id"
|
|
|
+ />
|
|
|
+ </el-select>
|
|
|
+ </div>
|
|
|
+ </el-form-item>
|
|
|
+
|
|
|
+ <!-- 农场亩数 -->
|
|
|
+ <el-form-item label="农场亩数" prop="mu">
|
|
|
+ <el-input v-model="formData.mu" placeholder="请输入" type="number">
|
|
|
+ <template #suffix>
|
|
|
+ <span class="unit">亩</span>
|
|
|
+ </template>
|
|
|
+ </el-input>
|
|
|
+ </el-form-item>
|
|
|
+
|
|
|
+ <!-- 农场名称 -->
|
|
|
+ <el-form-item label="农场名称" prop="name">
|
|
|
+ <el-input
|
|
|
+ v-model="formData.name"
|
|
|
+ placeholder="请输入农场名称"
|
|
|
+ clearable
|
|
|
+ @input="handleNameInput"
|
|
|
+ />
|
|
|
+ </el-form-item>
|
|
|
+ </el-form>
|
|
|
+ </template>
|
|
|
+
|
|
|
+ <!-- 第二步:物候期起始时间填写 -->
|
|
|
+ <template v-else>
|
|
|
+ <!-- 提示文字 -->
|
|
|
+ <div class="popup-title">请填写当下物候期起始时间,农事预测更精准</div>
|
|
|
+
|
|
|
+ <!-- 物候期表单 -->
|
|
|
+ <el-form ref="phenologyFormRef" :model="phenologyData" :rules="phenologyRules" class="farm-form">
|
|
|
+ <!-- 物候期选择器 -->
|
|
|
+ <el-form-item
|
|
|
+ label="当下物候期"
|
|
|
+ prop="phenologyId"
|
|
|
+ >
|
|
|
<el-select
|
|
|
- v-model="formData.variety2"
|
|
|
- placeholder="请选择"
|
|
|
- class="variety-select"
|
|
|
- :disabled="!formData.variety1"
|
|
|
- @change="handleVariety2Change"
|
|
|
+ v-model="phenologyData.phenologyId"
|
|
|
+ placeholder="选择物候期"
|
|
|
+ style="width: 100%"
|
|
|
+ @change="handlePhenologyChange"
|
|
|
>
|
|
|
<el-option
|
|
|
- v-for="item in variety2List"
|
|
|
- :key="item.value"
|
|
|
- :label="item.label"
|
|
|
- :value="item.value"
|
|
|
+ v-for="phenology in phenologyList"
|
|
|
+ :key="phenology.phenologyId"
|
|
|
+ :label="phenology.phenologyName"
|
|
|
+ :value="phenology.phenologyId"
|
|
|
/>
|
|
|
</el-select>
|
|
|
- </div>
|
|
|
- </el-form-item>
|
|
|
-
|
|
|
- <!-- 农场亩数 -->
|
|
|
- <el-form-item label="农场亩数" prop="acreage">
|
|
|
- <el-input v-model="formData.acreage" placeholder="请输入" type="number">
|
|
|
- <template #suffix>
|
|
|
- <span class="unit">亩</span>
|
|
|
- </template>
|
|
|
- </el-input>
|
|
|
- </el-form-item>
|
|
|
-
|
|
|
- <!-- 农场名称 -->
|
|
|
- <el-form-item label="农场名称" prop="farmName">
|
|
|
- <el-input v-model="formData.farmName" placeholder="请输入农场名称" clearable />
|
|
|
- </el-form-item>
|
|
|
- </el-form>
|
|
|
+ </el-form-item>
|
|
|
+
|
|
|
+ <!-- 日期选择器 -->
|
|
|
+ <el-form-item
|
|
|
+ label="起始时间"
|
|
|
+ prop="phenologyStartDate"
|
|
|
+ >
|
|
|
+ <el-date-picker
|
|
|
+ v-model="phenologyData.phenologyStartDate"
|
|
|
+ type="date"
|
|
|
+ placeholder="选择时间"
|
|
|
+ format="YYYY-MM-DD"
|
|
|
+ value-format="YYYY-MM-DD"
|
|
|
+ style="width: 100%"
|
|
|
+ />
|
|
|
+ </el-form-item>
|
|
|
+ </el-form>
|
|
|
+ </template>
|
|
|
|
|
|
<!-- 确认按钮 -->
|
|
|
<div class="btn-confirm" @click="handleConfirm">确认信息</div>
|
|
|
@@ -71,8 +123,12 @@
|
|
|
|
|
|
<script setup>
|
|
|
import { Popup } from "vant";
|
|
|
-import { computed, ref, watch, nextTick } from "vue";
|
|
|
+import { computed, ref, watch, nextTick ,onMounted} from "vue";
|
|
|
import { ElMessage } from "element-plus";
|
|
|
+import { convertPointToArray } from "@/utils/index";
|
|
|
+import { useStore } from "vuex";
|
|
|
+
|
|
|
+const store = useStore();
|
|
|
|
|
|
const props = defineProps({
|
|
|
// 控制弹窗显示/隐藏
|
|
|
@@ -90,8 +146,45 @@ const props = defineProps({
|
|
|
type: Object,
|
|
|
default: () => ({}),
|
|
|
},
|
|
|
+ expertMiniUserId: {
|
|
|
+ type: [String, Number],
|
|
|
+ default: "",
|
|
|
+ },
|
|
|
});
|
|
|
|
|
|
+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 || [];
|
|
|
+ return data;
|
|
|
+ });
|
|
|
+}
|
|
|
+
|
|
|
+function getFruitsList(parentId) {
|
|
|
+ VE_API.farm.fruitsTypeItemList({ parentId }).then(({ data }) => {
|
|
|
+ fruitsList.value = data;
|
|
|
+ });
|
|
|
+}
|
|
|
+
|
|
|
const emit = defineEmits(["update:show", "confirm"]);
|
|
|
|
|
|
// 处理v-model双向绑定
|
|
|
@@ -101,34 +194,35 @@ const showValue = computed({
|
|
|
});
|
|
|
|
|
|
const formRef = ref(null);
|
|
|
+const phenologyFormRef = ref(null);
|
|
|
+
|
|
|
+// 当前步骤:1-填写农场信息,2-填写物候期时间
|
|
|
+const currentStep = ref(1);
|
|
|
+
|
|
|
+// 用户是否手动修改过农场名称
|
|
|
+const isNameEdited = ref(false);
|
|
|
|
|
|
// 表单数据
|
|
|
const formData = ref({
|
|
|
- location: "广东省广州市从化区",
|
|
|
- variety1: "荔枝",
|
|
|
- variety2: "桂味",
|
|
|
- acreage: "",
|
|
|
- farmName: "",
|
|
|
+ address: "",
|
|
|
+ speciesId: "",
|
|
|
+ typeId: "",
|
|
|
+ mu: "",
|
|
|
+ name: "",
|
|
|
});
|
|
|
|
|
|
-// 品种选项(示例数据,实际应该从接口获取)
|
|
|
-const variety1List = ref([
|
|
|
- { label: "荔枝", value: "荔枝" },
|
|
|
- { label: "龙眼", value: "龙眼" },
|
|
|
- { label: "芒果", value: "芒果" },
|
|
|
- { label: "柑橘", value: "柑橘" },
|
|
|
-]);
|
|
|
-
|
|
|
-const variety2List = ref([
|
|
|
- { label: "桂味", value: "桂味" },
|
|
|
- { label: "妃子笑", value: "妃子笑" },
|
|
|
- { label: "糯米糍", value: "糯米糍" },
|
|
|
- { label: "黑叶", value: "黑叶" },
|
|
|
-]);
|
|
|
+// 物候期列表
|
|
|
+const phenologyList = ref([]);
|
|
|
+
|
|
|
+// 物候期表单数据
|
|
|
+const phenologyData = ref({});
|
|
|
+
|
|
|
+const specieList = ref([]);
|
|
|
+const fruitsList = ref([]);
|
|
|
|
|
|
// 自定义验证器:验证农场品种
|
|
|
const validateVariety = (rule, value, callback) => {
|
|
|
- if (!formData.value.variety1 || !formData.value.variety2) {
|
|
|
+ if (!formData.value.speciesId || !formData.value.typeId) {
|
|
|
callback(new Error("请选择农场品种"));
|
|
|
} else {
|
|
|
callback();
|
|
|
@@ -137,13 +231,19 @@ const validateVariety = (rule, value, callback) => {
|
|
|
|
|
|
// 表单验证规则
|
|
|
const rules = {
|
|
|
- location: [{ required: true, message: "请输入农场位置", trigger: "blur" }],
|
|
|
- variety: [{ validator: validateVariety, trigger: "change" }],
|
|
|
- acreage: [
|
|
|
+ address: [{ required: true, message: "请输入农场位置", trigger: "blur" }],
|
|
|
+ speciesId: [{ required: true, validator: validateVariety, trigger: "change" }],
|
|
|
+ mu: [
|
|
|
{ required: true, message: "请输入农场亩数", trigger: "blur" },
|
|
|
{ pattern: /^\d+(\.\d+)?$/, message: "请输入有效的数字", trigger: "blur" },
|
|
|
],
|
|
|
- farmName: [{ required: true, message: "请输入农场名称", trigger: "blur" }],
|
|
|
+ name: [{ required: true, message: "请输入农场名称", trigger: "blur" }],
|
|
|
+};
|
|
|
+
|
|
|
+// 物候期表单验证规则
|
|
|
+const phenologyRules = {
|
|
|
+ phenologyId: [{ required: true, message: "请选择物候期", trigger: "change" }],
|
|
|
+ phenologyStartDate: [{ required: true, message: "请选择起始时间", trigger: "change" }],
|
|
|
};
|
|
|
|
|
|
// 监听初始数据变化
|
|
|
@@ -162,54 +262,133 @@ watch(
|
|
|
() => props.show,
|
|
|
(newVal) => {
|
|
|
if (newVal) {
|
|
|
+ // 重置步骤为第一步
|
|
|
+ currentStep.value = 1;
|
|
|
+ // 重置物候期列表和表单数据
|
|
|
+ phenologyList.value = [];
|
|
|
+ phenologyData.value = {};
|
|
|
+ // 重置名称编辑状态
|
|
|
+ isNameEdited.value = false;
|
|
|
// 弹窗打开时,如果有初始数据则使用,否则使用默认值
|
|
|
if (props.initialData && Object.keys(props.initialData).length > 0) {
|
|
|
Object.assign(formData.value, props.initialData);
|
|
|
} else {
|
|
|
formData.value = {
|
|
|
- location: "广东省广州市从化区",
|
|
|
- variety1: "荔枝",
|
|
|
- variety2: "桂味",
|
|
|
- acreage: "",
|
|
|
- farmName: "",
|
|
|
+ address: "",
|
|
|
+ speciesId: "",
|
|
|
+ typeId: "",
|
|
|
+ mu: "",
|
|
|
+ name: "",
|
|
|
};
|
|
|
}
|
|
|
// 清除验证状态
|
|
|
nextTick(() => {
|
|
|
formRef.value?.clearValidate();
|
|
|
+ phenologyFormRef.value?.clearValidate();
|
|
|
});
|
|
|
}
|
|
|
}
|
|
|
);
|
|
|
|
|
|
// 品种1变化时,重置品种2并触发验证
|
|
|
-const handleVariety1Change = (val) => {
|
|
|
- formData.value.variety2 = "";
|
|
|
+const handleSpecieChange = (val) => {
|
|
|
+ formData.value.typeId = "";
|
|
|
+ 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("variety");
|
|
|
+ formRef.value?.validateField("speciesId");
|
|
|
});
|
|
|
- // 这里可以根据品种1的值动态加载品种2的选项
|
|
|
- // 示例:不同品种对应不同的子品种列表
|
|
|
};
|
|
|
|
|
|
// 品种2变化时,触发验证
|
|
|
-const handleVariety2Change = () => {
|
|
|
+const handleFruitsChange = () => {
|
|
|
nextTick(() => {
|
|
|
- formRef.value?.validateField("variety");
|
|
|
+ // 校验农场品种(包含大类和品种)
|
|
|
+ formRef.value?.validateField("speciesId");
|
|
|
});
|
|
|
};
|
|
|
|
|
|
+// 农场名称输入时,标记为用户已手动修改
|
|
|
+const handleNameInput = () => {
|
|
|
+ isNameEdited.value = true;
|
|
|
+};
|
|
|
+
|
|
|
// 确认信息
|
|
|
const handleConfirm = async () => {
|
|
|
- if (!formRef.value) return;
|
|
|
+ // 第一步:验证农场信息表单
|
|
|
+ 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();
|
|
|
+ // 验证通过,提交所有数据并关闭弹窗
|
|
|
+ emit("confirm", {
|
|
|
+ ...formData.value,
|
|
|
+ ...phenologyData.value,
|
|
|
+ wkt: store.state.home.miniUserLocationPoint,
|
|
|
+ expertMiniUserId: props.expertMiniUserId,
|
|
|
+ containerId: specieList.value.find(item => item.id === formData.value.speciesId)?.defaultContainerId,
|
|
|
+ });
|
|
|
+ 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;
|
|
|
+ }
|
|
|
+};
|
|
|
+
|
|
|
+// 获取当前和下一个物候期
|
|
|
+const getCurrentAndNextPhenology = async () => {
|
|
|
try {
|
|
|
- await formRef.value.validate();
|
|
|
- emit("confirm", { ...formData.value });
|
|
|
- emit("update:show", false);
|
|
|
+ const { data } = await VE_API.home.getCurrentAndNextPhenology({
|
|
|
+ expertMiniUserId: props.expertMiniUserId,
|
|
|
+ containerId: specieList.value.find(item => item.id === formData.value.speciesId)?.defaultContainerId,
|
|
|
+ });
|
|
|
+ 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.log("表单验证失败", error);
|
|
|
+ console.error("获取物候期数据失败", error);
|
|
|
+ ElMessage.error("获取物候期数据失败");
|
|
|
}
|
|
|
};
|
|
|
</script>
|