|
|
@@ -0,0 +1,434 @@
|
|
|
+<template>
|
|
|
+ <el-dialog v-model="visible" :title="form.name || '编辑农事'" width="720px" class="farm-work-edit-dialog"
|
|
|
+ :close-on-click-modal="false" align-center append-to-body @closed="onClosed">
|
|
|
+ <el-form ref="formRef" :model="form" label-width="96px" class="farm-work-form">
|
|
|
+ <el-form-item label="农事类型:">
|
|
|
+ <div class="type-select">
|
|
|
+ <span v-for="item in form.types" :key="item" class="type-select__tag">{{ item }}</span>
|
|
|
+ </div>
|
|
|
+ </el-form-item>
|
|
|
+
|
|
|
+ <el-form-item label="触发条件:">
|
|
|
+ <el-input v-model="form.trigger" placeholder="请输入触发条件" />
|
|
|
+ </el-form-item>
|
|
|
+
|
|
|
+ <el-form-item label="药肥处方:">
|
|
|
+ <div class="prescription-block">
|
|
|
+ <el-button class="add-btn" @click="addPrescription">+ 添加处方</el-button>
|
|
|
+ <div class="prescription-list">
|
|
|
+ <div v-for="(item, idx) in form.prescriptions" :key="idx" class="prescription-card">
|
|
|
+ <div class="prescription-card__head">
|
|
|
+ <el-input v-model="item.category" placeholder="请输入类型" />
|
|
|
+ <el-button link class="del-btn" @click="removePrescription(idx)">删除</el-button>
|
|
|
+ </div>
|
|
|
+ <el-input v-model="item.desc" placeholder="请输入具体处方" />
|
|
|
+ <el-input v-model="item.freq" placeholder="请输入使用频次" />
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </el-form-item>
|
|
|
+
|
|
|
+ <div class="section-title">执行规程</div>
|
|
|
+
|
|
|
+ <el-form-item label="执行窗口:">
|
|
|
+ <div class="inline-fields">
|
|
|
+ <div class="prefix-select">
|
|
|
+ <span class="prefix-select__label">起始时期:</span>
|
|
|
+ <el-select
|
|
|
+ v-model="form.execute.startPeriod"
|
|
|
+ class="prefix-select__inner"
|
|
|
+ multiple
|
|
|
+ :multiple-limit="1"
|
|
|
+ placeholder="请选择"
|
|
|
+ >
|
|
|
+ <el-option
|
|
|
+ v-for="item in periodOptions"
|
|
|
+ :key="item"
|
|
|
+ :label="item"
|
|
|
+ :value="item"
|
|
|
+ />
|
|
|
+ </el-select>
|
|
|
+ </div>
|
|
|
+ <div class="prefix-select">
|
|
|
+ <span class="prefix-select__label">截至时期:</span>
|
|
|
+ <el-select
|
|
|
+ v-model="form.execute.endPeriod"
|
|
|
+ class="prefix-select__inner"
|
|
|
+ multiple
|
|
|
+ :multiple-limit="1"
|
|
|
+ placeholder="请选择"
|
|
|
+ >
|
|
|
+ <el-option
|
|
|
+ v-for="item in periodOptions"
|
|
|
+ :key="item"
|
|
|
+ :label="item"
|
|
|
+ :value="item"
|
|
|
+ />
|
|
|
+ </el-select>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </el-form-item>
|
|
|
+
|
|
|
+ <el-form-item label="执行设备:">
|
|
|
+ <div class="inline-fields">
|
|
|
+ <div class="prefix-select">
|
|
|
+ <span class="prefix-select__label">主要设备:</span>
|
|
|
+ <el-select
|
|
|
+ v-model="form.execute.primaryDevices"
|
|
|
+ class="prefix-select__inner"
|
|
|
+ multiple
|
|
|
+ placeholder="请选择"
|
|
|
+ >
|
|
|
+ <el-option
|
|
|
+ v-for="item in deviceOptions"
|
|
|
+ :key="item"
|
|
|
+ :label="item"
|
|
|
+ :value="item"
|
|
|
+ />
|
|
|
+ </el-select>
|
|
|
+ </div>
|
|
|
+ <div class="prefix-select">
|
|
|
+ <span class="prefix-select__label">备用设备:</span>
|
|
|
+ <el-select
|
|
|
+ v-model="form.execute.backupDevices"
|
|
|
+ class="prefix-select__inner"
|
|
|
+ multiple
|
|
|
+ placeholder="请选择"
|
|
|
+ >
|
|
|
+ <el-option
|
|
|
+ v-for="item in deviceOptions"
|
|
|
+ :key="item"
|
|
|
+ :label="item"
|
|
|
+ :value="item"
|
|
|
+ />
|
|
|
+ </el-select>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </el-form-item>
|
|
|
+
|
|
|
+ <el-form-item label="注意事项:">
|
|
|
+ <el-input v-model="form.execute.notes" placeholder="请输入注意事项" />
|
|
|
+ </el-form-item>
|
|
|
+
|
|
|
+ <div class="section-title">复核规程</div>
|
|
|
+
|
|
|
+ <el-form-item label="复核时间:">
|
|
|
+ <div class="review-time-field">
|
|
|
+ <span>执行后</span>
|
|
|
+ <el-select v-model="form.review.days" class="review-time-field__select">
|
|
|
+ <el-option v-for="n in 30" :key="n" :label="String(n)" :value="n" />
|
|
|
+ </el-select>
|
|
|
+ <span class="unit">天</span>
|
|
|
+ </div>
|
|
|
+ </el-form-item>
|
|
|
+
|
|
|
+ <el-form-item label="复核标准:">
|
|
|
+ <el-input v-model="form.review.standard" placeholder="请输入复核标准" />
|
|
|
+ </el-form-item>
|
|
|
+ </el-form>
|
|
|
+
|
|
|
+ <template #footer>
|
|
|
+ <div class="dialog-footer">
|
|
|
+ <el-button @click="visible = false">取消</el-button>
|
|
|
+ <el-button type="warning" @click="onSubmit">提交</el-button>
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+ </el-dialog>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script setup>
|
|
|
+import { computed, reactive, ref, watch } from "vue";
|
|
|
+import { ElMessage } from "element-plus";
|
|
|
+
|
|
|
+const props = defineProps({
|
|
|
+ modelValue: { type: Boolean, default: false },
|
|
|
+ data: { type: Object, default: null },
|
|
|
+});
|
|
|
+
|
|
|
+const emit = defineEmits(["update:modelValue", "submit"]);
|
|
|
+
|
|
|
+const visible = computed({
|
|
|
+ get: () => props.modelValue,
|
|
|
+ set: (val) => emit("update:modelValue", val),
|
|
|
+});
|
|
|
+
|
|
|
+const formRef = ref(null);
|
|
|
+const periodOptions = ["生育期一", "生育期二", "生育期三", "生育起始", "生育结束"];
|
|
|
+const deviceOptions = ["农机设备一", "农机设备二", "设备一", "设备二"];
|
|
|
+
|
|
|
+const createDefaultForm = () => ({
|
|
|
+ name: "播前基肥",
|
|
|
+ types: ["标准农事", "日常营养", "水肥类"],
|
|
|
+ trigger: "",
|
|
|
+ prescriptions: [
|
|
|
+ { category: "营养类", desc: "具体处方", freq: "频次" },
|
|
|
+ { category: "", desc: "", freq: "" },
|
|
|
+ ],
|
|
|
+ execute: {
|
|
|
+ startPeriod: ["生育期一"],
|
|
|
+ endPeriod: ["生育期二"],
|
|
|
+ primaryDevices: ["农机设备一"],
|
|
|
+ backupDevices: ["农机设备一", "农机设备二"],
|
|
|
+ notes: "",
|
|
|
+ },
|
|
|
+ review: {
|
|
|
+ days: 7,
|
|
|
+ standard: "",
|
|
|
+ },
|
|
|
+});
|
|
|
+
|
|
|
+const form = reactive(createDefaultForm());
|
|
|
+
|
|
|
+const fillForm = (row) => {
|
|
|
+ Object.assign(form, createDefaultForm());
|
|
|
+ if (!row) return;
|
|
|
+ form.name = row.name || "播前基肥";
|
|
|
+ form.types = [...(row.types || ["标准农事", "日常营养", "水肥类"])];
|
|
|
+ form.trigger = row.trigger || "";
|
|
|
+ form.prescriptions = row.prescription
|
|
|
+ ? [
|
|
|
+ {
|
|
|
+ category: row.prescription.category || "",
|
|
|
+ desc: row.prescription.desc || "",
|
|
|
+ freq: row.prescription.freq || "",
|
|
|
+ },
|
|
|
+ { category: "", desc: "", freq: "" },
|
|
|
+ ]
|
|
|
+ : createDefaultForm().prescriptions;
|
|
|
+ form.execute.startPeriod = ["生育期一"];
|
|
|
+ form.execute.endPeriod = ["生育期二"];
|
|
|
+ form.execute.primaryDevices = [...(row.execute?.primaryDevices || ["农机设备一"])];
|
|
|
+ form.execute.backupDevices = [
|
|
|
+ ...(row.execute?.backupDevices || ["农机设备一", "农机设备二"]),
|
|
|
+ ];
|
|
|
+ form.execute.notes = row.execute?.notes || "";
|
|
|
+ form.review.days = row.review?.days || 7;
|
|
|
+ form.review.standard = row.review?.standard || "";
|
|
|
+};
|
|
|
+
|
|
|
+watch(
|
|
|
+ () => props.modelValue,
|
|
|
+ (val) => {
|
|
|
+ if (val) fillForm(props.data);
|
|
|
+ }
|
|
|
+);
|
|
|
+
|
|
|
+const addPrescription = () => {
|
|
|
+ form.prescriptions.push({ category: "", desc: "", freq: "" });
|
|
|
+};
|
|
|
+
|
|
|
+const removePrescription = (idx) => {
|
|
|
+ if (form.prescriptions.length <= 1) {
|
|
|
+ ElMessage.warning("至少保留一条处方");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ form.prescriptions.splice(idx, 1);
|
|
|
+};
|
|
|
+
|
|
|
+const onClosed = () => {
|
|
|
+ Object.assign(form, createDefaultForm());
|
|
|
+};
|
|
|
+
|
|
|
+const onSubmit = () => {
|
|
|
+ emit("submit", JSON.parse(JSON.stringify(form)));
|
|
|
+ visible.value = false;
|
|
|
+ ElMessage.success("提交成功");
|
|
|
+};
|
|
|
+</script>
|
|
|
+
|
|
|
+<style lang="scss" scoped>
|
|
|
+.farm-work-form {
|
|
|
+ margin: 0 -16px;
|
|
|
+ padding: 20px 20px;
|
|
|
+ border-top: 1px solid #e5e6eb;
|
|
|
+
|
|
|
+ :deep(.el-form-item__label) {
|
|
|
+ color: #1d2129;
|
|
|
+ }
|
|
|
+
|
|
|
+ .type-select {
|
|
|
+ display: flex;
|
|
|
+ flex-wrap: wrap;
|
|
|
+ gap: 8px;
|
|
|
+
|
|
|
+ &__tag {
|
|
|
+ padding: 0 6px;
|
|
|
+ border-radius: 2px;
|
|
|
+ font-size: 12px;
|
|
|
+ color: #FB8E33;
|
|
|
+ background: rgba(251, 142, 51, 0.1);
|
|
|
+ line-height: 24px;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .prescription-block {
|
|
|
+ width: 100%;
|
|
|
+ }
|
|
|
+
|
|
|
+ .add-btn {
|
|
|
+ color: $warning-color;
|
|
|
+ background: rgba($warning-color, 0.1);
|
|
|
+ border-color: transparent;
|
|
|
+ margin-bottom: 10px;
|
|
|
+ font-weight: 400;
|
|
|
+ font-size: 12px;
|
|
|
+
|
|
|
+ &:hover {
|
|
|
+ color: $warning-color;
|
|
|
+ background: rgba($warning-color, 0.16);
|
|
|
+ border-color: transparent;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .prescription-list {
|
|
|
+ display: grid;
|
|
|
+ grid-template-columns: 1fr 1fr;
|
|
|
+ gap: 10px;
|
|
|
+
|
|
|
+ .prescription-card {
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ gap: 5px;
|
|
|
+ padding: 6px;
|
|
|
+ border: 0.5px solid #E3E3E3;
|
|
|
+ border-radius: 5px;
|
|
|
+
|
|
|
+ &__head {
|
|
|
+ display: flex;
|
|
|
+ gap: 15px;
|
|
|
+ align-items: center;
|
|
|
+
|
|
|
+ .del-btn {
|
|
|
+ color: $warning-color;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .section-title {
|
|
|
+ padding-top: 10px;
|
|
|
+ margin-bottom: 16px;
|
|
|
+ padding-left: 12px;
|
|
|
+ font-weight: 500;
|
|
|
+ color: $warning-color;
|
|
|
+ }
|
|
|
+
|
|
|
+ .inline-fields {
|
|
|
+ display: flex;
|
|
|
+ align-items: flex-start;
|
|
|
+ gap: 12px;
|
|
|
+ width: 100%;
|
|
|
+ }
|
|
|
+
|
|
|
+ .prefix-select {
|
|
|
+ flex: 1;
|
|
|
+ min-width: 0;
|
|
|
+ display: flex;
|
|
|
+ align-items: flex-start;
|
|
|
+ gap: 4px;
|
|
|
+ min-height: 32px;
|
|
|
+ padding: 3px 8px 3px 12px;
|
|
|
+ border: 1px solid #dcdfe6;
|
|
|
+ border-radius: 4px;
|
|
|
+ background: #fff;
|
|
|
+ box-sizing: border-box;
|
|
|
+ transition: border-color 0.2s;
|
|
|
+
|
|
|
+ &:hover {
|
|
|
+ border-color: #c0c4cc;
|
|
|
+ }
|
|
|
+
|
|
|
+ &:focus-within {
|
|
|
+ border-color: $warning-color;
|
|
|
+ }
|
|
|
+
|
|
|
+ &__label {
|
|
|
+ flex-shrink: 0;
|
|
|
+ padding-top: 3px;
|
|
|
+ font-size: 13px;
|
|
|
+ line-height: 22px;
|
|
|
+ color: #86909c;
|
|
|
+ white-space: nowrap;
|
|
|
+ }
|
|
|
+
|
|
|
+ &__inner {
|
|
|
+ flex: 1;
|
|
|
+ min-width: 0;
|
|
|
+
|
|
|
+ :deep(.el-select__wrapper) {
|
|
|
+ min-height: 24px;
|
|
|
+ padding: 0;
|
|
|
+ background: transparent;
|
|
|
+ box-shadow: none !important;
|
|
|
+ gap: 4px;
|
|
|
+ }
|
|
|
+
|
|
|
+ :deep(.el-select__selection) {
|
|
|
+ flex-wrap: wrap;
|
|
|
+ gap: 4px;
|
|
|
+ }
|
|
|
+
|
|
|
+ :deep(.el-select__selected-item) {
|
|
|
+ max-width: 100%;
|
|
|
+ }
|
|
|
+
|
|
|
+ :deep(.el-select__input-wrapper) {
|
|
|
+ margin-left: 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ :deep(.el-tag) {
|
|
|
+ max-width: 100%;
|
|
|
+ height: 22px;
|
|
|
+ margin: 0;
|
|
|
+ padding: 0 6px;
|
|
|
+ background: #f2f3f5;
|
|
|
+ border: none;
|
|
|
+ border-radius: 4px;
|
|
|
+ color: #4e5969;
|
|
|
+
|
|
|
+ .el-tag__close {
|
|
|
+ color: #86909c;
|
|
|
+
|
|
|
+ &:hover {
|
|
|
+ background: transparent;
|
|
|
+ color: #4e5969;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ :deep(.el-select__caret) {
|
|
|
+ color: #86909c;
|
|
|
+ }
|
|
|
+
|
|
|
+ :deep(.el-select__suffix) {
|
|
|
+ align-self: flex-start;
|
|
|
+ height: 24px;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .review-time-field {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ gap: 8px;
|
|
|
+
|
|
|
+ &__select {
|
|
|
+ width: 80px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .unit {
|
|
|
+ color: rgba(0, 0, 0, 0.2);
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+.dialog-footer {
|
|
|
+ display: flex;
|
|
|
+ justify-content: center;
|
|
|
+ gap: 8px;
|
|
|
+ margin: 0 -16px;
|
|
|
+ padding: 12px 16px 0;
|
|
|
+ border-top: 1px solid #e5e6eb;
|
|
|
+ box-sizing: border-box;
|
|
|
+}
|
|
|
+</style>
|