index.vue 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295
  1. <template>
  2. <view :class="['page']">
  3. <view class="device-header">
  4. <view class="device-header_name">
  5. <text>洗车机编号:No.{{ state.device?.shortId }}</text>
  6. </view>
  7. <view class="device-header_fun">
  8. <view class="device-header_func-tag" v-for="f in state.device?.functionList" :key="f" style="margin-right: 10px;">
  9. <uv-tags :text="f" size="mini" plain plainFill bgColor="#19A497" color="white"></uv-tags>
  10. </view>
  11. </view>
  12. <view class="device-header_fun">
  13. <uv-tags plain size="mini" type="primary" :text="fmtDictName('WashDevice.state',state.device.state)"></uv-tags>
  14. </view>
  15. </view>
  16. <view class="device-body">
  17. <view class="device-body_ops" @click="debounceStartStopDevice">
  18. <text v-if="state.device.state==='idle'">启动设备</text>
  19. <text v-else>停止设备</text>
  20. </view>
  21. <view class=device-body_guide>
  22. <view>●点击上方【启动设备】按钮启动设备;
  23. </view>
  24. <view>●设备启动后,请在设备功能面板按下功能按键以选择服务项目;
  25. </view>
  26. <view>●洗车过程中再次按下功能按键可以暂停功能,暂停过程中将停止计费,如需恢复请再次按下功能按键;
  27. </view>
  28. <view>●洗车结束后,请按下结算按键或小程序【停止设备】按钮,设备停止运行之后将结束计费;
  29. </view>
  30. <view>●请在洗车完成后尽快将车辆驶离工位以方便后续用户,谢谢配合。
  31. </view>
  32. </view>
  33. <!-- <view class="device-body_ops-time">{{ state.time }}</view>-->
  34. </view>
  35. <login-bar class="w100 text-center"></login-bar>
  36. </view>
  37. </template>
  38. <script setup lang="ts">
  39. import {onHide, onLoad, onShow} from "@dcloudio/uni-app";
  40. import {reactive, ref} from "vue";
  41. import {debounce, fmtDictName} from "@/utils/common";
  42. import {get, post} from "@/utils/https";
  43. import {checkLogin, fetchToken, tryLogin} from "@/utils/auth";
  44. import LoginBar from "@/components/login-bar/index.vue";
  45. const initState = () => ({
  46. device: {
  47. functions: [],
  48. deviceName: '',
  49. state: ''
  50. },
  51. time: "00:00:00",
  52. start: new Date(),
  53. deviceId:null
  54. })
  55. const state = reactive(initState())
  56. onHide(() => {
  57. Object.assign(state, initState());
  58. })
  59. onLoad((options: any) => {
  60. // uni.showModal({
  61. // title:'onLoad,'+options?.shortId
  62. // })
  63. console.log("device onLoad>>>>", options)
  64. let id = options?.shortId;
  65. if (!id) {
  66. let query = decodeURIComponent(options.q);
  67. let scanTime = options.scancode_time;
  68. console.log(query, scanTime)
  69. if (query) {
  70. id = query.split("#")[1].split("?")[0]
  71. state.deviceId =id;
  72. } else {
  73. return;
  74. }
  75. }
  76. state.device = getApp<any>().globalData.last.device;
  77. checkLogin().then((token) => {
  78. setTimeout(() => {
  79. loadDeviceDetail(id);
  80. }, 200)
  81. }).catch(e=>{
  82. console.error("onLoad 校验登录失败,自动跳转登录页")
  83. uni.navigateTo({
  84. url:`/pages-user/login/index?shortId=${state.deviceId}&redirectUrl=/pages-wash/device/index`
  85. })
  86. })
  87. });
  88. onShow(() => {
  89. addListener();
  90. // uni.showToast({
  91. // title:'onShow,'
  92. // })
  93. checkLogin().then(()=>{
  94. // uni.showToast({
  95. // title:'onShow,loaded'
  96. // })
  97. if (!state.deviceId) {
  98. console.log("deviceId",getApp<any>().globalData.deviceId)
  99. let deviceId = getApp<any>().globalData.deviceId;
  100. if (deviceId) {
  101. loadDeviceDetail(deviceId);
  102. }
  103. }else{
  104. loadDeviceDetail(state.deviceId);
  105. }
  106. }).catch(e=>{
  107. console.error("校验登录失败,自动跳转登录页")
  108. uni.navigateTo({
  109. url:`/pages-user/login/index?shortId=${state.deviceId}&redirectUrl=/pages-wash/device/index`
  110. })
  111. })
  112. })
  113. const addListener = () => {
  114. uni.$on('login', function (data) {
  115. if(state.deviceId && data.isLogin){
  116. loadDeviceDetail(state.deviceId);
  117. }
  118. })
  119. uni.$on('logout', function (data) {
  120. })
  121. }
  122. const removeListener = () => {
  123. uni.$off('logout');
  124. uni.$off('login');
  125. }
  126. const loadDeviceDetail = (id: any) => {
  127. state.deviceId =id;
  128. let ft = fetchToken();
  129. console.log("device token ",ft)
  130. get(`/wash-device/queryDevice/${id}`).then((res: any) => {
  131. if (res.currentUserId && res.currentUserId != getApp<any>().globalData.user.id) {
  132. uni.showToast({
  133. title: '设备已被占用',
  134. icon: 'error'
  135. })
  136. setTimeout(() => {
  137. uni.switchTab({
  138. url: '/pages/index/index'
  139. })
  140. }, 2000)
  141. }
  142. res.functionList = res.functions?.split("|") || []
  143. state.device = res;
  144. getApp<any>().globalData.deviceId = id;
  145. }).catch(e => {
  146. console.error(e)
  147. })
  148. // countTime();
  149. }
  150. const handleNavigateBack = () => {
  151. uni.navigateBack();
  152. }
  153. const debounceStartStopDevice = debounce(() => {
  154. handleClickDevice();
  155. }, 600)
  156. const handleClickDevice = () => {
  157. uni.showModal({
  158. title: '提示',
  159. content: state.device?.state === 'idle' ? '确定启动设备开始洗车吗?' : '确定停止设备终止本次服务吗?',
  160. success: (res) => {
  161. if (res.confirm) {
  162. if (state.device?.state === 'idle') {
  163. uni.showLoading({
  164. title: "启动中",
  165. mask: true,
  166. });
  167. post(`/wash-device/startDevice/${state.device?.shortId}`).then((res: any) => {
  168. uni.hideLoading();
  169. uni.showToast({
  170. title: '设备启动成功'
  171. })
  172. state.device.state = 'busy'
  173. })
  174. } else {
  175. uni.showLoading({
  176. title: "停止中",
  177. mask: true,
  178. });
  179. post(`/wash-device/stopDevice/${state.device?.shortId}`).then((res: any) => {
  180. uni.hideLoading();
  181. uni.showToast({
  182. title: '设备停机成功'
  183. })
  184. state.device.state = 'idle'
  185. })
  186. }
  187. }
  188. }
  189. });
  190. }
  191. const countTime = () => {
  192. setInterval(() => {
  193. let delta = new Date().getTime() - state.start.getTime();
  194. delta = delta / 1000;
  195. let hour = (delta / 3600).toFixed(0);
  196. let min = ((delta % 3600) / 60).toFixed(0);
  197. let second = ((delta % 3600) % 60).toFixed(0);
  198. state.time = [
  199. Number(hour) > 9 ? hour : `0${hour}`,
  200. Number(min) > 9 ? min : `0${min}`,
  201. Number(second) > 9 ? second : `0${second}`
  202. ].join(":")
  203. }, 1000)
  204. }
  205. </script>
  206. <style lang="scss" scoped>
  207. .page {
  208. height: 100vh;
  209. width: 100%;
  210. background-color: #f6f7fa;
  211. }
  212. .device-header {
  213. padding: 20rpx;
  214. display: flex;
  215. flex-direction: column;
  216. justify-content: center;
  217. align-items: center;
  218. &_name {
  219. font-weight: 500;
  220. margin: 15rpx 0;
  221. }
  222. &_fun {
  223. font-size: 13px;
  224. color: #7a7a7a;
  225. margin: 10rpx 0;
  226. display: inline-flex;
  227. &-tag {
  228. margin-right: 10px;
  229. }
  230. }
  231. }
  232. .device-body {
  233. flex-grow: 1;
  234. margin-top: 60rpx;
  235. display: flex;
  236. flex-direction: column;
  237. justify-content: center;
  238. align-items: center;
  239. align-content: center;
  240. &_ops {
  241. display: flex;
  242. justify-content: center;
  243. align-items: center;
  244. align-content: center;
  245. width: 300rpx;
  246. height: 300rpx;
  247. border-radius: 50%;
  248. background-color: $uni-color-primary;
  249. color: white;
  250. font-size: 28px;
  251. font-weight: 500;
  252. }
  253. &_guide {
  254. width: 80%;
  255. margin-top: 40px;
  256. font-size: 14px;
  257. }
  258. }
  259. </style>