deviceControl.vue 28 KB

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