index.js 24 KB

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