prescriptionBox.vue 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528
  1. <template>
  2. <!-- 专家处方 -->
  3. <div class="work-item" :class="{ dark: prescriptioData?.progress === 0 && ROLETYPE != '3' }">
  4. <div class="work-info">
  5. <img
  6. v-if="prescriptioData?.progress === 0 && ROLETYPE == '3'"
  7. class="todo-img"
  8. src="@/assets/img/gallery/todo.png"
  9. />
  10. <div class="prescription-box">
  11. <div class="step-box">
  12. <step-box
  13. :orderStatus="infoItem.orderStatus"
  14. v-if="infoItem.orderStatus || infoItem.orderStatus === 0"
  15. ></step-box>
  16. </div>
  17. <div class="work-info-conetnt">
  18. <div class="info-item">
  19. <div class="info-name">农事编号:</div>
  20. <div class="info-value">{{ infoItem.orderId }}</div>
  21. </div>
  22. <div class="info-item">
  23. <div class="info-name">服务亩数:</div>
  24. <div class="info-value">{{ infoItem.area }}亩</div>
  25. </div>
  26. <div class="info-item">
  27. <div class="info-name">服务区域:</div>
  28. <div class="info-value">{{ infoItem.serviceRegion }}</div>
  29. </div>
  30. <div v-if="prescriptioData?.progress === 0 && ROLETYPE == '3'">
  31. <div class="info-item">
  32. <div class="info-name">触发条件:</div>
  33. <div class="info-value">
  34. {{ infoItem.farmWorkLibName }}
  35. <div class="select-value">
  36. <el-select v-model="infoItem.usageMode" placeholder="请选择" style="width: 80px">
  37. <el-option v-for="num in 9" :key="num" :value="20 + (num - 1) * 5 + '%'">
  38. {{ 20 + (num - 1) * 5 }}%
  39. </el-option>
  40. </el-select>
  41. </div>
  42. </div>
  43. </div>
  44. <div class="info-item time-picker">
  45. <div class="info-name">执行时间:</div>
  46. <div class="info-value">
  47. <el-date-picker
  48. style="width: 150px"
  49. value-format="YYYY-MM-DD"
  50. v-model="infoItem.executeDate"
  51. type="date"
  52. :clearable="false"
  53. class="date-info"
  54. placeholder="选择日期"
  55. />
  56. </div>
  57. </div>
  58. </div>
  59. <div v-else>
  60. <div class="info-item">
  61. <div class="info-name">触发条件:</div>
  62. <div class="info-value">{{ infoItem.farmWorkLibName }}</div>
  63. </div>
  64. <div class="info-item">
  65. <div class="info-name">执行时间:</div>
  66. <div class="info-value">{{ infoItem.executeDate }}</div>
  67. </div>
  68. </div>
  69. </div>
  70. <div class="desc">
  71. 您果园周边 3公里 出现虫害。根据气象模型推算,您的果园出现 卷叶蛾 风险达到90%。手机拍照上传
  72. 果园照片,自动预测物候期可以确定.
  73. <!-- {{ prescriptioData?.expertPrescription }} -->
  74. </div>
  75. <!-- v-if="prescriptioData?.progress === 0 && ROLETYPE == '3'" -->
  76. <div class="prescription-item">
  77. <div class="recipe-box">
  78. <div class="recipe-title">
  79. <div class="recipe-name">药物处方</div>
  80. <div class="recipe-btn" @click="addDomain">
  81. <el-icon class="icon"><Plus /></el-icon>新增药物
  82. </div>
  83. </div>
  84. <custom-table type="0" @handleDelete="removeDomain" :tableHeader="tableHeader" :tableData="dynamicValidateForm.domains"></custom-table>
  85. <!-- <div class="recipe-item">
  86. <div class="recipe-form">
  87. <el-form
  88. ref="formRef"
  89. style="max-width: 600px"
  90. :model="dynamicValidateForm"
  91. class="demo-dynamic"
  92. >
  93. <el-form-item
  94. v-for="(domain, index) in dynamicValidateForm.domains"
  95. :key="domain.key"
  96. :prop="'domains.' + index + '.value'"
  97. >
  98. <div class="form-box">
  99. <div class="form-index">{{ formatIndex(index) }}</div>
  100. <div class="box-item" v-if="domain.typeName">
  101. <div class="form-l">使用功效</div>
  102. <div class="form-r r-text">
  103. {{ domain.typeName }}
  104. </div>
  105. </div>
  106. <div class="box-item">
  107. <div class="form-l">肥药名称</div>
  108. <div class="form-r">
  109. <el-select
  110. @change="handlePesticideFertilizerChange(index)"
  111. v-model="domain.pesticideFertilizerId"
  112. placeholder="请选择"
  113. style="width: 140px"
  114. >
  115. <el-option
  116. v-for="item in pesticideFertilizersOptions"
  117. :key="item.id"
  118. :label="item.defaultName"
  119. :value="item.id"
  120. />
  121. </el-select>
  122. </div>
  123. </div>
  124. <div class="form-title">人工方式</div>
  125. <div class="box-item sub-item">
  126. <div class="form-l has-sub">
  127. <div class="main-name">肥药配比</div>
  128. <div class="sub-name">(药剂:兑水量)</div>
  129. </div>
  130. <div class="form-r input-box text-center">
  131. <el-input
  132. v-model="domain.ratio"
  133. style="width: 140px"
  134. placeholder="请输入"
  135. />
  136. </div>
  137. </div>
  138. <div class="box-item sub-item">
  139. <div class="form-l">施用方式</div>
  140. <div class="form-r">
  141. <el-select
  142. v-model="domain.usageMode"
  143. placeholder="请选择"
  144. style="width: 140px"
  145. >
  146. <el-option
  147. v-for="(usage, uId) in domain.usageModeList"
  148. :key="uId"
  149. :label="usage"
  150. :value="usage"
  151. />
  152. </el-select>
  153. </div>
  154. </div>
  155. <div class="box-item sub-item">
  156. <div class="form-l has-sub">
  157. <div class="main-name">单亩用量</div>
  158. <div class="sub-name">(亩数:药剂)</div>
  159. </div>
  160. <div class="form-r input-box text-center">
  161. <el-input
  162. v-model="domain.muUsage"
  163. style="width: 140px"
  164. placeholder="请输入"
  165. />
  166. </div>
  167. </div>
  168. <div class="form-title">无人机方式</div>
  169. <div class="box-item sub-item">
  170. <div class="form-l has-sub">
  171. <div class="main-name">肥药配比</div>
  172. <div class="sub-name">(药剂:兑水量)</div>
  173. </div>
  174. <div class="form-r input-box text-center">
  175. <el-input
  176. v-model="domain.muUsage2"
  177. style="width: 140px"
  178. placeholder="请输入"
  179. />
  180. </div>
  181. </div>
  182. <div class="box-item sub-item">
  183. <div class="form-l has-sub">
  184. <div class="main-name">单亩用量</div>
  185. <div class="sub-name">(亩数:药剂)</div>
  186. </div>
  187. <div class="form-r input-box text-center">
  188. <el-input
  189. v-model="domain.ratio2"
  190. style="width: 140px"
  191. placeholder="请输入"
  192. />
  193. </div>
  194. </div>
  195. <div class="input-box">
  196. <el-input
  197. v-model="domain.remark"
  198. style="width: 100%"
  199. placeholder="备注:用药注意事项"
  200. />
  201. </div>
  202. <div class="action-btn">
  203. <el-button class="btn delete-btn" @click.prevent="removeDomain(domain)">
  204. 删除
  205. </el-button>
  206. <el-button
  207. type="primary"
  208. class="btn"
  209. @click.prevent="resetItemForm(index)"
  210. >
  211. 重置
  212. </el-button>
  213. </div>
  214. </div>
  215. </el-form-item>
  216. </el-form>
  217. </div>
  218. </div> -->
  219. </div>
  220. </div>
  221. <!-- <div class="prescription-item" v-else>
  222. <div class="sub-title">
  223. <div class="sub-name">药物处方</div>
  224. <div class="sub-name"><span>施用方式:</span>根部施</div>
  225. </div>
  226. <custom-table type="0" :tableHeader="tableHeader" :tableData="tableData"></custom-table>
  227. </div> -->
  228. <div class="prescription-item" v-if="prescriptioData?.progress === 0">
  229. <div class="sub-title">
  230. <div class="sub-line"></div>
  231. <div class="sub-name">指标动态</div>
  232. <div class="sub-line"></div>
  233. </div>
  234. <div class="prescription-chart">
  235. <chart :key="1" type="feature" :chartJson="prescriptioData.indexJson"></chart>
  236. </div>
  237. </div>
  238. <div class="prescription-item" v-if="prescriptioData?.progress === 0 && ROLETYPE == '3'">
  239. <el-button class="one-btn" type="primary" @click="submitForm(formRef)">确认下发</el-button>
  240. </div>
  241. </div>
  242. </div>
  243. </div>
  244. </template>
  245. <script setup>
  246. import { ElMessage } from "element-plus";
  247. import eventBus from "@/api/eventBus";
  248. import chart from "./chart.vue";
  249. import { onActivated, onMounted, reactive, ref } from "vue";
  250. import { useStore } from "vuex";
  251. import stepBox from "@/components/common/stepBox.vue";
  252. import customTable from "./table.vue";
  253. const props = defineProps({
  254. prescriptioData: {
  255. type: Object,
  256. },
  257. });
  258. const tableHeader = [
  259. {
  260. name: "使用功效",
  261. props: "typeName",
  262. },
  263. {
  264. name: "肥药名称",
  265. props: "defaultName",
  266. },
  267. {
  268. name: "执行方式",
  269. props: "usageMode1",
  270. },
  271. {
  272. name: "药肥配比",
  273. props: "usageMode",
  274. },
  275. {
  276. name: "单亩用量",
  277. props: "muUsage",
  278. },
  279. ];
  280. const tableData = ref([
  281. {
  282. brand: "",
  283. defaultDroneRatio: null,
  284. defaultName: "灌水",
  285. defaultRatio: null,
  286. executeStyle: null,
  287. id: "686142764512972800",
  288. muPrice: null,
  289. muUsage: 222,
  290. muUsage2: null,
  291. orderId: "686142764492001280",
  292. pesticideFertilizerCode: "",
  293. pesticideFertilizerId: "15",
  294. pesticideFertilizerName: "灌水",
  295. price: null,
  296. ratio: 11,
  297. ratio2: null,
  298. remark: "",
  299. typeName: "调节",
  300. unit: "kg",
  301. usageMode: "",
  302. list: [],
  303. },
  304. ]);
  305. const infoItem = ref({});
  306. const store = useStore();
  307. const ROLETYPE = store.state.app.curRole;
  308. // 农事类型--区分表格显示字段等
  309. const workType = ref(false);
  310. let pesticideFertilizersOptions = ref([
  311. {
  312. id: "null",
  313. name: "芸苔素内酯 15000倍",
  314. typeName: "30",
  315. defaultRatio: null,
  316. defaultDroneRatio: null,
  317. unit: 0,
  318. defaultName: "调节",
  319. },
  320. ]);
  321. VE_API.order.pesticideFertilizers().then(({ data }) => {
  322. pesticideFertilizersOptions.value = data;
  323. tableData.value[0].list = data;
  324. });
  325. onMounted(() => {
  326. dynamicValidateForm.domains = props.prescriptioData?.pesticideFertilizers.map((item) => ({ ...item }));
  327. // submit()
  328. console.log("dynamicValidateForm.domains", dynamicValidateForm.domains);
  329. infoItem.value = props.prescriptioData;
  330. });
  331. // 表单
  332. const formRef = ref();
  333. const dynamicValidateForm = reactive({
  334. domains: [
  335. {
  336. key: 1,
  337. typeName: "",
  338. muUsage: "",
  339. muUsage2: "",
  340. ratio: "",
  341. ratio2: "",
  342. remark: "",
  343. },
  344. ],
  345. });
  346. const addDomain = () => {
  347. dynamicValidateForm.domains.unshift({
  348. key: Date.now(),
  349. muUsage: "",
  350. muUsage2: "",
  351. ratio: "",
  352. ratio2: "",
  353. remark: "",
  354. });
  355. console.log("121323.domains", dynamicValidateForm.domains);
  356. };
  357. const removeDomain = (index) => {
  358. // const index = dynamicValidateForm.domains.indexOf(item);
  359. // if (index !== -1) {
  360. if(dynamicValidateForm.domains.length===1) return ElMessage.warning('至少保留一个处方!')
  361. dynamicValidateForm.domains.splice(index, 1);
  362. // }
  363. };
  364. const resetItemForm = (index) => {
  365. dynamicValidateForm.domains[index] = { typeName: "", muUsage: "", muUsage2: "", ratio: "", ratio2: "", remark: "" };
  366. };
  367. /**
  368. * 选择药肥的时候修改订单中药肥pesticideFertilizerId 以外其他数据
  369. * @param index
  370. */
  371. const handlePesticideFertilizerChange = (index) => {
  372. let obj = pesticideFertilizersOptions.value.filter(
  373. (item) => dynamicValidateForm.domains[index].pesticideFertilizerId === item.id
  374. )[0];
  375. dynamicValidateForm.domains[index] = {
  376. ...dynamicValidateForm.domains[index],
  377. typeName: obj.typeName,
  378. unit: obj.unit,
  379. defaultRatio: obj.defaultRatio,
  380. usageModeList: obj.usageModeList,
  381. ratio: obj.defaultRatio,
  382. defaultName: obj.defaultName,
  383. pesticideFertilizerName: obj.name,
  384. };
  385. console.log(dynamicValidateForm.domains);
  386. };
  387. const submitForm = (formEl) => {
  388. if (!formEl) return;
  389. formEl.validate((valid) => {
  390. if (valid) {
  391. submit();
  392. } else {
  393. console.log("error submit!");
  394. }
  395. });
  396. };
  397. const submit = () => {
  398. const data = {
  399. orderId: props.prescriptioData.orderId,
  400. orderStatus: 1,
  401. pesticideFertilizers: dynamicValidateForm.domains,
  402. };
  403. VE_API.order.confirm(data).then(({ code }) => {
  404. if (code == 0) {
  405. console.log("专家下发处方成功");
  406. eventBus.emit("discover:submitForm");
  407. window.location.reload();
  408. }
  409. });
  410. };
  411. const formatIndex = (index) => {
  412. return String(index + 1).padStart(2, "0");
  413. };
  414. const handleTableData = (item) => {
  415. return [
  416. {
  417. typeName: item.typeName,
  418. defaultName: item.defaultName,
  419. executeStyle: 1,
  420. ratio: item.ratio || item.defaultRatio,
  421. usageMode: item.usageMode,
  422. muUsage: item.muUsage,
  423. unit: item.unit,
  424. },
  425. {
  426. typeName: item.typeName,
  427. defaultName: item.defaultName,
  428. executeStyle: 2,
  429. ratio: item.ratio2,
  430. usageMode: "---",
  431. muUsage: item.muUsage2,
  432. unit: item.unit,
  433. },
  434. ];
  435. };
  436. </script>
  437. <style lang="scss" scoped>
  438. @import "./boxClass.scss";
  439. .recipe-box {
  440. .recipe-title {
  441. display: flex;
  442. align-items: center;
  443. justify-content: space-between;
  444. margin-bottom: 10px;
  445. padding-left: 10px;
  446. position: relative;
  447. &::before {
  448. content: "";
  449. position: absolute;
  450. left: 0;
  451. top: 3px;
  452. width: 3px;
  453. height: 15px;
  454. background: #fff;
  455. border-radius: 11px;
  456. }
  457. .recipe-name {
  458. color: #fff;
  459. font-size: 15px;
  460. }
  461. .recipe-btn {
  462. color: #FFD489;
  463. display: flex;
  464. align-items: center;
  465. cursor: pointer;
  466. .icon{
  467. margin-right: 3px;
  468. }
  469. }
  470. }
  471. }
  472. .prescription-result {
  473. position: relative;
  474. &.has-wrap {
  475. border: 0.5px solid rgba(33, 153, 248, 0.5);
  476. border-radius: 4px;
  477. padding: 8px 10px 10px 10px;
  478. }
  479. .result-index {
  480. position: absolute;
  481. left: -1px;
  482. top: -1px;
  483. padding: 0 8px;
  484. background: #2199f8;
  485. color: #fff;
  486. font-size: 12px;
  487. border-radius: 4px 0 4px 0;
  488. }
  489. .result-title {
  490. display: flex;
  491. justify-content: center;
  492. align-items: center;
  493. padding-bottom: 8px;
  494. .title-item {
  495. display: flex;
  496. align-items: center;
  497. .name {
  498. color: rgba(33, 153, 248, 0.85);
  499. }
  500. .value {
  501. color: rgba(0, 0, 0, 0.4);
  502. }
  503. }
  504. .title-item + .title-item {
  505. padding-left: 16px;
  506. }
  507. }
  508. }
  509. </style>