deviceControl.vue 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833
  1. <template>
  2. <view class="device-detail">
  3. <view class="device-detail__header">
  4. <u-icon
  5. size="36"
  6. class="arrow-left"
  7. name="arrow-left"
  8. @click="handleBack"
  9. ></u-icon>
  10. {{ title }}
  11. </view>
  12. <view class="device-detail__body">
  13. <view class="tabs">
  14. <view class="tab-container">
  15. <view class="tab-item" v-if="myuser_type" :class="activeTab === 'pestAnalysis'?'active':''" @click="handleTabClick('pestAnalysis')">
  16. 管理员
  17. </view>
  18. <view class="tab-item" :class="activeTab === 'viewImage'?'active':''" @click="handleTabClick('viewImage')">
  19. 设置
  20. </view>
  21. </view>
  22. </view>
  23. <view class="device-detail-content" v-if="activeTab === 'pestAnalysis'">
  24. <view class="device-detail-item">
  25. <text class="device-detail-label">联网模块</text>
  26. <view class="device-detail-btn-container">
  27. <view class="device-detail-btn" @click="setDeviceContorl('dtu_update')">升级</view>
  28. <view class="device-detail-btn" @click="setDeviceContorl('dtu_reboot')">重启</view>
  29. <!-- <view class="device-detail-btn" @click="showMqttConfig">MQTT配置</view> -->
  30. <view class="device-detail-btn" @click="setDeviceContorl('yfwlw')">平台切换</view>
  31. </view>
  32. </view>
  33. <view class="device-detail-item">
  34. <text class="device-detail-label">板子设置</text>
  35. <view class="device-detail-btn-container">
  36. <!-- <view class="device-detail-btn">查看原始IMEI</view> -->
  37. <view class="device-detail-btn" @click="showMqttConfig('imei')">更改IMEI</view>
  38. </view>
  39. </view>
  40. <view class="device-detail-item">
  41. <text class="device-detail-label">强制操作</text>
  42. <view class="device-detail-btn-container">
  43. <view class="device-detail-btn force-btn" @click="setDeviceContorl('update')">升级</view>
  44. <view class="device-detail-btn force-btn" @click="setDeviceContorl('reboot')">重启</view>
  45. <view class="device-detail-btn force-btn" @click="setDeviceContorl('takephoto')">立即拍照</view>
  46. <view class="device-detail-btn force-btn" @click="setDeviceContorl('autotakephoto')">对焦拍照</view>
  47. <view class="device-detail-btn force-btn" @click="setDeviceContorl('turn')">转仓</view>
  48. </view>
  49. </view>
  50. </view>
  51. <view class="device-detail-content" style="padding-bottom: 50rpx" v-if="activeTab === 'viewImage'">
  52. <view class="device-detail-viewImage">
  53. <u-icon name="clock" color="#0bbc58" size="46"></u-icon>
  54. <text class="device-detail-label" style="margin-left: 10rpx">
  55. 采集开始和关闭时间
  56. </text>
  57. <view class="clear-btn" @click="clearTime">清空</view>
  58. </view>
  59. <view class="time-container" v-for="(item,index) in coll_time" :key="index">
  60. <view class="start-time" @click="showPickerHandler(index,'start_time')">{{item.start_time_label || '开始时间'}}</view>-
  61. <view class="end-time" @click="showPickerHandler(index,'end_time')">{{item.end_time_label || '结束时间'}}
  62. </view><u-icon name="clock" color="#4E5969" size="26" style="padding-right: 20rpx"></u-icon>
  63. </view>
  64. <view class="device-detail-viewImage">
  65. <text class="device-detail-label">高温保护阀值(℃) {{ sliderField === 'tph' && sliderDragValue !== null ? sliderDragValue : equipContrlForm.tph }}</text>
  66. </view>
  67. <view class="slider-container">
  68. <view class="slider-min-value">50</view>
  69. <view
  70. class="custom-progress"
  71. @touchstart.stop="onSliderTouchStart($event, 'tph', 50, 70, 1)"
  72. @touchmove.stop.prevent="onSliderTouchMove($event, 50, 70, 1)"
  73. @touchend.stop="onSliderTouchEnd"
  74. @tap.stop="onSliderTap($event, 'tph', 50, 70, 1)"
  75. >
  76. <view class="progress-track">
  77. <view class="progress-fill" :style="{ width: getProgressWidth(sliderField === 'tph' && sliderDragValue !== null ? sliderDragValue : equipContrlForm.tph, 50, 70) + '%' }"></view>
  78. <view class="progress-thumb" :style="{ left: getProgressWidth(sliderField === 'tph' && sliderDragValue !== null ? sliderDragValue : equipContrlForm.tph, 50, 70) + '%' }"></view>
  79. </view>
  80. </view>
  81. <view class="slider-max-value">70</view>
  82. </view>
  83. <view class="device-detail-viewImage" v-if="device_model == 0">
  84. <text class="device-detail-label">载玻片滴液时间(h) {{ sliderField === 'drop_time' && sliderDragValue !== null ? sliderDragValue : equipContrlForm.drop_time }}</text>
  85. </view>
  86. <view class="slider-container" v-if="device_model == 0">
  87. <view class="slider-min-value">1</view>
  88. <view
  89. class="custom-progress"
  90. @touchstart.stop="onSliderTouchStart($event, 'drop_time', 1, 30, 1)"
  91. @touchmove.stop.prevent="onSliderTouchMove($event, 1, 30, 1)"
  92. @touchend.stop="onSliderTouchEnd"
  93. @tap.stop="onSliderTap($event, 'drop_time', 1, 30, 1)"
  94. >
  95. <view class="progress-track">
  96. <view class="progress-fill" :style="{ width: getProgressWidth(sliderField === 'drop_time' && sliderDragValue !== null ? sliderDragValue : equipContrlForm.drop_time, 1, 30) + '%' }"></view>
  97. <view class="progress-thumb" :style="{ left: getProgressWidth(sliderField === 'drop_time' && sliderDragValue !== null ? sliderDragValue : equipContrlForm.drop_time, 1, 30) + '%' }"></view>
  98. </view>
  99. </view>
  100. <view class="slider-max-value">30</view>
  101. </view>
  102. <view class="device-detail-viewImage" v-if="device_model == 0">
  103. <text class="device-detail-label">孢子培养时间(h) {{ sliderField === 'cul_time' && sliderDragValue !== null ? sliderDragValue : equipContrlForm.cul_time }}</text>
  104. </view>
  105. <view class="slider-container" v-if="device_model == 0">
  106. <view class="slider-min-value">1</view>
  107. <view
  108. class="custom-progress"
  109. @touchstart.stop="onSliderTouchStart($event, 'cul_time', 1, 24, 1)"
  110. @touchmove.stop.prevent="onSliderTouchMove($event, 1, 24, 1)"
  111. @touchend.stop="onSliderTouchEnd"
  112. @tap.stop="onSliderTap($event, 'cul_time', 1, 24, 1)"
  113. >
  114. <view class="progress-track">
  115. <view class="progress-fill" :style="{ width: getProgressWidth(sliderField === 'cul_time' && sliderDragValue !== null ? sliderDragValue : equipContrlForm.cul_time, 1, 24) + '%' }"></view>
  116. <view class="progress-thumb" :style="{ left: getProgressWidth(sliderField === 'cul_time' && sliderDragValue !== null ? sliderDragValue : equipContrlForm.cul_time, 1, 24) + '%' }"></view>
  117. </view>
  118. </view>
  119. <view class="slider-max-value">24</view>
  120. </view>
  121. <view class="device-detail-viewImage" v-if="device_model == 0">
  122. <text class="device-detail-label">保温仓设定温度(℃) {{ sliderField === 'set_temp' && sliderDragValue !== null ? sliderDragValue : equipContrlForm.set_temp }}</text>
  123. </view>
  124. <view class="slider-container" v-if="device_model == 0">
  125. <view class="slider-min-value">10</view>
  126. <view
  127. class="custom-progress"
  128. @touchstart.stop="onSliderTouchStart($event, 'set_temp', 10, 40, 1)"
  129. @touchmove.stop.prevent="onSliderTouchMove($event, 10, 40, 1)"
  130. @touchend.stop="onSliderTouchEnd"
  131. @tap.stop="onSliderTap($event, 'set_temp', 10, 40, 1)"
  132. >
  133. <view class="progress-track">
  134. <view class="progress-fill" :style="{ width: getProgressWidth(sliderField === 'set_temp' && sliderDragValue !== null ? sliderDragValue : equipContrlForm.set_temp, 10, 40) + '%' }"></view>
  135. <view class="progress-thumb" :style="{ left: getProgressWidth(sliderField === 'set_temp' && sliderDragValue !== null ? sliderDragValue : equipContrlForm.set_temp, 10, 40) + '%' }"></view>
  136. </view>
  137. </view>
  138. <view class="slider-max-value">40</view>
  139. </view>
  140. <view class="device-detail-viewImage">
  141. <text class="device-detail-label">低温保护阀值(℃) {{ sliderField === 'tpl' && sliderDragValue !== null ? sliderDragValue : equipContrlForm.tpl }}</text>
  142. </view>
  143. <view class="slider-container">
  144. <view class="slider-min-value">-30</view>
  145. <view
  146. class="custom-progress"
  147. @touchstart.stop="onSliderTouchStart($event, 'tpl', -30, 20, 1)"
  148. @touchmove.stop.prevent="onSliderTouchMove($event, -30, 20, 1)"
  149. @touchend.stop="onSliderTouchEnd"
  150. @tap.stop="onSliderTap($event, 'tpl', -30, 20, 1)"
  151. >
  152. <view class="progress-track">
  153. <view class="progress-fill" :style="{ width: getProgressWidth(sliderField === 'tpl' && sliderDragValue !== null ? sliderDragValue : equipContrlForm.tpl, -30, 20) + '%' }"></view>
  154. <view class="progress-thumb" :style="{ left: getProgressWidth(sliderField === 'tpl' && sliderDragValue !== null ? sliderDragValue : equipContrlForm.tpl, -30, 20) + '%' }"></view>
  155. </view>
  156. </view>
  157. <view class="slider-max-value">20</view>
  158. </view>
  159. <!-- 滤网更换周期:仅孢子仪2.1(device_code=1)支持 -->
  160. <view class="device-detail-viewImage" v-if="device_code == 1">
  161. <text class="device-detail-label">滤网更换周期(天) {{ sliderField === 'freq_filter' && sliderDragValue !== null ? sliderDragValue : equipContrlForm.freq_filter }}</text>
  162. </view>
  163. <view class="slider-container" v-if="device_code == 1">
  164. <view class="slider-min-value">1</view>
  165. <view
  166. class="custom-progress"
  167. @touchstart.stop="onSliderTouchStart($event, 'freq_filter', 1, 30, 1)"
  168. @touchmove.stop.prevent="onSliderTouchMove($event, 1, 30, 1)"
  169. @touchend.stop="onSliderTouchEnd"
  170. @tap.stop="onSliderTap($event, 'freq_filter', 1, 30, 1)"
  171. >
  172. <view class="progress-track">
  173. <view class="progress-fill" :style="{ width: getProgressWidth(sliderField === 'freq_filter' && sliderDragValue !== null ? sliderDragValue : equipContrlForm.freq_filter, 1, 30) + '%' }"></view>
  174. <view class="progress-thumb" :style="{ left: getProgressWidth(sliderField === 'freq_filter' && sliderDragValue !== null ? sliderDragValue : equipContrlForm.freq_filter, 1, 30) + '%' }"></view>
  175. </view>
  176. </view>
  177. <view class="slider-max-value">30</view>
  178. </view>
  179. <view class="device-detail-viewImage">
  180. <text class="device-detail-label">数据上传间隔(min) {{ sliderField === 'datt' && sliderDragValue !== null ? sliderDragValue : equipContrlForm.datt }}</text>
  181. </view>
  182. <view class="slider-container">
  183. <view class="slider-min-value">10</view>
  184. <view
  185. class="custom-progress"
  186. @touchstart.stop="onSliderTouchStart($event, 'datt', 10, 60, 10)"
  187. @touchmove.stop.prevent="onSliderTouchMove($event, 10, 60, 10)"
  188. @touchend.stop="onSliderTouchEnd"
  189. @tap.stop="onSliderTap($event, 'datt', 10, 60, 10)"
  190. >
  191. <view class="progress-track">
  192. <view class="progress-fill" :style="{ width: getProgressWidth(sliderField === 'datt' && sliderDragValue !== null ? sliderDragValue : equipContrlForm.datt, 10, 60) + '%' }"></view>
  193. <view class="progress-thumb" :style="{ left: getProgressWidth(sliderField === 'datt' && sliderDragValue !== null ? sliderDragValue : equipContrlForm.datt, 10, 60) + '%' }"></view>
  194. </view>
  195. </view>
  196. <view class="slider-max-value">60</view>
  197. </view>
  198. </view>
  199. </view>
  200. <view class="device-detail-btn-footer" v-if="activeTab === 'viewImage'">
  201. <view class="device-detail-btn" @click="saveSettings">保存</view>
  202. </view>
  203. <u-popup v-model="show" mode="bottom">
  204. <view class="device-detail-content" style="height: 50vh">
  205. <view class="device-detail-item">
  206. <text class="device-detail-label">请输入imei</text>
  207. <u-input v-model="equipContrlForm.imei" placeholder="请输入imei"></u-input>
  208. </view>
  209. </view>
  210. <view class="device-detail-btn-footer">
  211. <view class="device-detail-btn" @click="setDeviceContorl('imei')">保存</view>
  212. </view>
  213. </u-popup>
  214. <u-select v-model="showPicker" :list="timeList" @confirm="confirmPicker"></u-select>
  215. </view>
  216. </template>
  217. <script>
  218. export default {
  219. data(){
  220. return {
  221. showPicker: false,
  222. value: 10,
  223. timeList: [],
  224. imageList: [],
  225. coll_time:[{
  226. start_time: '',
  227. start_time_label: '',
  228. end_time: '',
  229. end_time_label: '',
  230. },{
  231. start_time: '',
  232. start_time_label: '',
  233. end_time: '',
  234. end_time_label: '',
  235. },{
  236. start_time: '',
  237. start_time_label: '',
  238. end_time: '',
  239. end_time_label: '',
  240. }],
  241. equipContrlForm: {},
  242. time: '',
  243. activeTab: 'pestAnalysis',
  244. myuser_type: false,
  245. title: '设置控制',
  246. deviceType: '',
  247. location: '',
  248. d_id: '',
  249. show: false,
  250. checked: false,
  251. currentIndex: -1,
  252. currentType: '',
  253. sliderDragValue: null,
  254. sliderRect: null,
  255. sliderField: '',
  256. sliderMin: 0,
  257. sliderMax: 100,
  258. device_model: '',
  259. device_code: '',
  260. sliderStep: 1
  261. }
  262. },
  263. onLoad(options){
  264. this.d_id = options.d_id;
  265. this.device_model = options.device_model;
  266. this.device_code = options.device_code || '';
  267. this.getControlDeviceConfigInfo();
  268. this.timeList = [];
  269. for(let i = 0;i<24;i++){
  270. this.timeList.push({
  271. value:i,
  272. label:i < 10 ? '0' + i + ':00' : i + ':00'
  273. })
  274. }
  275. uni.getStorage({
  276. key:"myuser_type",
  277. success:(res)=>{
  278. if(Number(res.data) == 1){
  279. this.myuser_type = true
  280. this.activeTab = 'pestAnalysis'
  281. }else{
  282. this.activeTab = 'viewImage'
  283. this.$nextTick(() => {
  284. this.cacheSliderRect()
  285. })
  286. }
  287. }
  288. })
  289. },
  290. methods: {
  291. getProgressWidth(value, min, max) {
  292. if (max === min) return 0
  293. return ((value - min) / (max - min)) * 100
  294. },
  295. cacheSliderRect() {
  296. const query = uni.createSelectorQuery().in(this)
  297. query.select('.custom-progress').boundingClientRect(rect => {
  298. if (rect) {
  299. this.sliderRect = rect
  300. }
  301. }).exec()
  302. },
  303. onSliderTouchStart(e, field, min, max, step) {
  304. this.sliderField = field
  305. this.sliderMin = min
  306. this.sliderMax = max
  307. this.sliderStep = step || 1
  308. this._lastUpdateTime = 0
  309. this._touchX = e.touches[0].clientX
  310. if (!this.sliderRect) {
  311. const query = uni.createSelectorQuery().in(this)
  312. query.select('.custom-progress').boundingClientRect(rect => {
  313. this.sliderRect = rect
  314. this._applyDragValue(e.touches[0].clientX)
  315. }).exec()
  316. } else {
  317. this._applyDragValue(e.touches[0].clientX)
  318. }
  319. },
  320. onSliderTouchMove(e, min, max, step) {
  321. if (!this.sliderField || !this.sliderRect) return
  322. this._touchX = e.touches[0].clientX
  323. const now = Date.now()
  324. if (now - this._lastUpdateTime < 33) return
  325. this._lastUpdateTime = now
  326. this._applyDragValue(e.touches[0].clientX)
  327. },
  328. onSliderTouchEnd(e) {
  329. const clientX = (e.changedTouches && e.changedTouches[0])
  330. ? e.changedTouches[0].clientX
  331. : this._touchX
  332. if (this.sliderField && this.sliderRect && clientX != null) {
  333. const ratio = Math.max(0, Math.min(1,
  334. (clientX - this.sliderRect.left) / this.sliderRect.width))
  335. const value = this._snapToStep(Math.round(this.sliderMin + ratio * (this.sliderMax - this.sliderMin)))
  336. this.$set(this.equipContrlForm, this.sliderField, value)
  337. }
  338. this.sliderField = ''
  339. this.sliderDragValue = null
  340. this._lastUpdateTime = 0
  341. this._touchX = 0
  342. },
  343. onSliderTap(e, field, min, max, step) {
  344. const snap = step || 1
  345. const apply = (rect) => {
  346. const ratio = Math.max(0, Math.min(1, e.detail.x / rect.width))
  347. const raw = Math.round(min + ratio * (max - min))
  348. const snapped = Math.round((raw - min) / snap) * snap + min
  349. this.$set(this.equipContrlForm, field, Math.max(min, Math.min(max, snapped)))
  350. }
  351. if (!this.sliderRect) {
  352. const query = uni.createSelectorQuery().in(this)
  353. query.select('.custom-progress').boundingClientRect(rect => {
  354. this.sliderRect = rect
  355. apply(rect)
  356. }).exec()
  357. } else {
  358. apply(this.sliderRect)
  359. }
  360. },
  361. _applyDragValue(clientX) {
  362. const ratio = Math.max(0, Math.min(1,
  363. (clientX - this.sliderRect.left) / this.sliderRect.width))
  364. const raw = Math.round(this.sliderMin + ratio * (this.sliderMax - this.sliderMin))
  365. this.sliderDragValue = this._snapToStep(raw)
  366. },
  367. _snapToStep(value) {
  368. const step = this.sliderStep || 1
  369. const snapped = Math.round((value - this.sliderMin) / step) * step + this.sliderMin
  370. return Math.max(this.sliderMin, Math.min(this.sliderMax, snapped))
  371. },
  372. clearTime(){
  373. this.coll_time.forEach(item => {
  374. item.start_time = '';
  375. item.start_time_label = '';
  376. item.end_time = '';
  377. item.end_time_label = '';
  378. })
  379. },
  380. confirmPicker(e){
  381. const value = e[0].value;
  382. const label = e[0].label;
  383. if(this.currentType == 'end_time'){
  384. if(this.coll_time[this.currentIndex]['start_time'] > value){
  385. uni.showToast({
  386. title: '结束时间不能早于开始时间',
  387. icon: 'none',
  388. })
  389. return
  390. }
  391. }
  392. if(this.currentType == 'start_time' && this.currentIndex > 0){
  393. if(this.coll_time[this.currentIndex-1]['end_time'] > value){
  394. uni.showToast({
  395. title: '开始时间不能早于前面采集时间的结束时间',
  396. icon: 'none',
  397. })
  398. return
  399. }
  400. }
  401. if(this.currentType == 'start_time' && this.coll_time[this.currentIndex]['end_time'] !== ''){
  402. if(value > this.coll_time[this.currentIndex]['end_time']){
  403. uni.showToast({
  404. title: '开始时间不能晚于结束时间',
  405. icon: 'none',
  406. })
  407. return
  408. }
  409. }
  410. this.coll_time[this.currentIndex][this.currentType] = value;
  411. this.coll_time[this.currentIndex][this.currentType + '_label'] = label;
  412. },
  413. showPickerHandler(index,type){
  414. if(type == 'end_time'){
  415. if(this.coll_time[index]['start_time'] === ''){
  416. uni.showToast({
  417. title: '请先选择开始时间',
  418. icon: 'none',
  419. })
  420. return
  421. }
  422. }
  423. if(index != 0){
  424. if(this.coll_time[index-1]['start_time_label'] === '' || this.coll_time[index-1]['end_time_label'] === ''){
  425. uni.showToast({
  426. title: '请先选择前面采集时间的开始和结束时间',
  427. icon: 'none',
  428. })
  429. return
  430. }
  431. }
  432. this.showPicker = true;
  433. this.currentIndex = index
  434. this.currentType = type
  435. },
  436. closePicker(){
  437. this.showPicker = false;
  438. this.currentType = ''
  439. this.currentIndex = -1
  440. },
  441. handleBack() {
  442. uni.navigateBack({
  443. delta: 1
  444. });
  445. },
  446. handleTabClick(tab) {
  447. this.activeTab = tab;
  448. if (tab === 'viewImage') {
  449. this.$nextTick(() => {
  450. this.cacheSliderRect()
  451. })
  452. }
  453. },
  454. showMqttConfig(){
  455. this.show = true;
  456. },
  457. closeMqttConfig(){
  458. this.show = false;
  459. },
  460. async setDeviceContorl(type){
  461. const data = {
  462. device_type_id: 7,
  463. d_id: this.d_id,
  464. cmd: type,
  465. }
  466. if(type === 'imei'){
  467. data.imei = this.equipContrlForm.imei
  468. }else{
  469. delete data.imei
  470. }
  471. this.$myRequest({
  472. url: '/api/api_gateway?method=forecast.send_control.admin_device_control',
  473. method: 'POST',
  474. data
  475. }).then(res => {
  476. this.closeMqttConfig()
  477. if (res) {
  478. uni.showToast({
  479. title: '设备控制修改成功!',
  480. icon: 'success',
  481. });
  482. } else {
  483. uni.showToast({
  484. title: '设备控制修改失败',
  485. icon: 'error',
  486. });
  487. }
  488. });
  489. },
  490. saveSettings(){
  491. let newForm = Object.assign({}, this.equipContrlForm) // 深拷贝
  492. // newForm.st = newForm.st + ''
  493. // newForm.et = newForm.et + ''
  494. // newForm.st && newForm.st.slice(0, 2).charAt(0) != '0'
  495. // ? newForm.st.slice(0, 2)
  496. // : newForm.st.slice(1, 2)
  497. // newForm.et =
  498. // newForm.et && newForm.et.slice(0, 2).charAt(0) != '0'
  499. // ? newForm.et.slice(0, 2)
  500. // : newForm.et.slice(1, 2)
  501. for (let k in newForm) {
  502. if (typeof newForm[k] === 'number') {
  503. newForm[k] = newForm[k] + ''
  504. }
  505. }
  506. // newForm.st = newForm.st.replace(':00', '')
  507. console.log(this.coll_time,'coll_timecoll_timecoll_time')
  508. const coll_time = [];
  509. for(let i = 0;i< this.coll_time.length;i++){
  510. const coll_item = this.coll_time[i];
  511. if(String(coll_item.start_time) && String(coll_item.end_time)){
  512. coll_time.push(String(coll_item.start_time) + '-' + String(coll_item.end_time))
  513. }
  514. }
  515. newForm.coll_time = coll_time
  516. newForm.admin = Number(newForm.admin);
  517. newForm.drop_time = Number(newForm.drop_time);
  518. newForm.cul_time = Number(newForm.cul_time);
  519. newForm.set_temp = Number(newForm.set_temp);
  520. newForm.datt = Number(newForm.datt);
  521. newForm.cold_sw = Number(newForm.cold_sw);
  522. newForm.on_off = Number(newForm.on_off);
  523. newForm.tpl = Number(newForm.tpl);
  524. newForm.tph = Number(newForm.tph);
  525. newForm.freq_filter = Number(newForm.freq_filter);
  526. if(this.device_model == 0){
  527. delete newForm.tpl
  528. delete newForm.tph
  529. }
  530. // 滤网更换周期仅孢子仪2.1(device_code=1)支持
  531. if(this.device_code == 1){
  532. newForm.freq_filter = Number(newForm.freq_filter);
  533. }else{
  534. delete newForm.freq_filter
  535. }
  536. this.$myRequest({
  537. url: '/api/api_gateway?method=forecast.send_control.device_control',
  538. method: 'POST',
  539. data: {
  540. device_type_id: 7,
  541. d_id: this.d_id,
  542. config: JSON.stringify(newForm)
  543. }
  544. }).then(res => {
  545. if (res) {
  546. // 设备控制修改成功
  547. uni.showToast({
  548. title: '设备控制修改成功!',
  549. icon: 'success',
  550. });
  551. } else {
  552. uni.showToast({
  553. title: '设备控制修改失败',
  554. icon: 'error',
  555. });
  556. }
  557. })
  558. },
  559. async getControlDeviceConfigInfo(){
  560. const res = await this.$myRequest({
  561. url: '/api/api_gateway?method=forecast.send_control.device_control_info',
  562. method: 'POST',
  563. data: {
  564. d_id: this.d_id,
  565. cmd:'paramconf'
  566. },
  567. });
  568. this.equipContrlForm = res
  569. // 2.1 设备的滤网更换周期缺省按 1 天显示
  570. if(this.device_code == 1){
  571. this.equipContrlForm.freq_filter = parseInt(this.equipContrlForm.freq_filter || 1);
  572. }
  573. const coll_time = res?.coll_time || [];
  574. for(let i = 0;i< coll_time.length;i++){
  575. const coll_item = coll_time[i];
  576. const start_time = coll_item.split('-')[0];
  577. const end_time = coll_item.split('-')[1];
  578. this.coll_time[i]['start_time'] = start_time;
  579. this.coll_time[i]['end_time'] = end_time;
  580. this.coll_time[i]['start_time_label'] = start_time >= 10 ? start_time + ':00' : '0' + start_time + ':00';
  581. this.coll_time[i]['end_time_label'] = end_time >= 10 ? end_time + ':00' : '0' + end_time + ':00';
  582. }
  583. console.log(this.coll_time,'coll_timecoll_timecoll_time')
  584. this.equipContrlForm.tph = Number(this.equipContrlForm.tph || 50)
  585. this.equipContrlForm.tpl = Number(this.equipContrlForm.tpl || 0)
  586. },
  587. }
  588. }
  589. </script>
  590. <style scoped lang="scss">
  591. .device-detail {
  592. display: flex;
  593. width: 100%;
  594. height: calc(100vh - 112rpx);
  595. padding-top: 112rpx;
  596. flex-direction: column;
  597. align-items: center;
  598. background: linear-gradient(180deg, #ffffff00 0%, #F5F6FA 23.64%, #F5F6FA 100%), linear-gradient(102deg, #BFEADD 6.77%, #B8F1E7 40.15%, #B9EEF5 84.02%);
  599. .device-detail__header {
  600. width: 100%;
  601. font-size: 28rpx;
  602. color: #999;
  603. color: #042118;
  604. font-family: 'Source Han Sans CN VF';
  605. font-weight: 700;
  606. position: relative;
  607. text-align: center;
  608. .arrow-left {
  609. position: absolute;
  610. left: 32rpx;
  611. margin-right: 12rpx;
  612. }
  613. }
  614. .time-container{
  615. display: flex;
  616. justify-content: center;
  617. align-items: center;
  618. color: #999999;
  619. border-radius: 8rpx;
  620. background:#F6F8FC;
  621. gap: 12rpx;
  622. .start-time{
  623. width: 250rpx;
  624. height: 50rpx;
  625. line-height: 50rpx;
  626. text-align: left;
  627. font-size: 24rpx;
  628. color: #999999;
  629. font-family: 'Source Han Sans CN VF';
  630. border-radius: 16rpx;
  631. padding: 0 24rpx;
  632. }
  633. .end-time{
  634. width: 200rpx;
  635. height: 50rpx;
  636. line-height: 50rpx;
  637. text-align: left;
  638. font-size: 24rpx;
  639. color: #999999;
  640. font-family: 'Source Han Sans CN VF';
  641. border-radius: 16rpx;
  642. padding: 0 24rpx;
  643. }
  644. }
  645. .device-detail__body {
  646. width: calc(100% - 64rpx);
  647. margin: 0 auto;
  648. border-radius: 16rpx;
  649. overflow-x: hidden;
  650. overflow-y: auto;
  651. // 隐藏滚动条
  652. -ms-overflow-style: none;
  653. scrollbar-width: none;
  654. }
  655. .tabs {
  656. margin: 24rpx 0;
  657. border-radius: 16rpx;
  658. padding: 16rpx 0;
  659. padding-top: 0;
  660. .tab-container{
  661. display: flex;
  662. width: 100%;
  663. height: 88rpx;
  664. line-height: 88rpx;
  665. text-align: center;
  666. font-size: 28rpx;
  667. color: #042118;
  668. font-family: 'Source Han Sans CN VF';
  669. }
  670. .tab-item {
  671. margin-right: 40rpx;
  672. color:#999999;
  673. }
  674. .active{
  675. position: relative;
  676. color: #0bbc58;
  677. text-align: center;
  678. font-family: "Source Han Sans CN VF";
  679. font-size: 28rpx;
  680. font-weight: 700;
  681. &::after {
  682. content: '';
  683. position: absolute;
  684. bottom: 10rpx;
  685. left: 50%;
  686. transform: translateX(-50%);
  687. width: 100%;
  688. height: 36rpx;
  689. border-bottom: 6rpx solid #0bbc58;
  690. }
  691. }
  692. }
  693. .slider-container{
  694. position: relative;
  695. margin-bottom: 20rpx;
  696. .slider-min-value{
  697. position: absolute;
  698. left: 0;
  699. top: -50rpx;
  700. }
  701. .slider{
  702. width: 600rpx;
  703. }
  704. .slider-max-value{
  705. position: absolute;
  706. right: 0;
  707. top: -50rpx;
  708. }
  709. }
  710. .custom-progress{
  711. width: 600rpx;
  712. padding: 0;
  713. .progress-track{
  714. position: relative;
  715. height: 12rpx;
  716. background-color: #ebedf0;
  717. border-radius: 6rpx;
  718. }
  719. .progress-fill{
  720. position: absolute;
  721. left: 0;
  722. top: 0;
  723. height: 100%;
  724. background-color: #0BBC58;
  725. border-radius: 6rpx;
  726. }
  727. .progress-thumb{
  728. position: absolute;
  729. top: 50%;
  730. width: 28rpx;
  731. height: 28rpx;
  732. margin-left: -14rpx;
  733. margin-top: -14rpx;
  734. border-radius: 50%;
  735. background-color: #fff;
  736. box-shadow: 0 1px 4px rgba(0,0,0,0.3);
  737. }
  738. }
  739. .device-detail-content{
  740. display: flex;
  741. padding: 24rpx 32rpx;
  742. flex-direction: column;
  743. align-items: flex-start;
  744. gap: 20rpx;
  745. border-radius: 16rpx;
  746. background: #FFF;
  747. .device-detail-item{
  748. .device-detail-label{
  749. color: #303133;
  750. font-family: "Source Han Sans CN VF";
  751. font-size: 28rpx;
  752. font-weight: 400;
  753. }
  754. .device-detail-btn-container{
  755. display: flex;
  756. gap: 24rpx;
  757. margin-top: 12rpx;
  758. }
  759. .device-detail-btn{
  760. display: flex;
  761. padding: 10rpx 16rpx;
  762. justify-content: center;
  763. align-items: center;
  764. gap: 16rpx;
  765. border-radius: 16rpx;
  766. background: #0bbc58;
  767. color: #ffffff;
  768. font-family: "Source Han Sans CN VF";
  769. font-size: 24rpx;
  770. font-weight: 400;
  771. }
  772. .force-btn{
  773. background: #FB4E52;
  774. }
  775. }
  776. .device-detail-viewImage{
  777. width: 100%;
  778. display: flex;
  779. align-items: center;
  780. padding-bottom: 20rpx;
  781. position: relative;
  782. .clear-btn{
  783. position: absolute;
  784. right: 0rpx;
  785. border: 1rpx solid #0bbc58;
  786. border-radius: 8rpx;
  787. padding: 4rpx 12rpx;
  788. font-size: 24rpx;
  789. color: #0bbc58;
  790. font-family: 'Source Han Sans CN VF';
  791. font-weight: 400;
  792. }
  793. }
  794. }
  795. .device-detail-btn-footer{
  796. position: fixed;
  797. bottom: 0;
  798. left: 0;
  799. width: 100%;
  800. height: 112rpx;
  801. line-height: 112rpx;
  802. text-align: center;
  803. font-size: 28rpx;
  804. font-weight: 700;
  805. color: #042118;
  806. font-family: 'Source Han Sans CN VF';
  807. background: #ffffff;
  808. display: flex;
  809. justify-content: center;
  810. align-items: center;
  811. .device-detail-btn{
  812. display: flex;
  813. height: 80rpx;
  814. width: 90%;
  815. margin: 0 auto;
  816. padding: 0rpx 20rpx;
  817. justify-content: center;
  818. align-items: center;
  819. gap: 8rpx;
  820. border-radius: 16rpx;
  821. background:#0bbc58;
  822. color: #ffffff;
  823. text-align: center;
  824. font-family: "Source Han Sans CN VF";
  825. font-size: 14px;
  826. font-style: normal;
  827. font-weight: 500;
  828. }
  829. }
  830. }
  831. </style>