addWork.vue 61 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891
  1. <template>
  2. <div class="new-farming-page" ref="pageRef">
  3. <custom-header name="新增农事"></custom-header>
  4. <div class="new-farming-content">
  5. <el-form
  6. ref="formRef"
  7. style="max-width: 600px"
  8. label-position="left"
  9. :rules="rules"
  10. :model="dynamicValidateForm"
  11. class="demo-dynamic"
  12. >
  13. <div class="farm-card">
  14. <div class="card-title between">
  15. 基本信息
  16. <div>
  17. <el-select size="small" v-model="tagName" placeholder="标记为" style="width: 94px">
  18. <el-option
  19. v-for="item in tagList"
  20. :key="item.value"
  21. :label="item.label"
  22. :value="item.value"
  23. />
  24. </el-select>
  25. </div>
  26. </div>
  27. <div class="info-content">
  28. <el-form-item label-width="82px" class="form-item name-item" prop="name" label="农事名称">
  29. <el-input
  30. v-model="dynamicValidateForm.name"
  31. style="width: 100%"
  32. placeholder="请输入农事名称"
  33. />
  34. </el-form-item>
  35. <el-form-item label-width="82px" class="form-item" prop="executeDate" label="执行时间">
  36. <el-date-picker
  37. v-model="dynamicValidateForm.executeDate"
  38. value-format="YYYY-MM-DD"
  39. type="date"
  40. placeholder="请选择执行时间"
  41. style="width: 100%"
  42. :editable="false"
  43. />
  44. </el-form-item>
  45. </div>
  46. </div>
  47. <div class="farm-card">
  48. <!-- 农情互动 -->
  49. <div class="card-title border-bottom between">
  50. <div>农情互动</div>
  51. <!-- <span class="del-tag">删除互动</span> -->
  52. </div>
  53. <div class="interact-form">
  54. <div class="interact-form-item" data-interact-field="phenologyId">
  55. <div class="form-label">互动阶段</div>
  56. <div class="form-input-wrapper two-select">
  57. <div class="select-item">
  58. <el-select
  59. style="width: 100%"
  60. v-model="interactFormData.phenologyId"
  61. placeholder="请选择物候期"
  62. @change="handlePhenologyChange"
  63. :editable="false">
  64. <el-option
  65. v-for="item in phenologyList"
  66. :key="item.id"
  67. :label="item.name"
  68. :value="item.id"
  69. ></el-option>
  70. </el-select>
  71. </div>
  72. <div class="select-item">
  73. <el-select style="width: 100%" v-model="interactFormData.reproductiveId" placeholder="请选择物候期" :editable="false">
  74. <el-option
  75. v-for="item in reproductiveList"
  76. :key="item.id"
  77. :label="item.name"
  78. :value="item.id"
  79. ></el-option>
  80. </el-select>
  81. </div>
  82. </div>
  83. </div>
  84. <!-- <div class="interact-form-item" data-interact-field="interactionTime">
  85. <div class="form-label">互动日期</div>
  86. <div class="form-input-wrapper">
  87. <el-date-picker
  88. v-model="interactFormData.interactionTime"
  89. style="width: 100%"
  90. type="date"
  91. placeholder="请选择日期"
  92. :editable="false"
  93. />
  94. </div>
  95. </div> -->
  96. <div class="interact-form-item" data-interact-field="interactionQuestion">
  97. <div class="form-label">互动问题</div>
  98. <el-input
  99. v-model="interactFormData.interactionQuestion"
  100. type="textarea"
  101. :rows="4"
  102. placeholder="请设置互动问题"
  103. class="question-textarea"
  104. />
  105. </div>
  106. </div>
  107. </div>
  108. <div class="farm-card prescription-content common-inputs">
  109. <div class="card-title pb-12 between">
  110. 药物处方
  111. <div class="add-tag" @click="addDomain()">
  112. <el-icon color="#2199F8"><Plus /></el-icon>新增药物
  113. </div>
  114. </div>
  115. <el-form-item label-width="82px" class="form-item" prop="usageMode" label="施用方式">
  116. <el-select
  117. v-model="dynamicValidateForm.usageMode"
  118. placeholder="请选择施用方式"
  119. style="width: 100%"
  120. >
  121. <el-option
  122. v-for="(usage, uId) in allUsageModeList"
  123. :key="uId"
  124. :label="usage"
  125. :value="usage"
  126. />
  127. </el-select>
  128. </el-form-item>
  129. <el-form-item
  130. label-width="82px"
  131. class="form-item"
  132. prop="executeStyle"
  133. label="执行方式"
  134. >
  135. <el-select
  136. class="select-item"
  137. v-model="dynamicValidateForm.executeStyle"
  138. placeholder="执行方式"
  139. @change="handleExecutionMethodChange"
  140. >
  141. <el-option
  142. v-for="(item, index) in modeList"
  143. :key="index"
  144. :label="item.name"
  145. :value="item.value"
  146. />
  147. </el-select>
  148. </el-form-item>
  149. <div v-if="dynamicValidateForm.usageMode !== '人工'">
  150. <el-form-item
  151. v-for="(domain, index) in dynamicValidateForm.prescription.pesticideFertilizerList"
  152. :key="index"
  153. :prop="'prescription.pesticideFertilizerList.' + index + '.value'"
  154. class="prescription-item"
  155. >
  156. <div class="recipe-item">
  157. <div class="recipe-form">
  158. <div class="form-box">
  159. <div class="form-index">药肥{{ index + 1 }}</div>
  160. <div class="box-item" v-if="domain.typeName">
  161. <div class="form-l">药肥类型</div>
  162. <div class="form-r r-text">
  163. {{ domain.typeName }}
  164. </div>
  165. </div>
  166. <div class="box-item">
  167. <div class="form-l">药肥名称</div>
  168. <div class="form-r">
  169. <el-select
  170. filterable
  171. @change="handlePesticideFertilizerChange(index)"
  172. v-model="domain.code"
  173. placeholder="请选择"
  174. style="width: 150px"
  175. >
  176. <el-option
  177. v-for="item in pesticideFertilizersOptions"
  178. :key="item.pesticideFertilizerCode"
  179. :label="item.defaultName || item.name"
  180. :value="item.pesticideFertilizerCode"
  181. />
  182. </el-select>
  183. </div>
  184. </div>
  185. <div class="mt-8">
  186. <div class="box-item sub-item" :data-ratio-index="index">
  187. <div class="form-l has-sub">
  188. <div class="main-name">药肥配比</div>
  189. </div>
  190. <div class="form-r input-box text-center input-unit">
  191. <el-input
  192. v-model="domain.ratio"
  193. type="number"
  194. step="0.01"
  195. style="width: 150px"
  196. placeholder="请输入"
  197. >
  198. <template #append>倍</template>
  199. </el-input>
  200. </div>
  201. </div>
  202. <div class="box-item sub-item" :data-dosage-index="index">
  203. <div class="form-l has-sub">
  204. <div class="main-name">单亩用量</div>
  205. </div>
  206. <div class="form-r input-box text-center">
  207. <el-input
  208. v-model="domain.dosage"
  209. type="number"
  210. step="0.01"
  211. style="width: 150px"
  212. placeholder="请输入"
  213. >
  214. <template #append>{{ domain.unit }}</template>
  215. </el-input>
  216. </div>
  217. </div>
  218. <div class="box-item">
  219. <div class="form-l">药肥品牌</div>
  220. <div class="form-r">
  221. <el-input
  222. v-model="domain.brand"
  223. placeholder="药肥品牌"
  224. style="width: 150px"
  225. />
  226. </div>
  227. </div>
  228. <div class="box-item">
  229. <div class="form-l">药肥单价</div>
  230. <div class="form-r">
  231. <el-input
  232. style="width: 150px"
  233. v-model="domain.price"
  234. type="number"
  235. step="0.01"
  236. placeholder="单价"
  237. >
  238. <template #append>元/{{ domain.unit }}</template>
  239. </el-input>
  240. </div>
  241. </div>
  242. </div>
  243. <!-- <div class="input-box mark-box">
  244. <el-input
  245. v-model="domain.remark"
  246. style="width: 100%"
  247. placeholder="备注:用药注意事项"
  248. />
  249. </div> -->
  250. <div class="action-btn">
  251. <el-button
  252. class="btn delete-btn"
  253. @click.prevent="removeDomain(prescriptionI, domain)"
  254. >
  255. 删除
  256. </el-button>
  257. <el-button
  258. type="default"
  259. class="btn"
  260. @click.prevent="resetItemForm(prescriptionI, index)"
  261. >
  262. 重置
  263. </el-button>
  264. </div>
  265. </div>
  266. <!-- </el-form-item> -->
  267. </div>
  268. </div>
  269. </el-form-item>
  270. </div>
  271. </div>
  272. <div
  273. class="farm-card prescription-content common-inputs"
  274. >
  275. <div class="medicine-wrap">
  276. <div class="medicine-box">
  277. <div class="form-index">服务报价</div>
  278. <div class="box-wrap">
  279. <div class="medicine-item mt-8">
  280. <div class="item-name">单亩价格</div>
  281. <div class="item-val">
  282. <el-input
  283. style="width: 150px"
  284. v-model="servicePricePerMu"
  285. type="number"
  286. step="0.01"
  287. placeholder="服务单价"
  288. >
  289. <template #append>元/亩</template>
  290. </el-input>
  291. </div>
  292. </div>
  293. </div>
  294. </div>
  295. </div>
  296. </div>
  297. <div class="submit-btn">
  298. <div class="btn second" @click.prevent="cancelEdit">取消</div>
  299. <div class="btn" @click.prevent="submitForm(formRef)">保存</div>
  300. </div>
  301. </el-form>
  302. </div>
  303. </div>
  304. </template>
  305. <script setup>
  306. import { onActivated, ref, reactive, onDeactivated, onBeforeUnmount, computed, onMounted, nextTick } from "vue";
  307. import { useRouter, useRoute } from "vue-router";
  308. import { ElMessage, ElMessageBox } from "element-plus";
  309. import customHeader from "@/components/customHeader.vue";
  310. import { useStore } from "vuex";
  311. import { formatArea } from "@/common/commonFun";
  312. import interactPopup from "@/components/popup/interactPopup.vue";
  313. import dayjs from "dayjs";
  314. const store = useStore();
  315. const pageRef = ref(null);
  316. const router = useRouter();
  317. const route = useRoute();
  318. const tagList = ref([
  319. { label: "托管农事", value: 2 },
  320. { label: "特别关注", value: 1 },
  321. ]);
  322. const tagName = ref("");
  323. // 互动表单数据
  324. const interactFormData = ref({
  325. phenologyId: "",
  326. reproductiveId: "",
  327. // interactionTime: "",
  328. interactionQuestion: "",
  329. });
  330. const phenologyList = ref([]);
  331. const reproductiveList = ref([]);
  332. const handlePhenologyChange = async (val) => {
  333. interactFormData.value.reproductiveId = "";
  334. const { data } = await VE_API.farm.listByPhenologyId({ phenologyId: val });
  335. if (!data || !Array.isArray(data)) return;
  336. reproductiveList.value = data;
  337. };
  338. onMounted(() => {
  339. getPhenologyList()
  340. });
  341. const statusMap = ref({
  342. 0: "取消关注",
  343. 1: "特别关注",
  344. 2: "托管农事",
  345. });
  346. const detailData = ref({});
  347. const getPriceList = async (schemeId, pesticideFertilizerCodes) => {
  348. const { data } = await VE_API.farm.getPriceList({ schemeId, pesticideFertilizerCodes });
  349. if (!data || !Array.isArray(data)) return;
  350. dynamicValidateForm.prescription.pesticideFertilizerList.forEach((item) => {
  351. const priceInfo = data.find((p) => p.pesticideFertilizerCode === item.code);
  352. if (!priceInfo) return;
  353. item.price = priceInfo.price ?? item.price;
  354. item.brand = priceInfo.brand ?? item.brand;
  355. });
  356. quotationData.value = { ...detailData.value, ...dynamicValidateForm };
  357. };
  358. const quotationData = ref({});
  359. // 计算单个药肥的总计:单价 * 单亩用量 * 亩数
  360. const getPesticideTotal = (pesticide) => {
  361. const price = Number(pesticide.price || 0);
  362. const dosage = Number(pesticide.dosage || 0); // 单亩用量
  363. const area = Number(detailData.value.farm?.mianji || 0); // 农场面积
  364. if (!price || !dosage || !area) return "--";
  365. const total = (price * dosage * area).toFixed(2);
  366. return total;
  367. };
  368. function getServiceCost(cost, area) {
  369. if (!cost || !area) return "--";
  370. return (parseFloat(cost) * parseFloat(area)).toFixed(2);
  371. }
  372. const resetForm = (formEl) => {
  373. if (!formEl) return;
  374. formEl.resetFields();
  375. };
  376. // 清空所有数据
  377. const clearData = () => {
  378. // 清空表单
  379. resetForm(formRef.value);
  380. // 清空详情数据
  381. detailData.value = {};
  382. // 清空表单数据
  383. dynamicValidateForm.name = "";
  384. dynamicValidateForm.purpose = "";
  385. dynamicValidateForm.executeDate = dayjs().format("YYYY-MM-DD");
  386. dynamicValidateForm.usageMode = "";
  387. dynamicValidateForm.prescription = {
  388. id: "",
  389. usageMode: "",
  390. farmWorkLibCode: "",
  391. expertId: "",
  392. phenology: "",
  393. soil: "",
  394. speed: null,
  395. pesticideFertilizerList: [
  396. {
  397. code: "",
  398. name: "",
  399. dosage: "",
  400. ratio: "",
  401. typeName: "",
  402. muPrice: 0,
  403. executeStyle: 1,
  404. unit: "",
  405. },
  406. ],
  407. };
  408. };
  409. onDeactivated(() => {
  410. clearData();
  411. });
  412. onBeforeUnmount(() => {
  413. clearData();
  414. });
  415. const cancelEdit = () => {
  416. router.back();
  417. };
  418. const modeList = ref([
  419. { name: "无人机", value: 1 },
  420. { name: "人工", value: 2 },
  421. { name: "无人机+人工", value: 3 },
  422. ]);
  423. const handleExecutionMethodChange = (index, val) => {
  424. // if (val == 1) {
  425. // servicePricePerMu.value = detailData.value.uavServicePrice;
  426. // } else {
  427. // servicePricePerMu.value = detailData.value.manualServicePrice;
  428. // }
  429. };
  430. // 表单
  431. const formRef = ref();
  432. const dynamicValidateForm = reactive({
  433. name: "",
  434. executeDate: dayjs().format("YYYY-MM-DD"),
  435. usageMode: "",
  436. executeStyle: 2,
  437. executionMethod: 2,
  438. prescription: {
  439. id: "",
  440. usageMode: "",
  441. farmWorkLibCode: "",
  442. expertId: "",
  443. phenology: "",
  444. soil: "",
  445. speed: null,
  446. pesticideFertilizerList: [
  447. {
  448. code: "",
  449. id: "",
  450. name: "",
  451. dosage: "",
  452. ratio: "",
  453. typeName: "",
  454. muPrice: 0,
  455. executeStyle: 1,
  456. unit: "",
  457. },
  458. ],
  459. },
  460. });
  461. const rules = {
  462. name: [
  463. {
  464. required: true,
  465. message: "请输入农事名称",
  466. trigger: "blur",
  467. },
  468. ],
  469. executeDate: [
  470. {
  471. required: false,
  472. message: "请选择执行时间",
  473. trigger: "blur",
  474. },
  475. ],
  476. };
  477. const addDomain = () => {
  478. if (!dynamicValidateForm.prescription.pesticideFertilizerList) {
  479. dynamicValidateForm.prescription.pesticideFertilizerList = [];
  480. }
  481. dynamicValidateForm.prescription.pesticideFertilizerList.unshift({
  482. code: "",
  483. name: "",
  484. dosage: "",
  485. ratio: "",
  486. typeName: "",
  487. muPrice: 0,
  488. id: "",
  489. executeStyle: 1,
  490. unit: "",
  491. });
  492. };
  493. let pesticideFertilizersOptions = ref([]);
  494. VE_API.z_farm_work_order.pesticideFertilizersList().then(({ data }) => {
  495. pesticideFertilizersOptions.value = data;
  496. });
  497. const allUsageModeList = ["树冠+内膛", "地面喷施", "树冠喷施", "根部施", "叶面施", "内膛喷施", "其他"];
  498. /**
  499. * 选择药肥的时候修改订单中药肥pesticideFertilizerId 以外其他数据
  500. * @param index
  501. */
  502. const handlePesticideFertilizerChange = (index) => {
  503. const currentItem = dynamicValidateForm.prescription.pesticideFertilizerList[index];
  504. let obj = pesticideFertilizersOptions.value.filter((item) => currentItem.code === item.pesticideFertilizerCode)[0];
  505. if (obj) {
  506. dynamicValidateForm.prescription.pesticideFertilizerList[index] = {
  507. ...currentItem,
  508. code: obj.pesticideFertilizerCode,
  509. id: obj.id,
  510. name: obj.name || obj.defaultName,
  511. typeName: obj.typeName,
  512. unit: obj.unit,
  513. ratio: "", // 清空亩兑水量
  514. dosage: "", // 清空单亩用量
  515. executeStyle: obj.executionMethod || 1,
  516. };
  517. }
  518. };
  519. const removeDomain = (index) => {
  520. if (index !== -1 && dynamicValidateForm.prescription.pesticideFertilizerList) {
  521. dynamicValidateForm.prescription.pesticideFertilizerList.splice(index, 1);
  522. }
  523. };
  524. const resetItemForm = (index) => {
  525. if (dynamicValidateForm.prescription.pesticideFertilizerList) {
  526. dynamicValidateForm.prescription.pesticideFertilizerList[index] = {
  527. code: "",
  528. id: "",
  529. name: "",
  530. dosage: "",
  531. ratio: "",
  532. typeName: "",
  533. muPrice: 0,
  534. executeStyle: 1,
  535. unit: "",
  536. };
  537. }
  538. };
  539. const servicePricePerMu = ref(null);
  540. // 服务费用总计(数值):亩单价 * 亩数
  541. const serviceCostTotal = computed(() => {
  542. const price = Number(servicePricePerMu.value || 0);
  543. const area = Number(detailData.value?.farm?.mianji || detailData.value?.area || 0);
  544. if (!price || !area) return 0;
  545. return Number((price * area).toFixed(2));
  546. });
  547. // 显示用的服务费用(字符串或 "--")
  548. const getServiceTotal = () => {
  549. const total = serviceCostTotal.value;
  550. return total ? total.toFixed(2) : "--";
  551. };
  552. // 药肥费用总计:∑(单价 * 单亩用量 * 亩数)
  553. const pesticideCostTotal = computed(() => {
  554. const list = dynamicValidateForm.prescription?.pesticideFertilizerList || [];
  555. const area = Number(detailData.value?.farm?.mianji || detailData.value?.area || 0);
  556. if (!list.length || !area) return 0;
  557. const sum = list.reduce((acc, item) => {
  558. const price = Number(item?.price || 0);
  559. const dosage = Number(item?.dosage || 0);
  560. if (!price || !dosage) return acc;
  561. return acc + price * dosage * area;
  562. }, 0);
  563. return Number(sum.toFixed(2));
  564. });
  565. // 报价合计 = 药肥费用 + 服务费用
  566. const totalCost = computed(() => {
  567. const pesticide = Number(pesticideCostTotal.value || 0);
  568. const service = Number(serviceCostTotal.value || 0);
  569. if (!pesticide && !service) return '--';
  570. return Number((pesticide + service).toFixed(2));
  571. });
  572. const submitForm = (formEl) => {
  573. if (!formEl) return;
  574. formEl.validate(async (valid) => {
  575. if (valid) {
  576. // 校验标记是否已选择
  577. if (!validateTagName()) return;
  578. // 校验农情互动,不通过,直接返回失败
  579. if (!validateInteractForm()) return false;
  580. // 校验药肥的亩兑水量和单亩用量是否填写
  581. if (!validatePesticideDosage()) return;
  582. // 保存报价信息前先校验是否填写完整
  583. if (!validatePriceInfos()) return;
  584. // 检验服务报价是否填写
  585. if (!validateServicePrice()) return;
  586. submit();
  587. } else {
  588. console.log("error submit!");
  589. }
  590. });
  591. };
  592. // 检验服务报价是否填写
  593. const validateServicePrice = () => {
  594. if (!servicePricePerMu.value) {
  595. ElMessage.warning("请完善服务报价信息");
  596. return false;
  597. }
  598. return true;
  599. };
  600. // 校验药肥的亩兑水量和单亩用量是否填写
  601. const validatePesticideDosage = () => {
  602. const list = dynamicValidateForm.prescription?.pesticideFertilizerList || [];
  603. if (!list.length) return true; // 没有药肥就不校验
  604. // 找到第一个未填写完整的药肥
  605. for (let i = 0; i < list.length; i++) {
  606. const item = list[i];
  607. // 如果选择了药肥(有 code),就必须填写亩兑水量和单亩用量
  608. if (item.code) {
  609. const hasRatio = item.ratio !== undefined && item.ratio !== null && item.ratio !== "";
  610. const hasDosage = item.dosage !== undefined && item.dosage !== null && item.dosage !== "";
  611. if (!hasRatio || !hasDosage) {
  612. ElMessage.warning("请完善药物处方信息");
  613. return false;
  614. }
  615. }
  616. }
  617. return true;
  618. };
  619. // 校验报价信息是否填写完整
  620. const validatePriceInfos = () => {
  621. const list = dynamicValidateForm.prescription?.pesticideFertilizerList || [];
  622. if (!list.length) return true; // 没有药肥就不校验
  623. // 找到第一个未填写完整的药肥
  624. const invalidIndex = list.findIndex((item) => {
  625. // 只要选择了药肥(有 id),就必须填写单价和品牌
  626. if (!item.id) return false; // 没选择药肥不校验
  627. const hasPrice = item.price !== undefined && item.price !== null && item.price !== "";
  628. const hasBrand = !!item.brand;
  629. return !hasPrice || !hasBrand;
  630. });
  631. if (invalidIndex !== -1) {
  632. ElMessage.warning("请先完善报价信息");
  633. return false;
  634. }
  635. return true;
  636. };
  637. const submit = async () => {
  638. const params = {
  639. ...dynamicValidateForm,
  640. serviceMuPrice: servicePricePerMu.value,
  641. prescription: dynamicValidateForm.prescription,
  642. };
  643. const { data, code } = await VE_API.monitor.saveFarmWorkLib(params);
  644. if (code === 0) {
  645. handleSaveInteract(data.id);
  646. } else {
  647. ElMessage.error(data.message || "保存失败");
  648. }
  649. // 保存报价信息
  650. const priceList = {
  651. schemeId: route.query.schemeId,
  652. pesticideFertilizerInfos: dynamicValidateForm.prescription.pesticideFertilizerList.map((item) => {
  653. return {
  654. pesticideFertilizerId: item.id,
  655. price: item.price,
  656. brand: item.brand,
  657. };
  658. }),
  659. };
  660. VE_API.farm.updateBatchByScheme(priceList).then(async (res) => {
  661. if (res.code === 0) {
  662. ElMessage.success("保存成功");
  663. router.back();
  664. }
  665. });
  666. // 切换标记
  667. // VE_API.container_farm_work_arrange.toggleFollow({ id: data.id, isFollow: tagName.value });
  668. };
  669. // 获取物候期列表
  670. const getPhenologyList = async () => {
  671. const containerSpaceTimeId = route.query.containerSpaceTimeId;
  672. if (!containerSpaceTimeId) {
  673. phenologyList.value = [];
  674. return;
  675. }
  676. const res = await VE_API.monitor.listPhenology({ containerSpaceTimeId });
  677. if (res.code === 0) {
  678. phenologyList.value = res.data || [];
  679. }
  680. };
  681. // 获取互动设置详情
  682. const getFarmWorkArrangeDetail = async (id) => {
  683. if (!id) return;
  684. const { data, code } = await VE_API.farm.getFarmWorkArrangeDetail({ id });
  685. if (code === 0) {
  686. tagName.value = data.isFollow;
  687. interactFormData.value = {
  688. phenologyId: data.phenologyId || "",
  689. reproductiveId: data.reproductiveId || "",
  690. // interactionTime: data.interactionTime || "",
  691. interactionQuestion: data.interactionQuestion || "",
  692. };
  693. }
  694. };
  695. // 格式化日期
  696. const formatInteractDate = (date) => {
  697. // 如果已经是字符串格式 YYYY-MM-DD,直接返回
  698. if (typeof date === "string" && /^\d{4}-\d{2}-\d{2}$/.test(date)) {
  699. return date;
  700. }
  701. // 如果是 Date 对象,进行转换
  702. if (date instanceof Date) {
  703. let year = date.getFullYear();
  704. let month = String(date.getMonth() + 1).padStart(2, "0");
  705. let day = String(date.getDate()).padStart(2, "0");
  706. return `${year}-${month}-${day}`;
  707. }
  708. // 其他情况返回原值
  709. return date;
  710. };
  711. // 校验标记是否已选择
  712. const validateTagName = () => {
  713. if (tagName.value !== 1 && tagName.value !== 2) {
  714. ElMessage.warning("请选择标记类型");
  715. return false;
  716. }
  717. return true;
  718. };
  719. // 验证互动表单
  720. const validateInteractForm = () => {
  721. if (!interactFormData.value.phenologyId) {
  722. ElMessage.warning("请选择互动阶段");
  723. return false;
  724. }
  725. if (!interactFormData.value.reproductiveId) {
  726. ElMessage.warning("请选择互动阶段");
  727. return false;
  728. }
  729. // if (!interactFormData.value.interactionTime) {
  730. // ElMessage.warning("请选择互动时间");
  731. // return false;
  732. // }
  733. if (!interactFormData.value.interactionQuestion?.trim()) {
  734. ElMessage.warning("请设置互动问题");
  735. return false;
  736. }
  737. return true;
  738. };
  739. // 保存互动设置
  740. const handleSaveInteract = async (id) => {
  741. const paramsObj = {
  742. farmWorkId: id,
  743. schemeId: route.query.schemeId,
  744. ...interactFormData.value,
  745. // interactionTime: formatInteractDate(interactFormData.value.interactionTime),
  746. };
  747. try {
  748. const res = await VE_API.monitor.updateFarmWorkArrange(paramsObj);
  749. if (res.code !== 0) {
  750. ElMessage.error(res.message || "保存农情互动信息失败");
  751. return false;
  752. }
  753. return true;
  754. } catch (error) {
  755. console.error("保存互动设置失败:", error);
  756. ElMessage.error("保存失败,请重试");
  757. return false;
  758. }
  759. };
  760. // 删除互动设置
  761. const handleDeleteInteract = () => {
  762. ElMessageBox.confirm("确定要删除该互动设置吗?", "提示", {
  763. confirmButtonText: "确定",
  764. cancelButtonText: "取消",
  765. type: "warning",
  766. })
  767. .then(async () => {
  768. if (!detailData.value.id) return;
  769. const res = await VE_API.monitor.deleteFarmWorkArrange({ id: detailData.value.id });
  770. if (res.code === 0) {
  771. ElMessage.success("删除成功");
  772. // 清空表单数据
  773. interactFormData.value = {
  774. phenologyId: "",
  775. reproductiveId: "",
  776. // interactionTime: "",
  777. interactionQuestion: "",
  778. };
  779. } else {
  780. ElMessage.error(res.message || "删除失败");
  781. }
  782. })
  783. .catch(() => {
  784. // 用户取消,不做任何操作
  785. });
  786. };
  787. </script>
  788. <style lang="scss" scoped>
  789. .new-farming-page {
  790. height: 100vh;
  791. position: relative;
  792. overflow: auto;
  793. font-size: 14px;
  794. background: #f2f3f5;
  795. ::v-deep {
  796. .custom-header {
  797. position: fixed;
  798. top: 0;
  799. padding-bottom: 1px;
  800. }
  801. }
  802. .step-wrap {
  803. padding: 12px 0;
  804. }
  805. .box-wrap {
  806. background: #fff;
  807. padding: 20px 10px 10px;
  808. border-radius: 6px;
  809. }
  810. .new-farming-content {
  811. margin: 41px 0 62px 0;
  812. padding: 4px 12px 8px 12px;
  813. width: 100%;
  814. box-sizing: border-box;
  815. &.no-permission {
  816. margin-bottom: 12px;
  817. }
  818. // ::v-deep {
  819. // .el-select__input {
  820. // color: #2199F8;
  821. // }
  822. // .el-select__wrapper {
  823. // color: #2199F8;
  824. // min-height: 30px;
  825. // line-height: 28px;
  826. // box-shadow: 0 0 0 1px rgba(33, 153, 248, 0.3) inset;
  827. // }
  828. // .el-select__caret {
  829. // color: #2199F8;
  830. // }
  831. // .el-select__placeholder {
  832. // color: #2199F8;
  833. // }
  834. // .el-radio {
  835. // margin-right: 16px;
  836. // }
  837. // .el-input__wrapper {
  838. // box-shadow: 0 0 0 1px rgba(33, 153, 248, 0.3) inset;
  839. // }
  840. // .el-input__prefix {
  841. // color: #2199F8;
  842. // }
  843. // .el-input__inner {
  844. // color: #2199F8;
  845. // --el-input-placeholder-color: rgba(33, 153, 248, 0.43);
  846. // }
  847. // .el-tag.el-tag--info {
  848. // --el-tag-text-color: #2199F8;
  849. // --el-tag-bg-color: rgba(33, 153, 248, 0.1);
  850. // }
  851. // }
  852. .farm-info {
  853. color: rgba(0, 0, 0, 0.6);
  854. font-size: 14px;
  855. margin-top: 14px;
  856. .info-title {
  857. display: flex;
  858. align-items: center;
  859. justify-content: space-between;
  860. color: rgba(41, 41, 41, 0.3);
  861. .info-more {
  862. display: flex;
  863. align-items: center;
  864. }
  865. }
  866. }
  867. .farm-photo {
  868. margin-top: 10px;
  869. .photo-list {
  870. display: flex;
  871. align-items: center;
  872. width: 100%;
  873. overflow: auto;
  874. padding-bottom: 10px;
  875. .photo-item {
  876. width: 92px;
  877. height: 92px;
  878. border-radius: 8px;
  879. object-fit: cover;
  880. }
  881. .img-item {
  882. img {
  883. width: 92px;
  884. height: 92px;
  885. border-radius: 8px;
  886. object-fit: cover;
  887. margin-right: 12px;
  888. }
  889. }
  890. }
  891. .list-text {
  892. text-align: center;
  893. color: rgba(0, 0, 0, 0.5);
  894. padding-top: 2px;
  895. }
  896. }
  897. .submit-btn {
  898. z-index: 10;
  899. position: fixed;
  900. bottom: 0px;
  901. left: 0;
  902. width: 100%;
  903. display: flex;
  904. align-items: center;
  905. justify-content: space-between;
  906. padding: 12px;
  907. background: #fff;
  908. box-sizing: border-box;
  909. box-shadow: 0 4px 4px rgba(0, 0, 0, 0.4);
  910. border-top: 1px solid rgba(0, 0, 0, 0.1);
  911. &.center-btn {
  912. justify-content: center;
  913. }
  914. .btn {
  915. height: 40px;
  916. border-radius: 25px;
  917. line-height: 40px;
  918. width: 110px;
  919. text-align: center;
  920. background: linear-gradient(180deg, #70bffe, #2199f8);
  921. color: #ffffff;
  922. font-size: 14px;
  923. &.second {
  924. background: #ffffff;
  925. border: 1px solid rgba(153, 153, 153, 0.5);
  926. color: #666666;
  927. }
  928. }
  929. .btn + .btn {
  930. margin-left: 12px;
  931. }
  932. }
  933. }
  934. .card-title {
  935. font-size: 16px;
  936. font-weight: bold;
  937. color: #000;
  938. display: flex;
  939. align-items: center;
  940. &.between {
  941. justify-content: space-between;
  942. .del-tag {
  943. color: #e04c4c;
  944. border: 1px solid #e04c4c;
  945. border-radius: 5px;
  946. padding: 4px 14px;
  947. font-size: 12px;
  948. font-weight: normal;
  949. }
  950. .title-tag {
  951. padding: 2px 10px;
  952. height: 26px;
  953. line-height: 26px;
  954. }
  955. }
  956. // justify-content: space-between;
  957. .add-tag {
  958. font-size: 12px;
  959. color: #2199f8;
  960. padding: 0px 11px;
  961. border: 1px solid #2199f8;
  962. border-radius: 5px;
  963. font-weight: normal;
  964. height: 28px;
  965. line-height: 28px;
  966. }
  967. .type-tag {
  968. margin-left: 5px;
  969. font-size: 12px;
  970. color: #000000;
  971. padding: 0 10px;
  972. background: rgba(119, 119, 119, 0.1);
  973. border-radius: 20px;
  974. font-weight: normal;
  975. height: 26px;
  976. line-height: 26px;
  977. display: inline-block;
  978. }
  979. }
  980. .pb-12 {
  981. padding-bottom: 12px;
  982. }
  983. .farm-card {
  984. background: #ffffff;
  985. border-radius: 8px;
  986. padding: 12px 12px 0 12px;
  987. width: 100%;
  988. box-sizing: border-box;
  989. margin-top: 10px;
  990. color: rgba(0, 0, 0, 0.4);
  991. &.progress {
  992. display: flex;
  993. align-items: center;
  994. padding: 12px;
  995. .progress-title {
  996. margin-right: 12px;
  997. }
  998. ::v-deep {
  999. .el-radio {
  1000. margin-right: 10px;
  1001. }
  1002. }
  1003. }
  1004. &.map-content {
  1005. margin-top: 12px;
  1006. }
  1007. &.prescription-content {
  1008. padding: 12px;
  1009. }
  1010. .border-bottom {
  1011. padding-bottom: 7px;
  1012. border-bottom: 1px solid rgba(245, 245, 245, 0.99);
  1013. }
  1014. }
  1015. .table-item {
  1016. padding: 6px 0 10px 0;
  1017. .form-item {
  1018. display: flex;
  1019. align-items: center;
  1020. font-size: 14px;
  1021. color: #767676;
  1022. height: 24px;
  1023. .item-name {
  1024. width: 80px;
  1025. color: rgba(0, 0, 0, 0.2);
  1026. }
  1027. }
  1028. }
  1029. .new-wrap {
  1030. border-radius: 5px;
  1031. text-align: center;
  1032. border: 1px solid rgba(225, 225, 225, 0.5);
  1033. .new-title {
  1034. background: rgba(241, 241, 241, 0.4);
  1035. border-radius: 5px 5px 0 0;
  1036. border-bottom: 1px solid rgba(225, 225, 225, 0.5);
  1037. display: flex;
  1038. color: #767676;
  1039. // justify-content: space-around;
  1040. padding: 5px 6px;
  1041. font-size: 12px;
  1042. .table-name {
  1043. width: 24px;
  1044. font-size: 12px;
  1045. margin: 0 auto;
  1046. }
  1047. }
  1048. .title-1 {
  1049. width: 46px;
  1050. }
  1051. .title-2 {
  1052. flex: 1;
  1053. }
  1054. .title-3 {
  1055. width: 52px;
  1056. }
  1057. .title-4 {
  1058. width: 56px;
  1059. }
  1060. .title-5 {
  1061. width: 52px;
  1062. }
  1063. .new-table-wrap {
  1064. padding: 5px 0;
  1065. .new-prescription + .new-prescription {
  1066. border-top: 1px solid rgba(225, 225, 225, 0.8);
  1067. }
  1068. // .new-prescription {
  1069. .new-table {
  1070. display: flex;
  1071. align-items: center;
  1072. // border: 1px solid rgba(225, 225, 225, 0.8);
  1073. background: #fff;
  1074. border-radius: 5px;
  1075. color: rgba(0, 0, 0, 0.6);
  1076. font-size: 11px;
  1077. .line-l {
  1078. display: flex;
  1079. flex: 1;
  1080. .line-2 {
  1081. flex: 1;
  1082. padding: 0 2px;
  1083. }
  1084. }
  1085. .line-r {
  1086. &.has-border {
  1087. border-left: 1px solid rgba(225, 225, 225, 0.8);
  1088. }
  1089. .line-3 {
  1090. display: flex;
  1091. align-items: center;
  1092. }
  1093. .sub-line {
  1094. padding: 10px 0;
  1095. }
  1096. .line-4 {
  1097. display: flex;
  1098. align-items: center;
  1099. border-top: 1px solid rgba(225, 225, 225, 0.8);
  1100. }
  1101. .execute-line {
  1102. border-right: 1px solid rgba(225, 225, 225, 0.8);
  1103. }
  1104. }
  1105. }
  1106. .note-text {
  1107. margin: 8px 0 4px 0;
  1108. color: rgba(0, 0, 0, 0.4);
  1109. background: #fff;
  1110. padding: 6px 8px;
  1111. border-radius: 5px;
  1112. text-align: left;
  1113. font-size: 11px;
  1114. }
  1115. // }
  1116. // .new-prescription + .new-prescription {
  1117. // padding-top: 8px;
  1118. // }
  1119. }
  1120. }
  1121. .info-content-wrap {
  1122. ::v-deep {
  1123. .new-table-wrap {
  1124. padding: 5px 0;
  1125. .new-prescription + .new-prescription {
  1126. border-top: 1px solid rgba(225, 225, 225, 0.8);
  1127. }
  1128. }
  1129. }
  1130. }
  1131. .price-bottom {
  1132. padding-top: 8px;
  1133. .info-title-wrap {
  1134. display: flex;
  1135. align-items: center;
  1136. justify-content: space-between;
  1137. color: #000;
  1138. .info-more {
  1139. font-size: 18px;
  1140. }
  1141. .unit-text {
  1142. font-size: 12px;
  1143. }
  1144. }
  1145. .price-info {
  1146. padding: 8px 0;
  1147. display: flex;
  1148. align-items: center;
  1149. justify-content: space-between;
  1150. color: rgba(0, 0, 0, 0.2);
  1151. .main-text {
  1152. padding-left: 6px;
  1153. color: rgba(0, 0, 0, 0.8);
  1154. }
  1155. .info-c {
  1156. flex: 1;
  1157. text-align: center;
  1158. }
  1159. }
  1160. .price-total {
  1161. height: 38px;
  1162. display: flex;
  1163. align-items: center;
  1164. justify-content: center;
  1165. border: 1px solid rgba(33, 153, 248, 0.5);
  1166. background: rgba(33, 153, 248, 0.1);
  1167. color: #000000;
  1168. border-radius: 4px;
  1169. .main-val {
  1170. font-size: 20px;
  1171. font-weight: bold;
  1172. color: #2199f8;
  1173. padding-right: 2px;
  1174. }
  1175. }
  1176. }
  1177. .pb-8 {
  1178. padding-bottom: 8px;
  1179. }
  1180. .common-inputs {
  1181. ::v-deep {
  1182. .el-input__wrapper {
  1183. box-shadow: none;
  1184. }
  1185. .el-input-group__append {
  1186. padding: 0 10px;
  1187. background: none;
  1188. box-shadow: none;
  1189. }
  1190. .el-input-group__append {
  1191. color: rgba(33, 153, 248, 0.5);
  1192. }
  1193. .el-input {
  1194. border: 1px solid rgba(33, 153, 248, 0.3);
  1195. border-radius: 5px;
  1196. height: 30px;
  1197. box-sizing: border-box;
  1198. }
  1199. .el-input__wrapper {
  1200. padding: 0 2px 0 10px;
  1201. height: 28px;
  1202. line-height: 28px;
  1203. min-height: 28px;
  1204. }
  1205. .el-input__inner {
  1206. --el-input-inner-height: 28px;
  1207. height: 28px;
  1208. line-height: 28px;
  1209. min-height: 28px;
  1210. color: #2199f8;
  1211. --el-input-placeholder-color: rgba(33, 153, 248, 0.43);
  1212. }
  1213. .el-select__wrapper {
  1214. box-shadow: 0 0 0 1px rgba(33, 153, 248, 0.3) inset;
  1215. }
  1216. .el-select__placeholder,
  1217. .el-select__caret {
  1218. color: #2199f8;
  1219. }
  1220. }
  1221. }
  1222. .medicine-box {
  1223. // padding-top: 10px;
  1224. border: 1px solid rgba(33, 153, 248, 0.8);
  1225. position: relative;
  1226. border-radius: 6px;
  1227. .item-title {
  1228. padding-left: 5px;
  1229. font-size: 16px;
  1230. color: #000000;
  1231. font-weight: 500;
  1232. padding-bottom: 10px;
  1233. }
  1234. .medicine-item {
  1235. display: flex;
  1236. align-items: center;
  1237. justify-content: space-between;
  1238. height: 32px;
  1239. .item-name {
  1240. color: rgba(0, 0, 0, 0.4);
  1241. }
  1242. .item-val {
  1243. min-width: 142px;
  1244. text-align: center;
  1245. color: #302f2f;
  1246. display: flex;
  1247. align-items: center;
  1248. justify-content: center;
  1249. gap: 4px;
  1250. .price-unit {
  1251. font-size: 12px;
  1252. color: rgba(0, 0, 0, 0.4);
  1253. white-space: nowrap;
  1254. }
  1255. }
  1256. .item-total {
  1257. font-size: 16px;
  1258. color: #000;
  1259. }
  1260. .item-price {
  1261. color: #2199f8;
  1262. font-size: 20px;
  1263. font-weight: bold;
  1264. .item-unit {
  1265. font-size: 14px;
  1266. font-weight: normal;
  1267. padding-left: 2px;
  1268. color: #474747;
  1269. }
  1270. }
  1271. }
  1272. .medicine-item + .medicine-item {
  1273. padding-top: 2px;
  1274. }
  1275. .mt-8 {
  1276. margin-top: 8px;
  1277. }
  1278. }
  1279. .usage-mode-wrap {
  1280. padding: 0 12px;
  1281. margin-top: 12px;
  1282. .info-content {
  1283. padding-top: 14px;
  1284. padding-bottom: 1px;
  1285. }
  1286. .el-form-item--default {
  1287. margin-bottom: 0;
  1288. }
  1289. }
  1290. ::v-deep {
  1291. .el-form-item__label {
  1292. height: 30px;
  1293. line-height: 30px;
  1294. color: rgba(0, 0, 0, 0.4);
  1295. }
  1296. .el-form-item.is-required:not(.is-no-asterisk).asterisk-left > .el-form-item__label:before {
  1297. display: none;
  1298. }
  1299. }
  1300. .interact-content {
  1301. padding: 10px 0;
  1302. line-height: 20px;
  1303. color: #919191;
  1304. font-size: 14px;
  1305. }
  1306. .interact-form {
  1307. padding: 8px 0 20px 0px;
  1308. .interact-form-item {
  1309. display: flex;
  1310. align-items: baseline;
  1311. margin-bottom: 12px;
  1312. &:last-child {
  1313. margin-bottom: 0;
  1314. }
  1315. .form-label {
  1316. width: 70px;
  1317. color: rgba(0, 0, 0, 0.4);
  1318. font-weight: normal;
  1319. margin-right: 10px;
  1320. font-size: 14px;
  1321. flex: none;
  1322. }
  1323. .form-input-wrapper {
  1324. position: relative;
  1325. width: calc(100% - 70px);
  1326. &.two-select {
  1327. display: flex;
  1328. gap: 10px;
  1329. .select-item {
  1330. flex: 1;
  1331. }
  1332. }
  1333. ::v-deep {
  1334. .el-input__inner {
  1335. caret-color: transparent;
  1336. padding-right: 40px;
  1337. }
  1338. .el-input__suffix {
  1339. display: none;
  1340. }
  1341. }
  1342. }
  1343. .question-textarea {
  1344. ::v-deep {
  1345. .el-textarea__inner {
  1346. resize: none;
  1347. line-height: 1.5;
  1348. min-height: 80px;
  1349. }
  1350. }
  1351. }
  1352. }
  1353. .interact-buttons {
  1354. display: flex;
  1355. gap: 12px;
  1356. padding-top: 16px;
  1357. .btn-delete,
  1358. .btn-save {
  1359. flex: 1;
  1360. padding: 8px;
  1361. border-radius: 25px;
  1362. font-size: 16px;
  1363. text-align: center;
  1364. cursor: pointer;
  1365. transition: all 0.3s;
  1366. user-select: none;
  1367. }
  1368. .btn-delete {
  1369. background: #ffffff;
  1370. border: 1px solid #ff4d4f;
  1371. color: #ff4d4f;
  1372. &:hover {
  1373. background: #fff5f5;
  1374. }
  1375. &:active {
  1376. opacity: 0.8;
  1377. transform: scale(0.98);
  1378. }
  1379. }
  1380. .btn-save {
  1381. background: #2199f8;
  1382. color: #fff;
  1383. border: none;
  1384. &:hover:not(.disabled) {
  1385. background: #1a8ae6;
  1386. }
  1387. &:active:not(.disabled) {
  1388. opacity: 0.9;
  1389. transform: scale(0.98);
  1390. }
  1391. &.disabled {
  1392. opacity: 0.6;
  1393. cursor: not-allowed;
  1394. pointer-events: none;
  1395. }
  1396. }
  1397. }
  1398. }
  1399. .edit-tag {
  1400. padding-left: 4px;
  1401. color: #2199f8;
  1402. }
  1403. .tag-text {
  1404. font-size: 12px;
  1405. font-weight: normal;
  1406. }
  1407. .info-content {
  1408. padding: 10px 0;
  1409. position: relative;
  1410. .condition-wrap {
  1411. display: flex;
  1412. align-items: center;
  1413. width: 100%;
  1414. .symbol {
  1415. width: 10px;
  1416. // text-align: center;
  1417. // padding: 0 4px;
  1418. }
  1419. }
  1420. .item-input {
  1421. // width: 60%;
  1422. min-width: 140px;
  1423. max-width: 240px;
  1424. }
  1425. .recheck-text {
  1426. padding-left: 6px;
  1427. }
  1428. .info-item {
  1429. display: flex;
  1430. justify-content: space-between;
  1431. align-items: center;
  1432. width: 100%;
  1433. }
  1434. .info-item + .info-item {
  1435. margin-top: 12px;
  1436. }
  1437. .bottom-map {
  1438. width: 100%;
  1439. height: 250px;
  1440. clip-path: inset(0px round 8px);
  1441. }
  1442. .check-btn {
  1443. position: absolute;
  1444. bottom: 16px;
  1445. right: 6px;
  1446. background: rgba(0, 0, 0, 0.6);
  1447. padding: 0 8px;
  1448. border-radius: 8px;
  1449. ::v-deep {
  1450. .el-checkbox {
  1451. color: #fff;
  1452. }
  1453. }
  1454. }
  1455. .area-select {
  1456. padding-bottom: 12px;
  1457. .block {
  1458. width: 12px;
  1459. display: inline-block;
  1460. }
  1461. }
  1462. }
  1463. ::v-deep {
  1464. .el-form-item--default {
  1465. margin-bottom: 8px;
  1466. &.name-item {
  1467. margin-bottom: 14px;
  1468. }
  1469. &.text-item {
  1470. margin-bottom: 2px;
  1471. .el-form-item__content {
  1472. line-height: 24px;
  1473. }
  1474. .el-form-item__label {
  1475. height: 24px;
  1476. line-height: 24px;
  1477. }
  1478. }
  1479. }
  1480. }
  1481. .sub-title {
  1482. display: flex;
  1483. align-items: center;
  1484. justify-content: space-between;
  1485. color: rgba(0, 0, 0, 0.6);
  1486. font-size: 14px;
  1487. .add-tag {
  1488. font-size: 12px;
  1489. color: #2199f8;
  1490. padding: 0 8px;
  1491. border: 1px solid #2199f8;
  1492. border-radius: 5px;
  1493. font-weight: normal;
  1494. height: 28px;
  1495. line-height: 28px;
  1496. }
  1497. }
  1498. .font-bold {
  1499. font-weight: 500;
  1500. color: #000000;
  1501. }
  1502. .form-index {
  1503. position: absolute;
  1504. left: 0;
  1505. top: 0;
  1506. padding: 0 6px;
  1507. background: #2199f8;
  1508. border-radius: 5px 0 4px 0;
  1509. height: 18px;
  1510. line-height: 18px;
  1511. font-size: 12px;
  1512. color: #fff;
  1513. }
  1514. .recipe-item {
  1515. width: 100%;
  1516. .recipe-form {
  1517. padding-top: 8px;
  1518. ::v-deep {
  1519. .el-form-item {
  1520. &:last-child {
  1521. margin-bottom: 0;
  1522. }
  1523. }
  1524. }
  1525. }
  1526. .mt-8 {
  1527. margin-top: 8px;
  1528. }
  1529. .box-item {
  1530. display: flex;
  1531. align-items: center;
  1532. justify-content: space-between;
  1533. color: rgba(0, 0, 0, 0.4);
  1534. .r-text {
  1535. color: #302f2f;
  1536. width: 150px;
  1537. text-align: center;
  1538. }
  1539. .form-r {
  1540. width: 150px;
  1541. min-width: 140px;
  1542. max-width: 240px;
  1543. }
  1544. }
  1545. .form-box {
  1546. border: 1px solid rgba(33, 153, 248, 0.8);
  1547. border-radius: 6px;
  1548. padding: 20px 10px;
  1549. width: 100%;
  1550. box-sizing: border-box;
  1551. position: relative;
  1552. // background: rgb(209, 235, 255, 0.3);
  1553. // margin-bottom: 12px;
  1554. .input-box {
  1555. &.mark-box {
  1556. padding: 8px 0 12px 0;
  1557. }
  1558. }
  1559. // .input-unit {
  1560. // ::v-deep {
  1561. // .el-input {
  1562. // border: 1px solid #dcdfe6;
  1563. // border-radius: 5px;
  1564. // height: 32px;
  1565. // box-sizing: border-box;
  1566. // }
  1567. // .el-input__wrapper {
  1568. // padding: 0 2px 0 10px;
  1569. // height: 30px;
  1570. // line-height: 30px;
  1571. // min-height: 30px;
  1572. // box-shadow: none;
  1573. // }
  1574. // .el-input__inner {
  1575. // --el-input-inner-height: 30px;
  1576. // height: 30px;
  1577. // line-height: 30px;
  1578. // min-height: 30px;
  1579. // color: #606266;
  1580. // --el-input-placeholder-color: #a8abb2;
  1581. // }
  1582. // .el-input-group__append {
  1583. // box-shadow: none;
  1584. // border: none;
  1585. // background: none;
  1586. // }
  1587. // }
  1588. // }
  1589. // .text-center {
  1590. // ::v-deep {
  1591. // .el-input__inner {
  1592. // text-align: center;
  1593. // }
  1594. // }
  1595. // }
  1596. .action-btn {
  1597. margin-top: 12px;
  1598. display: flex;
  1599. justify-content: flex-end;
  1600. .btn {
  1601. color: #8f8f8f;
  1602. border-radius: 25px;
  1603. padding: 5px 30px;
  1604. }
  1605. .delete-btn {
  1606. color: rgba(255, 89, 89, 0.9);
  1607. background: #fff;
  1608. border: 1px solid rgba(255, 89, 89, 0.9);
  1609. }
  1610. }
  1611. .btn-group {
  1612. padding-top: 12px;
  1613. }
  1614. .sub-item {
  1615. // padding-left: 10px;
  1616. .has-sub {
  1617. display: flex;
  1618. flex-direction: column;
  1619. align-items: center;
  1620. .main-name {
  1621. line-height: 20px;
  1622. }
  1623. .sub-name {
  1624. font-size: 10px;
  1625. color: rgba(129, 129, 129, 0.5);
  1626. line-height: 14px;
  1627. }
  1628. }
  1629. .colunm-sub {
  1630. display: flex;
  1631. align-items: center;
  1632. .sub-name {
  1633. font-size: 10px;
  1634. color: rgba(129, 129, 129, 0.5);
  1635. }
  1636. }
  1637. .r-text {
  1638. width: 132px;
  1639. text-align: center;
  1640. font-size: 14px;
  1641. color: #474747;
  1642. }
  1643. .price {
  1644. ::v-deep {
  1645. .el-input__wrapper {
  1646. box-shadow: 0 0 0 1px rgba(33, 153, 248, 0.3) inset;
  1647. }
  1648. .el-input__inner {
  1649. color: #2199f8;
  1650. }
  1651. }
  1652. }
  1653. }
  1654. .form-title {
  1655. font-size: 14px;
  1656. padding-top: 6px;
  1657. color: #000;
  1658. font-weight: 600;
  1659. }
  1660. .box-item + .box-item {
  1661. margin-top: 8px;
  1662. }
  1663. }
  1664. .form-box + .form-box {
  1665. margin-top: 8px;
  1666. }
  1667. .usageMode-wrap {
  1668. padding-top: 8px;
  1669. }
  1670. }
  1671. // 状况描述样式
  1672. .situation-description {
  1673. width: 100%;
  1674. .description-title {
  1675. font-size: 16px;
  1676. font-weight: bold;
  1677. color: #000;
  1678. margin-bottom: 12px;
  1679. }
  1680. .description-content {
  1681. .description-textarea {
  1682. margin-bottom: 10px;
  1683. width: 100%;
  1684. }
  1685. .upload-section {
  1686. .upload-btn {
  1687. width: 112px;
  1688. height: 32px;
  1689. border-radius: 3px;
  1690. border: 1px solid #e0e0e0;
  1691. background: #fff;
  1692. color: #000;
  1693. font-size: 14px;
  1694. display: flex;
  1695. align-items: center;
  1696. justify-content: center;
  1697. margin-bottom: 8px;
  1698. .el-icon {
  1699. margin-right: 6px;
  1700. }
  1701. }
  1702. .upload-tip {
  1703. font-size: 12px;
  1704. color: #999;
  1705. line-height: 1.4;
  1706. }
  1707. }
  1708. }
  1709. }
  1710. // 专家诊断按钮样式
  1711. .expert-diagnosis-btn {
  1712. width: 180px;
  1713. height: 40px;
  1714. border-radius: 24px;
  1715. background: linear-gradient(180deg, #70bffe 0%, #2199f8 100%);
  1716. color: #ffffff;
  1717. display: flex;
  1718. align-items: center;
  1719. justify-content: center;
  1720. margin: 30px auto 0;
  1721. }
  1722. }
  1723. .tag-list {
  1724. font-size: 14px;
  1725. .tag-item + .tag-item {
  1726. margin-top: 6px;
  1727. }
  1728. .tag-item {
  1729. padding: 2px 8px;
  1730. text-align: center;
  1731. &.active {
  1732. color: #2199f8;
  1733. background: rgba(33, 153, 248, 0.16);
  1734. border-radius: 4px;
  1735. }
  1736. }
  1737. }
  1738. .task-tips-popup {
  1739. width: 75%;
  1740. padding: 28px 28px 20px;
  1741. display: flex;
  1742. flex-direction: column;
  1743. align-items: center;
  1744. justify-content: center;
  1745. .create-farm-icon {
  1746. width: 40px;
  1747. height: 40px;
  1748. margin-bottom: 12px;
  1749. }
  1750. .farm-check-icon {
  1751. width: 68px;
  1752. height: 68px;
  1753. margin-bottom: 12px;
  1754. }
  1755. .create-farm-text {
  1756. font-size: 20px;
  1757. font-weight: 500;
  1758. line-height: 40px;
  1759. margin-bottom: 32px;
  1760. text-align: center;
  1761. &.success-text {
  1762. font-size: 24px;
  1763. font-weight: 500;
  1764. }
  1765. }
  1766. .main-text {
  1767. color: #2199f8;
  1768. }
  1769. .create-farm-btn {
  1770. width: 100%;
  1771. box-sizing: border-box;
  1772. padding: 8px;
  1773. border-radius: 25px;
  1774. font-size: 16px;
  1775. background: #2199f8;
  1776. color: #fff;
  1777. text-align: center;
  1778. }
  1779. }
  1780. </style>