index.js 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893
  1. // nova-werun/pages/home/sport/sport-start/index.js
  2. const Parse = getApp().Parse;
  3. const company = getApp().globalData.company;
  4. const uid = Parse.User.current()?.id
  5. let request = require('../../../../../utils/request')
  6. const dateF = require("../../../../../utils/date")
  7. let {
  8. statusBarHeight
  9. } = wx.getSystemInfoSync()
  10. let custom = wx.getMenuButtonBoundingClientRect()
  11. let customHeight = custom.height
  12. Page({
  13. /**
  14. * 页面的初始数据
  15. */
  16. data: {
  17. navheight: 0, //导航高度px
  18. isStop: false, //计时是否暂停
  19. longitude: 0, //经度
  20. latitude: 0, //纬度
  21. markers: [], //地图标记点
  22. showPermissions: true, //权限弹框-开
  23. journey: 0, //运动的路程-米
  24. calorie: 0, //卡路里-千卡
  25. pace: 0, //配速-min/km
  26. timer: 0, //已记的时长-秒
  27. status: 'noStart', //运动状态 'noStart'未开始,'inSports'运动中,'paused'暂停
  28. percentage: '', //长按结束运动百分比
  29. endHaloInterval: null, //光环计时器
  30. endHaloStartDate: null, //光环开始时间戳
  31. endHaloEndDate: null, //光环结束时间戳
  32. isRefershLaLo: true, //是否刷新经纬度
  33. stage: 'start', //运动过程 start,progress,end
  34. actData: null, //运动数据
  35. formattedTime: '00:00:00', // 用于存储格式化后的时间
  36. step: 0, //运动步数
  37. type: 'walk', //运动类型-步行
  38. actDataList: [], //未运动结束数据
  39. isShowActDataList: false, //是否展示未运动结束的数据
  40. checkActDataId: null, //点击的未结束运动
  41. },
  42. /**
  43. * 生命周期函数--监听页面加载
  44. */
  45. onLoad: async function (options) {
  46. wx.offLocationChange()
  47. this.setData({
  48. navheight: customHeight + statusBarHeight + 5,
  49. type: options.type || 'walk', //运动方式 run/walk
  50. a_reg: options.a_reg || '', //所属报名记录 ActivityRegister.id
  51. })
  52. console.log(options)
  53. this.getActivityData()
  54. this.beforeUnload()
  55. // this.getWeRun()
  56. },
  57. /**获取运动数据 */
  58. async getActivityData() {
  59. let {
  60. a_reg,
  61. type
  62. } = this.data
  63. let query = new Parse.Query('ActivityData')
  64. query.equalTo('company', company)
  65. query.equalTo('user', uid)
  66. query.equalTo('type', type)
  67. query.notEqualTo('isDeleted', true)
  68. query.descending('createdAt')
  69. if (a_reg) { //如果传递了报名记录-直接进行这个运动
  70. console.log('如果传递了报名记录-直接进行这个运动')
  71. let actData
  72. query.equalTo('actRegister', a_reg)
  73. actData = await query.first()
  74. if (actData?.get('status') == 'end') {
  75. wx.showToast({
  76. title: '已结算成绩',
  77. icon: 'none'
  78. })
  79. wx.navigateBack({
  80. delta: 1
  81. })
  82. return
  83. }
  84. if (!actData?.id) {
  85. console.log('未查询出运动数据')
  86. let regQuery = new Parse.Query('ActivityRegister')
  87. let act_reg = await regQuery.get(a_reg)
  88. await this.creatActDateFun(act_reg)
  89. return
  90. } else {
  91. console.log('运动未结束')
  92. wx.showToast({
  93. title: '运动未结束',
  94. icon: 'none'
  95. })
  96. await this.assignmentFun(actData?.id)
  97. this.setData({
  98. actData
  99. })
  100. }
  101. } else { //未传递-显示当前类型(run/walk)所有未结束的运动
  102. console.log('/未传递-显示当前类型所有未结束的运动')
  103. let actDataCount
  104. actDataCount = await query.count()
  105. if (actDataCount <= 0 || !actDataCount) {
  106. await this.creatActDateFun()
  107. return
  108. } else {
  109. let sql = `SELECT act_d."objectId",act_d."startDate",act_d."createdAt",act."title",act_r."booking",act."endDate" AS act_end
  110. FROM "ActivityData" act_d
  111. LEFT JOIN "Activity" act ON act."objectId" = act_d."activity"
  112. LEFT JOIN "ActivityRegister" act_r ON act_r."objectId" = act_d."actRegister" AND act_r."isDeleted" IS NOT TRUE
  113. WHERE act_d."company"='${company}'
  114. AND act_d."user"='${uid}'
  115. AND act_d."status" NOT IN ('end')
  116. AND act_d."type"='${type}'
  117. AND act_d."isDeleted" IS NOT TRUE
  118. ORDER BY act_d."startDate" DESC
  119. LIMIT 20`
  120. let actDataList = await request.customSQL(sql) || []
  121. if (actDataList?.length <= 0 || !actDataList) {
  122. await this.creatActDateFun()
  123. return
  124. } else {
  125. console.log(actDataList)
  126. let actDataList2 = actDataList?.map(item => {
  127. let obj = item
  128. if (item.startDate || item.createdAt) obj.sport_startDate = dateF.formatTime("YYYY.mm.dd HH:MM", item.startDate || item.createdAt)
  129. if (item.booking?.from?.iso) obj.booking.fromDate = dateF.formatTime("YYYY.mm.dd HH:MM", item.booking.from.iso)
  130. /**该运动是否可继续 */
  131. let isAttend = false
  132. let now = new Date()
  133. if (item.act_end) {
  134. let end = new Date(item.act_end)
  135. isAttend = now < end
  136. obj.actEndDate = dateF.formatTime("YYYY.mm.dd HH:MM", item.act_end)
  137. console.log('end', end, isAttend)
  138. }
  139. if (item.booking?.to?.iso) {
  140. let to = new Date(item.booking?.to?.iso)
  141. isAttend = now < to
  142. obj.booking.toDate = dateF.formatTime("YYYY.mm.dd HH:MM", item.booking.to.iso)
  143. console.log('to', to, isAttend)
  144. }
  145. obj.isAttend = isAttend
  146. return obj
  147. })
  148. this.setData({
  149. actDataList: actDataList2,
  150. isShowActDataList: true,
  151. })
  152. console.log(actDataList2)
  153. }
  154. }
  155. }
  156. },
  157. /**关闭未结束运动弹框 */
  158. closeActDataList() {
  159. this.creatActDateFun()
  160. this.setData({
  161. isShowActDataList: false
  162. })
  163. },
  164. /**点击未结束运动 */
  165. async checkActEndDate(e) {
  166. let {
  167. actDataList,
  168. type
  169. } = this.data
  170. console.log(e)
  171. let {
  172. index
  173. } = e.currentTarget.dataset
  174. let act_end_data_id = actDataList[index].objectId
  175. let log_query = new Parse.Query('ActivityRunLog')
  176. log_query.equalTo('company', company)
  177. log_query.equalTo('user', uid)
  178. log_query.equalTo('actData', act_end_data_id)
  179. log_query.equalTo('type', type)
  180. log_query.notEqualTo('isDeleted', true)
  181. log_query.descending('createdAt')
  182. let log = await log_query.first()
  183. let that = this
  184. console.log(actDataList[index])
  185. if (actDataList[index].isAttend || !actDataList[index].title) {
  186. wx.showModal({
  187. title: `${actDataList[index].title||'日常运动'}`,
  188. content: `${actDataList[index].sport_startDate||'未知时间'}开始运动,已运动 ${log?.get('distance')||0} m, ${log?.get('steps')||0} 步,消耗 ${log?.get('burnCalories')||0} 千卡,是否继续进行?`,
  189. success: async (res) => {
  190. if (res.confirm) {
  191. console.log('用户点击确定')
  192. await that.assignmentFun(act_end_data_id)
  193. that.setData({
  194. isShowActDataList: false
  195. })
  196. } else if (res.cancel) {
  197. console.log('用户点击取消')
  198. }
  199. }
  200. })
  201. } else if (!actDataList[index].isAttend) {
  202. wx.showModal({
  203. title: `${actDataList[index].title||'日常运动'}`,
  204. content: `${actDataList[index].sport_startDate||'未知时间'}开始运动,已运动 ${log?.get('distance')||0} m, ${log?.get('steps')||0} 步,消耗 ${log?.get('burnCalories')||0} 千卡。当前报名记录已过期,可查看其他报名或其他活动。`,
  205. showCancel: false,
  206. confirmText: '结束运动',
  207. success: async (res) => {
  208. if (res.confirm) {
  209. await that.setEndActDateFun(act_end_data_id)
  210. actDataList.splice(index, 1)
  211. that.setData({
  212. actDataList
  213. })
  214. wx.showToast({
  215. title: '已结束',
  216. icon: 'none'
  217. })
  218. }
  219. }
  220. })
  221. }
  222. },
  223. /**继续未结束运动 */
  224. async goOnactEndDate() {
  225. let {
  226. checkActDataId
  227. } = this.data
  228. await this.assignmentFun(checkActDataId)
  229. this.setData({
  230. isShowActDataList: false
  231. })
  232. },
  233. /**全部结束 */
  234. async itemId() {
  235. wx.showModal({
  236. content: '确认结束列表内显示的全部运动吗?',
  237. success:async (res)=> {
  238. if (res.confirm) {
  239. wx.showLoading({
  240. title: '...',
  241. })
  242. let {
  243. actDataList
  244. } = this.data
  245. for (let i in actDataList) {
  246. let itemId = actDataList[i].objectId
  247. await this.setEndActDateFun(itemId)
  248. }
  249. this.creatActDateFun()
  250. wx.hideLoading()
  251. this.setData({
  252. isShowActDataList: false
  253. })
  254. }
  255. }
  256. })
  257. },
  258. /**
  259. * 新建运动数据
  260. * @param {*} act_reg 活动报名记录 Parse.Object
  261. */
  262. async creatActDateFun(act_reg) {
  263. let {
  264. type
  265. } = this.data
  266. let ActivityData = Parse.Object.extend('ActivityData')
  267. let actData = new ActivityData()
  268. if (act_reg?.id && act_reg?.get('activity')?.id) {
  269. actData.set('activity', {
  270. __type: 'Pointer',
  271. className: 'Activity',
  272. objectId: act_reg?.get('activity')?.id
  273. })
  274. actData.set('actRegister', {
  275. __type: 'Pointer',
  276. className: 'ActivityRegister',
  277. objectId: act_reg?.id
  278. })
  279. }
  280. actData.set('company', {
  281. __type: 'Pointer',
  282. className: 'Company',
  283. objectId: company
  284. })
  285. actData.set('user', {
  286. __type: 'Pointer',
  287. className: '_User',
  288. objectId: uid
  289. })
  290. actData.set('type', type)
  291. actData.set('startDate', new Date())
  292. console.log('未查询出显示这个', actData)
  293. await this.setData({
  294. actData
  295. })
  296. },
  297. /**
  298. * 运动数据赋值操作
  299. * @param {*} actDataId 运动数据id
  300. */
  301. async assignmentFun(actDataId) {
  302. let {
  303. type
  304. } = this.data
  305. let log_query = new Parse.Query('ActivityRunLog')
  306. log_query.equalTo('company', company)
  307. log_query.equalTo('user', uid)
  308. log_query.equalTo('actData', actDataId)
  309. log_query.equalTo('type', type)
  310. log_query.notEqualTo('isDeleted', true)
  311. log_query.descending('createdAt')
  312. let log = await log_query.first()
  313. let data_query = new Parse.Query('ActivityData')
  314. let actData = await data_query.get(actDataId)
  315. this.setData({
  316. actData
  317. })
  318. this.setData({
  319. stage: 'progress',
  320. status: 'paused',
  321. isRefershLaLo: true,
  322. timer: log?.get('sportDate') || 0,
  323. pace: log?.get('matchSpeed') || 0,
  324. calorie: log?.get('burnCalories') || 0,
  325. journey: log?.get('distance') || 0,
  326. step: log?.get('steps' || 0),
  327. formattedTime: this.formatTime(log?.get('sportDate') || 0),
  328. })
  329. },
  330. /**
  331. * 结束运动
  332. * @param {*} actDataId 运动数据id
  333. */
  334. async setEndActDateFun(actDataId) {
  335. let {
  336. type
  337. } = this.data
  338. let log_query = new Parse.Query('ActivityRunLog')
  339. log_query.equalTo('company', company)
  340. log_query.equalTo('user', uid)
  341. log_query.equalTo('actData', actDataId)
  342. log_query.equalTo('type', type)
  343. log_query.notEqualTo('isDeleted', true)
  344. log_query.descending('createdAt')
  345. let log = await log_query.first()
  346. let data_query = new Parse.Query('ActivityData')
  347. let data = await data_query.get(actDataId)
  348. log?.get('steps') && data.set('steps', log?.get('steps') || 0)
  349. log?.get('distance') && data.set('distance', log?.get('distance') || 0)
  350. log?.get('matchSpeed') && data.set('matchSpeed', log?.get('matchSpeed') || 0)
  351. log?.get('sportDate') && data.set('sportDate', log?.get('sportDate') || 0)
  352. log?.get('burnCalories') && data.set('burnCalories', log?.get('burnCalories') || 0)
  353. data.set('endDate', log?.get('createdAt') || new Date())
  354. data.set('status', 'end')
  355. await data.save()
  356. if (log?.id) {
  357. log.set('stage', 'end')
  358. await log.save()
  359. }
  360. },
  361. /**监听页面退出事件 */
  362. beforeUnload() {
  363. wx.enableAlertBeforeUnload({ //获取不到"确认/取消"按钮事件
  364. message: '未开始运动、暂停运动中以及运动结束请忽略本提示。若当前正在运动,退出本页面将在微信后台记录。关闭小程序、关闭小程序运行权限、长时间未进入小程序、手机退出微信等操作都将暂停记录。',
  365. })
  366. },
  367. /**检查用户授权状况 */
  368. examineAuthorization() {
  369. let that = this
  370. wx.getSetting({
  371. success(res) {
  372. console.log(res)
  373. if (!res.authSetting['scope.userLocation'] || !res.authSetting['scope.userLocationBackground']) {
  374. that.openPermissions()
  375. } else {
  376. that.closePermissions()
  377. }
  378. }
  379. })
  380. },
  381. /**权限弹框-开 */
  382. openPermissions() {
  383. this.setData({
  384. showPermissions: true
  385. })
  386. },
  387. /**权限弹框-关 */
  388. async closePermissions() {
  389. await this.setData({
  390. showPermissions: false
  391. })
  392. let {
  393. type
  394. } = this.data
  395. let tip = '运动'
  396. switch (type) {
  397. case 'run':
  398. tip = '跑步'
  399. break;
  400. case 'walk':
  401. tip = '步行'
  402. break;
  403. default:
  404. break;
  405. }
  406. wx.showToast({
  407. title: `开启${tip}之旅吧~`,
  408. icon: 'none'
  409. })
  410. this.refersh()
  411. },
  412. /**打开微信权限设置页面 */
  413. openWxSetting() {
  414. wx.openSetting({
  415. success(res) {
  416. console.log(res.authSetting)
  417. },
  418. fail(err) {
  419. console.log(err)
  420. }
  421. })
  422. },
  423. async refersh() {
  424. this.startSports()
  425. },
  426. /**刷新初始位置 */
  427. startSports() {
  428. let that = this
  429. wx.getLocation({
  430. type: 'gcj02',
  431. success: async (res) => {
  432. console.log(res)
  433. let {
  434. longitude,
  435. latitude,
  436. } = res
  437. let markers = [{
  438. iconPath: "https://file-cloud.fmode.cn/13WZ0W7u3l/20240724/7ebg0k104325941.png",
  439. width: 20,
  440. height: 20,
  441. longitude: longitude,
  442. latitude: latitude,
  443. id: 0,
  444. }]
  445. await that.setData({
  446. longitude,
  447. latitude,
  448. markers
  449. })
  450. },
  451. fail: (err) => {
  452. console.error(err);
  453. wx.showToast({
  454. title: '获取位置失败',
  455. icon: 'none'
  456. });
  457. }
  458. });
  459. },
  460. /**
  461. * 位置监听开启
  462. */
  463. async setTime() {
  464. await this.setData({
  465. status: 'inSports',
  466. isRefershLaLo: true,
  467. })
  468. let that = this
  469. wx.offLocationChange()
  470. setTimeout(() => {
  471. that.monitorLocationChange()
  472. console.log('执行经纬度获取')
  473. }, 1000);
  474. },
  475. /**开始运动 */
  476. async startInterval() {
  477. await this.setData({
  478. longitude: 0, //经度
  479. latitude: 0, //纬度
  480. markers: [], //地图标记点
  481. journey: 0, //运动的路程-米
  482. step: 0,
  483. calorie: 0, //卡路里-千卡
  484. pace: 0, //配速-min/km
  485. interval: null, //计时器
  486. timer: 0, //已记的时长-秒
  487. formattedTime: '00:00:00', // 用于存储格式化后的时间
  488. status: 'inSports', //运动中
  489. stage: 'start',
  490. })
  491. //===================这里在getActivityData方法设置=====================
  492. // let {
  493. // type,actData
  494. // } = this.data
  495. // if(!actData){
  496. // let ActivityData = Parse.Object.extend('ActivityData')
  497. // actData = new ActivityData()
  498. // actData.set('company', {
  499. // __type: 'Pointer',
  500. // className: 'Company',
  501. // objectId: company
  502. // })
  503. // actData.set('user', {
  504. // __type: 'Pointer',
  505. // className: '_User',
  506. // objectId: uid
  507. // })
  508. // actData.set('startDate', new Date())
  509. // actData.set('type', type)
  510. // }
  511. // this.setData({
  512. // actData
  513. // })
  514. setTimeout(() => {
  515. this.setTime()
  516. }, 1000);
  517. },
  518. /** 暂停运动*/
  519. async pausedInterval() {
  520. wx.offLocationChange()
  521. this.setData({
  522. status: 'paused',
  523. })
  524. let {
  525. actData,
  526. timer,
  527. pace,
  528. calorie,
  529. journey,
  530. step
  531. } = this.data
  532. console.log(actData)
  533. actData.set('status', 'paused')
  534. actData.set('distance', parseFloat(journey))
  535. actData.set('steps', parseInt(step))
  536. actData.set('sportDate', parseInt(timer))
  537. actData.set('matchSpeed', parseFloat(pace))
  538. actData.set('burnCalories', parseFloat(calorie))
  539. await actData.save()
  540. console.log('暂停')
  541. },
  542. /**继续运动 */
  543. goOn() {
  544. this.setTime()
  545. },
  546. /**长按结束-起 */
  547. onStart() {
  548. let endHaloStartDate = new Date()
  549. this.setData({
  550. endHaloStartDate
  551. })
  552. let {
  553. endHaloInterval
  554. } = this.data
  555. endHaloInterval = setInterval(() => {
  556. let now = new Date()
  557. let elapsedTime = now - endHaloStartDate
  558. let percentage = Math.min((elapsedTime / 4000) * 100, 100);
  559. this.setData({
  560. percentage: `conic-gradient(from 0deg, #015EEA ${percentage}%, white 0%)`,
  561. });
  562. }, 40);
  563. this.setData({
  564. endHaloInterval
  565. })
  566. },
  567. /**长按结束-终 */
  568. async onEnd() {
  569. let {
  570. endHaloStartDate,
  571. endHaloInterval,
  572. actData,
  573. } = this.data
  574. let endHaloEndDate = new Date()
  575. let a = endHaloEndDate - endHaloStartDate
  576. if (a >= 4000) { //长按4秒
  577. clearInterval(endHaloInterval)
  578. wx.offLocationChange()
  579. wx.stopLocationUpdate({
  580. success: (res) => {
  581. console.log('后台定位已停止');
  582. },
  583. fail: (res) => {
  584. console.error('停止后台定位失败', res);
  585. }
  586. });
  587. await this.setData({
  588. status: 'noStart',
  589. endHaloStartDate: null,
  590. endHaloStartDate: null,
  591. percentage: '',
  592. endHaloInterval: null,
  593. stage: 'end'
  594. })
  595. await this.setActivityRunLog()
  596. let {
  597. actData,
  598. timer,
  599. pace,
  600. calorie,
  601. journey,
  602. step
  603. } = this.data
  604. console.log(actData)
  605. actData.set('status', 'end')
  606. actData.set('endDate', new Date())
  607. actData.set('distance', parseFloat(journey))
  608. actData.set('sportDate', parseInt(timer))
  609. actData.set('steps', parseInt(step))
  610. actData.set('matchSpeed', parseFloat(pace))
  611. actData.set('burnCalories', parseFloat(calorie))
  612. await actData.save()
  613. wx.showToast({
  614. title: '已结束本次运动',
  615. icon: 'none'
  616. })
  617. } else {
  618. clearInterval(endHaloInterval)
  619. this.setData({
  620. endHaloStartDate: null,
  621. endHaloStartDate: null,
  622. percentage: '',
  623. endHaloInterval: null,
  624. })
  625. }
  626. },
  627. /**监听位置变化 */
  628. monitorLocationChange() {
  629. let that = this
  630. wx.startLocationUpdateBackground({
  631. success: (res) => {
  632. wx.onLocationChange(async (change_res) => {
  633. console.log(change_res.longitude, change_res.latitude)
  634. let {
  635. longitude, //经度
  636. latitude, //纬度
  637. journey, //路程-m
  638. calorie, //卡路里-千卡
  639. pace, //配速-min/km
  640. timer, //计时
  641. isRefershLaLo,
  642. } = that.data
  643. timer = timer + 1 || 1
  644. let formattedTime = that.formatTime(parseInt(timer))
  645. if (isRefershLaLo) {
  646. longitude = change_res.longitude
  647. latitude = change_res.latitude
  648. let {
  649. actData
  650. } = that.data
  651. console.log(actData)
  652. actData.set('status', 'inSports')
  653. await actData.save()
  654. that.setData({
  655. isRefershLaLo: false,
  656. actData
  657. })
  658. }
  659. let distance = that.haversine(latitude, longitude, change_res.latitude, change_res.longitude)?.toFixed(2)
  660. journey = (parseFloat(journey || 0) + parseFloat(distance || 0))?.toFixed(2)
  661. calorie = that.getCalorie(50, journey) //体重50kg
  662. pace = distance ? (distance * 6) / 100 : 0
  663. let step = parseInt(parseInt(journey) / 0.6)
  664. await that.setData({
  665. formattedTime,
  666. step,
  667. timer,
  668. journey,
  669. longitude: change_res.longitude,
  670. latitude: change_res.latitude,
  671. calorie,
  672. pace: parseFloat(pace)?.toFixed(2),
  673. })
  674. let time = timer % 5
  675. if (time === 0) {
  676. await that.setActivityRunLog()
  677. that.setData({
  678. stage: 'progress'
  679. })
  680. // console.log('执行保存数据')
  681. }
  682. });
  683. },
  684. fail: (res) => {
  685. this.openPermissions()
  686. }
  687. });
  688. },
  689. /**微信步数获取-弃用-使用0.6米/步 */
  690. async getWeRun() {
  691. wx.login({
  692. success: (res) => {
  693. console.log(res)
  694. wx.request({
  695. url: `https://api.weixin.qq.com/sns/jscode2session?appid=wxe6ecc0193c09696c&secret=0ee1172c8729c547d33f0ab45715d7ec&js_code=${res.code}&grant_type=authorization_code`,
  696. method: 'GET',
  697. success(res) {
  698. console.log(res)
  699. let session_key = res.data.session_key
  700. wx.getWeRunData({
  701. success: async (res) => {
  702. console.log(res)
  703. console.log(res.encryptedData)
  704. console.log(res.iv)
  705. wx.request({
  706. url: 'http://localhost:7337/api/o2o/wxrun',
  707. data: {
  708. app_id: 'wxe6ecc0193c09696c',
  709. session_key: session_key,
  710. encrypted_data: res.encryptedData,
  711. iv: res.iv
  712. },
  713. method: 'POST',
  714. success(res) {
  715. console.log(res)
  716. },
  717. })
  718. },
  719. fail: (err) => {
  720. console.log(err)
  721. }
  722. })
  723. },
  724. })
  725. },
  726. })
  727. },
  728. toRadians(degrees) {
  729. return degrees * (Math.PI / 180);
  730. },
  731. /**
  732. * 两点距离-米
  733. * @param {*} lat1 纬1
  734. * @param {*} lon1 经1
  735. * @param {*} lat2 纬2
  736. * @param {*} lon2 经2
  737. */
  738. haversine(lat1, lon1, lat2, lon2) {
  739. const R = 6371000;
  740. const φ1 = this.toRadians(parseFloat(lat1));
  741. const φ2 = this.toRadians(parseFloat(lat2));
  742. const Δφ = this.toRadians(parseFloat(lat2) - parseFloat(lat1));
  743. const Δλ = this.toRadians(parseFloat(lon2) - parseFloat(lon1));
  744. const a = Math.sin(Δφ / 2) * Math.sin(Δφ / 2) +
  745. Math.cos(φ1) * Math.cos(φ2) *
  746. Math.sin(Δλ / 2) * Math.sin(Δλ / 2);
  747. const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
  748. const distance = R * c;
  749. return distance;
  750. },
  751. /**
  752. * 计算卡路里-千卡
  753. * @param {*} weight 体重kg
  754. * @param {*} distance 距离m
  755. */
  756. getCalorie(weight, distance) {
  757. const caloriesBurned = weight * distance * 0.75;
  758. return (caloriesBurned / 1000).toFixed(2);
  759. },
  760. /**记录运动过程-每5秒保存一次 */
  761. async setActivityRunLog() {
  762. let {
  763. actData,
  764. stage,
  765. longitude, //经度
  766. latitude, //纬度
  767. journey, //运动的路程-米
  768. step,
  769. calorie, //卡路里-千卡
  770. pace, //配速-min/km
  771. timer, //已记的时长-秒
  772. type, //步行/跑步
  773. } = this.data
  774. let ActivityRunLog = Parse.Object.extend('ActivityRunLog')
  775. let log = new ActivityRunLog()
  776. log.set('company', {
  777. __type: 'Pointer',
  778. className: 'Company',
  779. objectId: company
  780. })
  781. log.set('user', {
  782. __type: 'Pointer',
  783. className: '_User',
  784. objectId: uid
  785. })
  786. log.set('actData', {
  787. __type: 'Pointer',
  788. className: 'ActivityData',
  789. objectId: actData?.id
  790. })
  791. log.set('stage', stage)
  792. log.set('type', type)
  793. log.set('sportDate', parseInt(timer) || 0)
  794. log.set('burnCalories', parseFloat(calorie || '0'))
  795. log.set('matchSpeed', parseFloat(pace || '0'))
  796. log.set('distance', parseFloat(journey || '0'))
  797. log.set('steps', step)
  798. let location = new Parse.GeoPoint({
  799. latitude: latitude,
  800. longitude: longitude
  801. });
  802. log.set('location', location)
  803. await log.save()
  804. },
  805. /**时间格式显示 */
  806. formatTime: function (seconds) {
  807. const hours = Math.floor(seconds / 3600);
  808. const minutes = Math.floor((seconds % 3600) / 60);
  809. const secs = seconds % 60;
  810. // 格式化为两位数
  811. const formattedHours = String(hours).padStart(2, '0');
  812. const formattedMinutes = String(minutes).padStart(2, '0');
  813. const formattedSeconds = String(secs).padStart(2, '0');
  814. return `${formattedHours}:${formattedMinutes}:${formattedSeconds}`;
  815. },
  816. /**
  817. * 生命周期函数--监听页面初次渲染完成
  818. */
  819. onReady: function () {
  820. },
  821. /**
  822. * 生命周期函数--监听页面显示
  823. */
  824. onShow: function () {
  825. this.examineAuthorization()
  826. },
  827. /**
  828. * 生命周期函数--监听页面隐藏
  829. */
  830. onHide: function () {},
  831. /**
  832. * 生命周期函数--监听页面卸载
  833. */
  834. onUnload: function () {},
  835. /**
  836. * 页面相关事件处理函数--监听用户下拉动作
  837. */
  838. onPullDownRefresh: function () {
  839. },
  840. /**
  841. * 页面上拉触底事件的处理函数
  842. */
  843. onReachBottom: function () {
  844. },
  845. /**
  846. * 用户点击右上角分享
  847. */
  848. onShareAppMessage: function () {
  849. },
  850. })