deviceSetting.vue 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586
  1. <template>
  2. <view class="setting-warp">
  3. <view class="clientInfo">
  4. <view class="wifItem">
  5. <text>设备序列号</text>
  6. <text>{{ devInfo.clientId }}</text>
  7. </view>
  8. <view class="wifItem">
  9. <text>设备ID</text>
  10. <text>{{ devInfo.devId }}</text>
  11. </view>
  12. <!-- <view class="wifItem">
  13. <text>设备分组</text>
  14. <text>{{}}</text>
  15. </view> -->
  16. <view class="wifItem">
  17. <text>安装位置</text>
  18. <text>{{ position }}</text>
  19. </view>
  20. <view class="wifItem">
  21. <text>硬件版本</text>
  22. <text>{{ devInfo.hardware }}</text>
  23. </view>
  24. <view class="menu-item">
  25. <view class="meanLeft">设备升级</view>
  26. <view class="meanRight" v-if="otaList.length > 0">
  27. <picker
  28. @change="bindPickerChangeTwo"
  29. :value="otaIndex"
  30. :range="otaListName"
  31. >
  32. <view class="uni-input">{{ otaListName[0] }}</view>
  33. </picker>
  34. <image
  35. src="../../static/rightArrow.png"
  36. alt=""
  37. @click="showPicker"
  38. ></image>
  39. </view>
  40. <view class="meanRight" v-else> 已是最新版本,无需升级 </view>
  41. </view>
  42. </view>
  43. <view class="clientInfo" style="margin-top: 40rpx">
  44. <view class="wifItem" @click="goShareCount">
  45. <text>分享记录</text>
  46. <image
  47. src="../../static/rightArrow.png"
  48. style="width: 30rpx; height: 30rpx"
  49. ></image>
  50. </view>
  51. <!-- <view class="wifItem">
  52. <text>紧急联系人</text>
  53. <text>{{}}</text>
  54. </view> -->
  55. <!-- <view class="wifItem">
  56. <text>撤销分享</text>
  57. <image
  58. src="../../static/rightArrow.png"
  59. style="width: 40rpx; height: 40rpx"
  60. ></image>
  61. </view> -->
  62. <view class="wifItem" @click="goFailDetail">
  63. <text>跌倒事件</text>
  64. <image
  65. src="../../static/rightArrow.png"
  66. style="width: 30rpx; height: 30rpx"
  67. ></image>
  68. </view>
  69. <view class="wifItem" @click="showRemoveDevice">
  70. <text>设备转移</text>
  71. <image
  72. src="../../static/rightArrow.png"
  73. style="width: 30rpx; height: 30rpx"
  74. ></image>
  75. </view>
  76. <view class="wifItem" @click="unbindDevice">
  77. <text>设备解绑</text>
  78. <image
  79. src="../../static/rightArrow.png"
  80. style="width: 30rpx; height: 30rpx"
  81. ></image>
  82. </view>
  83. </view>
  84. <view class="box">
  85. <view class="handle-btn" v-if="settingFlag">
  86. <view class="btn1" @click="goMoreSetting">更多设置</view>
  87. </view>
  88. <view class="handle-noflage" v-else>
  89. <view class="btn1" @click="goNoSetting">更多设置</view>
  90. </view>
  91. </view>
  92. <tenMinutes v-if="isIniTenMinutes" />
  93. <view class="modal-mask" v-if="removeDeviceModle">
  94. <view class="modal-container">
  95. <view class="modal-header">
  96. <text class="title">设备转移</text>
  97. <image
  98. src="../../static/closePng.png"
  99. @click="removeDeviceModle = false"
  100. class="close-btn"
  101. >
  102. </image>
  103. </view>
  104. <view class="modal-content">
  105. <input
  106. class="input"
  107. placeholder="请输入要转移的手机号"
  108. type="number"
  109. v-model="sharedPhone"
  110. />
  111. </view>
  112. <view class="modal-buttons">
  113. <button
  114. class="btn phone-btn"
  115. @click="handlePhoneAnalysis()"
  116. >
  117. <text>确认转移</text>
  118. </button>
  119. </view>
  120. </view>
  121. </view>
  122. </view>
  123. </template>
  124. <script>
  125. export default {
  126. data() {
  127. return {
  128. devInfo: "",
  129. devName: "",
  130. position: "",
  131. isIniTenMinutes: "",
  132. sharedPhone: "",
  133. removeDeviceModle: false,
  134. // ota部分
  135. otaList: [],
  136. otaListName: [],
  137. otaIndex: 0,
  138. settingFlag: false,
  139. };
  140. },
  141. methods: {
  142. getPosition(val) {
  143. if (val == "Toilet") {
  144. this.position = "卫生间";
  145. } else if (val == "LivingRoom") {
  146. this.position = "客厅";
  147. } else if (val == "Restaurant") {
  148. this.position = "餐厅";
  149. } else if (val == "Bedroom") {
  150. this.position = " 卧室";
  151. }
  152. return this.installPosition;
  153. },
  154. unbindDevice() {
  155. uni.showModal({
  156. title: "提示",
  157. content: "确定要解绑该设备吗?",
  158. success: (res) => {
  159. if (res.confirm) {
  160. this.$http
  161. .get("wap/device/deviceUnBind", {
  162. userId: uni.getStorageSync("userId"),
  163. devId: this.devInfo.devId,
  164. })
  165. .then((res) => {
  166. if (res.data.code == 200) {
  167. uni.showToast({
  168. title: "解绑成功",
  169. icon: "success",
  170. duration: 1500,
  171. });
  172. setTimeout(() => {
  173. uni.reLaunch({
  174. url: "/pagesA/devices/devices",
  175. });
  176. }, 2000);
  177. } else {
  178. uni.showToast({
  179. title: "解绑失败",
  180. icon: "none",
  181. duration: 1500,
  182. });
  183. }
  184. });
  185. }
  186. },
  187. });
  188. },
  189. goMoreSetting() {
  190. uni.navigateTo({
  191. url:
  192. "/pagesA/adDevice/adDevice?devInfo=" +
  193. JSON.stringify(this.devInfo),
  194. });
  195. },
  196. goNoSetting() {
  197. uni.showToast({
  198. title: "您没有设置权限",
  199. icon: "none",
  200. });
  201. },
  202. goFailDetail() {
  203. uni.navigateTo({
  204. url:
  205. "/pagesA/failDetail/failDetail?devInfo=" +
  206. JSON.stringify(this.devInfo),
  207. });
  208. },
  209. goShareCount() {
  210. uni.navigateTo({
  211. url:
  212. "/pagesA/shareCountList/shareCountList?devInfo=" +
  213. JSON.stringify(this.devInfo),
  214. });
  215. },
  216. showRemoveDevice() {
  217. this.removeDeviceModle = true;
  218. },
  219. handlePhoneAnalysis() {
  220. if (!this.sharedPhone) {
  221. uni.showToast({
  222. title: "请输入手机号",
  223. icon: "none",
  224. duration: 1500,
  225. });
  226. return;
  227. }
  228. let reg_tel =
  229. /^(13[0-9]|14[01456879]|15[0-3,5-9]|16[2567]|17[0-8]|18[0-9]|19[0-3,5-9])\d{8}$/;
  230. if (!reg_tel.test(this.sharedPhone)) {
  231. uni.showModal({
  232. content: "请填写正确手机号!",
  233. showCancel: false,
  234. });
  235. return;
  236. }
  237. this.$http
  238. .post(
  239. "wap/device/transfer",
  240. {
  241. userId: uni.getStorageSync("userId"),
  242. devId: this.devInfo.devId,
  243. phone: this.sharedPhone,
  244. },
  245. {
  246. header: {
  247. "Content-Type": "application/json;charset=UTF-8",
  248. token: uni.getStorageSync("tokenValue") || "",
  249. },
  250. }
  251. )
  252. .then((res) => {
  253. if (res.data.code == 200) {
  254. uni.showToast({
  255. title: "转移成功",
  256. icon: "success",
  257. duration: 1500,
  258. });
  259. this.removeDeviceModle = false;
  260. this.sharedPhone = "";
  261. } else {
  262. uni.showToast({
  263. title: "转移失败",
  264. icon: "none",
  265. duration: 1500,
  266. });
  267. this.removeDeviceModle = false;
  268. this.sharedPhone = "";
  269. }
  270. });
  271. },
  272. queryOtaList() {
  273. this.$http.get("wap/device/OTA/query", {}).then((res) => {
  274. this.otaList = this.filterFilesByVersion(
  275. res.data.data,
  276. "2.2.4"
  277. );
  278. this.otaListName = this.otaList.map((ele) => ele.fileName);
  279. });
  280. },
  281. bindPickerChangeTwo(e) {
  282. this.otaIndex = e.detail.value;
  283. this.freshOTA();
  284. },
  285. freshOTA() {
  286. let clientIds = [];
  287. clientIds.push(this.devInfo.clientId);
  288. let ossUrl = this.otaList[this.otaIndex].ossUrl;
  289. this.$http
  290. .post(
  291. "wap/device/OTA/update",
  292. { clientIds: clientIds, ossUrl: ossUrl },
  293. {
  294. header: {
  295. "Content-Type": "application/json;charset=UTF-8",
  296. },
  297. }
  298. )
  299. .then((res) => {
  300. if (res.data.code == 200) {
  301. uni.showToast({
  302. title: "设备升级成功",
  303. icon: "success",
  304. duration: 1500,
  305. });
  306. } else {
  307. uni.showToast({
  308. title: res.data.message,
  309. icon: "none",
  310. duration: 1500,
  311. });
  312. }
  313. });
  314. },
  315. parseVersion(fileName) {
  316. const match = fileName.match(/V(\d+\.\d+\.\d+)/);
  317. return match ? match[1].split(".").map(Number) : [0, 0, 0];
  318. },
  319. compareVersion(v1, v2) {
  320. for (let i = 0; i < Math.max(v1.length, v2.length); i++) {
  321. const num1 = v1[i] || 0;
  322. const num2 = v2[i] || 0;
  323. if (num1 > num2) return 1;
  324. if (num1 < num2) return -1;
  325. }
  326. return 0;
  327. },
  328. filterFilesByVersion(files, minVersionStr) {
  329. const minVersion = minVersionStr.split(".").map(Number);
  330. return files.filter((file) => {
  331. const version = this.parseVersion(file.fileName);
  332. return this.compareVersion(version, minVersion) > 0;
  333. });
  334. },
  335. },
  336. onLoad(options) {
  337. this.isIniTenMinutes = true;
  338. this.devInfo = JSON.parse(options.devInfo);
  339. },
  340. onShow() {
  341. this.isIniTenMinutes = true;
  342. this.getPosition(this.devInfo.installPosition);
  343. this.queryOtaList();
  344. let userId = uni.getStorageSync("userId");
  345. this.settingFlag = this.devInfo.userId == userId ? true : false;
  346. },
  347. onUnload() {
  348. this.isIniTenMinutes = false;
  349. },
  350. onHide() {
  351. this.isIniTenMinutes = false;
  352. },
  353. };
  354. </script>
  355. <style lang="less">
  356. .setting-warp {
  357. position: relative;
  358. padding-top: 40rpx;
  359. height: 100vh;
  360. background: linear-gradient(180deg, #faede2 0%, #f4f4f4 100%);
  361. .clientInfo {
  362. width: 700rpx;
  363. // height: 140px;
  364. margin: 0 auto 0 auto;
  365. background: #ffffff;
  366. border-radius: 38rpx;
  367. box-sizing: border-box;
  368. padding: 0 30rpx 20rpx 30rpx;
  369. .wifItem {
  370. width: 640rpx;
  371. display: flex;
  372. align-content: center;
  373. justify-content: space-between;
  374. border-bottom: 2rpx solid #ebeff5;
  375. padding-top: 30rpx;
  376. padding-bottom: 20rpx;
  377. image {
  378. width: 40rpx;
  379. height: 40rpx;
  380. }
  381. input {
  382. margin-left: auto;
  383. text-align: right;
  384. }
  385. }
  386. .menu-item {
  387. width: 640rpx;
  388. display: flex;
  389. align-content: center;
  390. justify-content: space-between;
  391. border-bottom: 2rpx solid #ebeff5;
  392. padding-top: 30rpx;
  393. padding-bottom: 20rpx;
  394. &:last-child {
  395. border-bottom: none;
  396. }
  397. .meanLeft {
  398. display: flex;
  399. align-items: center;
  400. justify-content: center;
  401. image {
  402. width: 38rpx;
  403. height: 38rpx;
  404. }
  405. text {
  406. margin-left: 10rpx;
  407. color: #111111;
  408. font-size: 32rpx;
  409. }
  410. }
  411. .meanRight {
  412. display: flex;
  413. align-items: center;
  414. }
  415. .meanRight image {
  416. margin-left: 4rpx;
  417. width: 16rpx;
  418. height: 26rpx;
  419. }
  420. }
  421. }
  422. .box {
  423. position: fixed;
  424. bottom: 0;
  425. left: 0;
  426. width: 100vw;
  427. height: 168rpx;
  428. padding: 0 37rpx;
  429. background: #ffffff;
  430. box-sizing: border-box;
  431. .handle-btn {
  432. margin-top: 40rpx;
  433. display: flex;
  434. align-items: center;
  435. justify-content: space-between;
  436. .btn1 {
  437. display: flex;
  438. align-items: center;
  439. justify-content: center;
  440. width: 700rpx;
  441. height: 94rpx;
  442. background: #7d5346;
  443. border-radius: 28rpx;
  444. font-weight: 500;
  445. color: #ffffff;
  446. font-size: 32rpx;
  447. text-align: center;
  448. }
  449. }
  450. .handle-noflage {
  451. margin-top: 40rpx;
  452. display: flex;
  453. align-items: center;
  454. justify-content: space-between;
  455. .btn1 {
  456. display: flex;
  457. align-items: center;
  458. justify-content: center;
  459. width: 700rpx;
  460. height: 94rpx;
  461. border-radius: 28rpx;
  462. font-weight: 500;
  463. background: #f0f0f0;
  464. color: #999999;
  465. font-size: 32rpx;
  466. text-align: center;
  467. }
  468. }
  469. }
  470. .modal-mask {
  471. position: fixed;
  472. top: 0;
  473. left: 0;
  474. right: 0;
  475. bottom: 0;
  476. background: rgba(0, 0, 0, 0.5);
  477. display: flex;
  478. justify-content: center;
  479. align-items: center;
  480. z-index: 333;
  481. .modal-container {
  482. width: 80%;
  483. background: #fff;
  484. border-radius: 16rpx;
  485. // overflow: hidden;
  486. animation: fadeIn 0.3s;
  487. .modal-header {
  488. padding: 30rpx;
  489. text-align: center;
  490. border-bottom: 1rpx solid #f5f5f5;
  491. position: relative;
  492. .title {
  493. font-size: 36rpx;
  494. display: block;
  495. margin-bottom: 10rpx;
  496. }
  497. .close-btn {
  498. position: absolute;
  499. width: 40rpx;
  500. height: 40rpx;
  501. top: 20rpx;
  502. right: 20rpx;
  503. }
  504. }
  505. .modal-content {
  506. padding: 20rpx 20rpx;
  507. .input {
  508. text-align: right;
  509. flex: 1;
  510. border: none;
  511. background: transparent;
  512. font-size: 28rpx;
  513. color: #333;
  514. }
  515. }
  516. .modal-buttons {
  517. display: flex;
  518. flex-direction: column;
  519. padding: 20rpx;
  520. .btn {
  521. flex: 1;
  522. height: 90rpx;
  523. margin: 15rpx 0;
  524. border-radius: 45rpx;
  525. display: flex;
  526. align-items: center;
  527. justify-content: center;
  528. font-size: 32rpx;
  529. border: none;
  530. background: none;
  531. position: relative;
  532. }
  533. .btn-icon {
  534. width: 40rpx;
  535. height: 40rpx;
  536. margin-right: 15rpx;
  537. }
  538. .phone-btn {
  539. background: linear-gradient(
  540. 105.95deg,
  541. #ba978a 0%,
  542. #a27867 100%
  543. );
  544. color: white;
  545. }
  546. .link-btn {
  547. background: linear-gradient(
  548. 105.95deg,
  549. #a27867 0%,
  550. #74483d 100%
  551. );
  552. color: white;
  553. }
  554. }
  555. }
  556. }
  557. }
  558. </style>