automation.vue 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417
  1. <template>
  2. <view class="automation">
  3. <custom-card>
  4. <block slot="backText">自动控制</block>
  5. </custom-card>
  6. <view
  7. class="automation-content"
  8. :class="{ 'automation-content-rever': activeIndex === 1 }"
  9. >
  10. <view class="automation-header">
  11. <view
  12. class="automation-header-item"
  13. :class="{ 'automation-header-item-active': activeIndex === 0 }"
  14. @click="clickHeaderItem(0)"
  15. >灌溉
  16. <view
  17. :class="
  18. activeIndex == '0'
  19. ? 'automation-header-item-icon'
  20. : 'automation-header-item-icon-bottom'
  21. "
  22. ></view>
  23. </view>
  24. <view
  25. class="automation-header-item"
  26. @click="clickHeaderItem(1)"
  27. :class="{ 'automation-header-item-active': activeIndex === 1 }"
  28. >水肥
  29. <view
  30. :class="
  31. activeIndex == '1'
  32. ? 'automation-header-item-icon'
  33. : 'automation-header-item-icon-bottom'
  34. "
  35. ></view>
  36. </view>
  37. </view>
  38. <view class="automation-body">
  39. <rotation-items :formData="formData" :tktype="tktype" />
  40. <view class="automation-body-title">灌区选择</view>
  41. <rotation-bottom
  42. :activeIndex="activeIndex"
  43. :irrigatedAreaList="irrigatedAreaList"
  44. :alreadyList="alreadyList"
  45. :tktype="tktype"
  46. />
  47. </view>
  48. </view>
  49. <view class="automation-footer">
  50. <view class="automation-footer-left">
  51. 已选<text class="automation-footer-left-num">{{ selectNum }}</text
  52. >个灌区
  53. </view>
  54. <view class="automation-footer-right" @click="immediateExecution"
  55. >立即执行</view
  56. >
  57. </view>
  58. </view>
  59. </template>
  60. <script>
  61. import rotationItems from './components/rotationItems.vue';
  62. import rotationBottom from './components/rotationBottom.vue';
  63. export default {
  64. name: 'automation',
  65. data() {
  66. return {
  67. activeIndex: 0,
  68. devBid: '',
  69. devName: '',
  70. devStatus: '',
  71. irrigatedAreaList: [],
  72. alreadyList: [],
  73. formData: {
  74. lgjg: '',
  75. fqcx: '',
  76. fhcx: '',
  77. lgcs: 1,
  78. },
  79. tktype: 1,
  80. selectNum: 0,
  81. };
  82. },
  83. components: {
  84. rotationBottom,
  85. rotationItems,
  86. },
  87. watch: {
  88. alreadyList: {
  89. handler(val) {
  90. this.selectNum = 0;
  91. val.forEach((item) => {
  92. if (item.isChecked) {
  93. this.selectNum++;
  94. }
  95. });
  96. },
  97. deep: true,
  98. immediate: true,
  99. },
  100. },
  101. onLoad(options) {
  102. this.devBid = options.devBid;
  103. this.devName = options.devName;
  104. this.devStatus = options.devStatus;
  105. // 检测是否有运行中的任务
  106. this.getRunStatus().then((hasRunningTask) => {
  107. if (hasRunningTask) {
  108. setTimeout(() => {
  109. uni.redirectTo({
  110. url: `/pages/cb/shuifeizs/rotationflow?devBid=${this.devBid}&devName=${this.devName}&devStatus=${this.devStatus}`,
  111. });
  112. }, 1000);
  113. } else {
  114. this.getdeviceSfStatus();
  115. this.getAlreadyList();
  116. }
  117. });
  118. },
  119. methods: {
  120. async getAlreadyList() {
  121. const res = await this.$myRequest({
  122. url: '/api/v2/iot/mobile/device/sf/group/already/list/',
  123. method: 'post',
  124. data: {
  125. devBid: this.devBid,
  126. },
  127. });
  128. console.log(res, '-------------------- get already list');
  129. res.forEach((item) => {
  130. item.isChecked = false;
  131. });
  132. this.alreadyList = res;
  133. },
  134. async getdeviceSfStatus() {
  135. const res = await this.$myRequest({
  136. url: '/api/v2/iot/mobile/device/sf/status/',
  137. method: 'post',
  138. data: {
  139. devBid: this.devBid,
  140. },
  141. });
  142. this.dataList = [];
  143. this.irrigatedAreaList = [];
  144. this.alreadyfertilizerBucketList = [];
  145. console.log('get device sf status', res);
  146. res.forEach((item) => {
  147. if (item.sfType === '7') {
  148. this.irrigatedAreaList.push(item);
  149. }
  150. });
  151. },
  152. clickHeaderItem(index) {
  153. this.activeIndex = index;
  154. this.tktype = index == 0 ? 1 : 2;
  155. },
  156. // 获取运行状态
  157. async getRunStatus() {
  158. try {
  159. const res = await this.$myRequest({
  160. url: '/api/v2/iot/mobile/device/sf/zsrf/task/run/status/',
  161. method: 'post',
  162. data: {
  163. devBid: this.devBid,
  164. },
  165. });
  166. console.log(res, 'resresresres');
  167. return Promise.resolve(res.status && res.status / 1 === 1);
  168. } catch (error) {
  169. return Promise.resolve(false);
  170. }
  171. },
  172. // iot/mobile/device/sf/zsrf/task/ctl/
  173. async postTaskCtl(payload) {
  174. // loading
  175. uni.showLoading({
  176. title: '正在执行',
  177. });
  178. const res = await this.$myRequest({
  179. url: '/api/v2/iot/mobile/device/sf/zsrf/task/ctl/',
  180. method: 'post',
  181. data: payload,
  182. header: {
  183. 'Content-Type': 'application/json',
  184. },
  185. });
  186. uni.hideLoading();
  187. if (res.code === '000000') {
  188. uni.showToast({
  189. title: '操作成功',
  190. });
  191. setTimeout(() => {
  192. uni.redirectTo({
  193. url: `/pages/cb/shuifeizs/rotationflow?devBid=${this.devBid}&devName=${this.devName}&devStatus=${this.devStatus}`,
  194. });
  195. }, 1000);
  196. } else {
  197. uni.showToast({
  198. icon: 'none',
  199. title: res.msg,
  200. });
  201. }
  202. },
  203. immediateExecution() {
  204. if (!this.formData['lgjg']) {
  205. uni.showToast({
  206. title: '请输入轮灌间隔时间',
  207. icon: 'none',
  208. });
  209. return;
  210. }
  211. if (this.tktype == 2 && !this.formData['fqcx']) {
  212. uni.showToast({
  213. title: '请输入肥前水时间',
  214. icon: 'none',
  215. });
  216. return;
  217. }
  218. if (this.tktype == 2 && !this.formData['fhcx']) {
  219. uni.showToast({
  220. title: '请输入肥后水时间',
  221. icon: 'none',
  222. });
  223. return;
  224. }
  225. if (this.tktype == 2 && !this.formData['sfmode']) {
  226. uni.showToast({
  227. title: '请选择模式',
  228. icon: 'none',
  229. });
  230. return;
  231. }
  232. if (this.selectNum === 0) {
  233. uni.showToast({
  234. title: '请选择灌区',
  235. icon: 'none',
  236. });
  237. return;
  238. }
  239. const fqList = [];
  240. for (let i = 0; i < this.alreadyList.length; i++) {
  241. const item = this.alreadyList[i];
  242. if (item.isChecked && !item.ti) {
  243. uni.showToast({
  244. title: `请输入${item.sfDisplayname || item.sfName}的时长`,
  245. icon: 'none',
  246. });
  247. return;
  248. } else if (item.isChecked && this.tktype == 2 && !item.pfCode) {
  249. uni.showToast({
  250. title: `请输入${item.sfDisplayname || item.sfName}的配方`,
  251. icon: 'none',
  252. });
  253. return;
  254. }
  255. if (item.isChecked) {
  256. fqList.push({
  257. fqCode: item.sfCode,
  258. ti: item.ti || '',
  259. pfCode: item.pfCode || '',
  260. });
  261. }
  262. }
  263. const payload = {
  264. devBid: this.devBid,
  265. tktype: this.tktype,
  266. tkid: 0,
  267. status: 1,
  268. ...this.formData,
  269. fqList,
  270. sfmode: this.tktype !== 1 ? this.formData.sfmode || 1 : '',
  271. };
  272. this.postTaskCtl(payload);
  273. },
  274. },
  275. };
  276. </script>
  277. <style scoped lang="scss">
  278. uni-page-body,
  279. uni-page-wrapper {
  280. position: relative;
  281. height: 100%;
  282. }
  283. .automation {
  284. background: linear-gradient(180deg, #ffffff00 0%, #fff 23.64%, #fff 100%),
  285. linear-gradient(102deg, #bfeadd 6.77%, #b8f1e7 40.15%, #b9eef5 84.02%);
  286. width: 100%;
  287. height: calc(100% - 100rpx);
  288. overflow: hidden;
  289. .automation-content {
  290. border-bottom: none;
  291. border-radius: 16rpx 16rpx 0 0;
  292. position: relative;
  293. overflow: hidden;
  294. &::before {
  295. position: absolute;
  296. content: '';
  297. top: 0;
  298. left: 0;
  299. right: 0;
  300. bottom: 0;
  301. background: url('./assets/controlbg.png') no-repeat;
  302. background-size: cover;
  303. }
  304. }
  305. .automation-content-rever {
  306. border-bottom: none;
  307. border-radius: 16rpx 16rpx 0 0;
  308. position: relative;
  309. &::before {
  310. position: absolute;
  311. content: '';
  312. top: 0;
  313. left: 0;
  314. right: 0;
  315. bottom: 0;
  316. background: url('./assets/controlbg.png') no-repeat;
  317. background-size: cover;
  318. transform: rotateY(180deg);
  319. transform-origin: center center;
  320. }
  321. }
  322. .automation-header {
  323. width: 100%;
  324. display: flex;
  325. .automation-header-item {
  326. width: 50%;
  327. height: 80rpx;
  328. display: flex;
  329. justify-content: center;
  330. align-items: center;
  331. font-size: 36rpx;
  332. color: #687a74;
  333. text-align: center;
  334. font-family: 'Source Han Sans CN VF';
  335. font-size: 32rpx;
  336. font-weight: 400;
  337. position: relative;
  338. }
  339. .automation-header-item-active {
  340. color: #042118;
  341. text-align: center;
  342. font-family: 'Source Han Sans CN VF';
  343. font-size: 32rpx;
  344. font-weight: 500;
  345. position: relative;
  346. }
  347. .automation-header-item-icon {
  348. width: 28rpx;
  349. height: 4rpx;
  350. border-radius: 4rpx;
  351. background-color: #14a478;
  352. position: absolute;
  353. bottom: 0;
  354. }
  355. .automation-header-item-icon-bottom {
  356. background-color: transparent;
  357. }
  358. }
  359. .automation-body {
  360. height: calc(100vh - 250rpx);
  361. overflow: hidden;
  362. .automation-body-title {
  363. position: relative;
  364. color: #042118;
  365. font-family: 'Source Han Sans CN VF';
  366. font-size: 28rpx;
  367. font-weight: 500;
  368. margin: 48rpx 32rpx 16rpx 32rpx;
  369. }
  370. }
  371. .automation-footer {
  372. position: fixed;
  373. width: 100%;
  374. padding: 16rpx 0;
  375. background: #fff;
  376. box-shadow: 0 -4rpx 8rpx 0 #0000001a;
  377. bottom: 0;
  378. height: 80rpx;
  379. display: flex;
  380. justify-content: space-between;
  381. align-items: center;
  382. .automation-footer-left {
  383. width: 50%;
  384. margin-left: 32rpx;
  385. color: #9ba6a3;
  386. font-family: 'Source Han Sans CN VF';
  387. font-size: 28rpx;
  388. font-weight: 400;
  389. .automation-footer-left-num {
  390. color: #14a478;
  391. text-align: center;
  392. font-family: 'Source Han Sans CN VF';
  393. font-size: 28rpx;
  394. font-style: normal;
  395. font-weight: 700;
  396. margin: 0 8rpx;
  397. }
  398. }
  399. .automation-footer-right {
  400. width: 224rpx;
  401. border-radius: 16rpx;
  402. background-color: #14a478;
  403. color: #ffffff;
  404. text-align: center;
  405. font-family: 'Source Han Sans CN VF';
  406. font-size: 32rpx;
  407. font-weight: 400;
  408. padding: 16rpx 0;
  409. margin-right: 32rpx;
  410. }
  411. }
  412. }
  413. </style>