getSportData.js 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330
  1. const Parse = getApp().Parse;
  2. const company = getApp().globalData.company;
  3. const uid = Parse.User.current()?.id
  4. let request = require('../../utils/request')
  5. const dateF = require('../../utils/date')
  6. /**
  7. * 计算运动累加状况-getwalk使用
  8. * @param {*} column 累加字段 (未知则'distance')
  9. * @param {*} type 运动类型 walk/run(未知则不限制)
  10. * @param {*} fromTo 时间范围 {from,to}(未知则今日)
  11. */
  12. async function getwalk(column, type, fromTo) {
  13. let todate = new Date(new Date().setHours(0, 0, 0, 0))
  14. let tomorrow = new Date(new Date(todate).setDate(todate.getDate() + 1))
  15. if (fromTo?.from && fromTo?.to) {
  16. todate = fromTo.from
  17. tomorrow = fromTo.to
  18. }
  19. let todaySql = dateF.formatTime(`YYYY-mm-dd HH:MM:SS`, todate)
  20. let yestodaySql = dateF.formatTime(`YYYY-mm-dd HH:MM:SS`, tomorrow)
  21. let sql = `SELECT SUM(COALESCE(t1."num", 0))- SUM(COALESCE(t1."ago_num",0)) AS "sum"
  22. FROM(SELECT MAX(al."${column||'distance'}") AS "num" ,al."actData",(
  23. SELECT MAX(al2."${column||'distance'}")
  24. FROM "ActivityRunLog" al2
  25. WHERE al2."actData"=al."actData"
  26. AND al2."isDeleted" IS NOT TRUE
  27. ${type?`AND al2."type"='${type}'`:''}
  28. AND al2."createdAt" < '${todaySql}'
  29. AND al2."isDeleted" IS NOT TRUE
  30. )AS "ago_num"
  31. FROM "ActivityRunLog" al
  32. LEFT JOIN "ActivityData" ad ON ad."objectId"=al."actData"
  33. WHERE al."isDeleted" IS NOT TRUE
  34. AND al."createdAt" > '${todaySql}'
  35. AND al."createdAt" < '${yestodaySql}'
  36. AND al."company"='${company}'
  37. AND al."user"='${uid}'
  38. ${type?`AND al."type"='${type}'`:''}
  39. AND al."isDeleted" IS NOT TRUE
  40. AND ad."isDeleted" IS NOT TRUE
  41. ${type?`AND ad."type"='${type}'`:''}
  42. GROUP BY al."actData")t1`
  43. // console.log(sql)
  44. let data = await request.customSQL(sql)
  45. // console.log(data)
  46. return data[0].sum < 0 ? 0 : data[0].sum || 0
  47. }
  48. /**查看活动运动数据(当前活动对应运动是否结束) */
  49. async function getActSport(actId) {
  50. let actQuery = new Parse.Query('Activity')
  51. let act = await actQuery.get(actId)
  52. if (act?.get('endDate')) {
  53. }
  54. }
  55. /**对于活动超时未结束的运动,设置stage为end */
  56. async function setEndSport(actId) {
  57. let regQuery = new Parse.Query('ActivityRegister')
  58. regQuery.equalTo('company', company)
  59. regQuery.equalTo('user', uid)
  60. regQuery.notEqualTo('isDeleted', true)
  61. regQuery.equalTo('activity', actId)
  62. regQuery.select('booking')
  63. let reg = await regQuery.find()
  64. let overtimeReg = reg?.filter(item => {
  65. let now = new Date()
  66. let endTime = item?.get('booking')?.to
  67. if (!endTime) return true
  68. return now >= endTime
  69. })?.map(item => item?.id)
  70. console.log(overtimeReg)
  71. if (overtimeReg?.length <= 0) return
  72. let actQuery = new Parse.Query('ActivityData')
  73. actQuery.equalTo('company', company)
  74. actQuery.equalTo('user', uid)
  75. actQuery.notEqualTo('isDeleted', true)
  76. actQuery.containedIn('activity', overtimeReg)
  77. actQuery.select('objectId')
  78. let actData = await actQuery.find()
  79. for (let i in actData) {
  80. let act = actData[i]
  81. //获取最后一条运动过程记录
  82. let logQuery = new Parse.Query('ActivityRunLog')
  83. logQuery.equalTo('company', company)
  84. logQuery.equalTo('user', uid)
  85. logQuery.notEqualTo('isDeleted', true)
  86. logQuery.equalTo('actData', act?.id)
  87. logQuery.descending('createdAt')
  88. let endLog = await logQuery.first()
  89. endLog.set('stage', 'end')
  90. await endLog.save()
  91. act.set('steps', endLog?.get('steps') || 0)
  92. act.set('distance', endLog?.get('distance') || 0)
  93. act.set('matchSpeed', endLog?.get('matchSpeed') || 0)
  94. act.set('sportDate', endLog?.get('sportDate') || 0)
  95. act.set('burnCalories', endLog?.get('burnCalories') || 0)
  96. act.set('status', 'end')
  97. act.set('endDate', new Date())
  98. await act.save()
  99. }
  100. }
  101. /**
  102. * 获取排行榜
  103. * @param {*} type 运动类型 默认不限制
  104. * @param {*} fromto 时间范围 默认为空 today/toweek/tomonth/空
  105. * @param {*} limit limit默认20
  106. * @param {*} skip skip默认0
  107. * @param {*} order 顺序 默认 DESC
  108. * @param {*} limitSql 其他限制语句 AND ad."xxx" = 'xxx'
  109. */
  110. async function getRanking(type, fromto, limit, skip, order, limitSql) {
  111. let fromtoSql = ``
  112. switch (fromto) {
  113. case 'today':
  114. let todate = new Date(new Date().setHours(0, 0, 0, 0))
  115. let tomorrow = new Date(new Date(todate).setDate(todate.getDate() + 1))
  116. let todaySql = dateF.formatTime(`YYYY-mm-dd HH:MM:SS`, todate)
  117. let yestodaySql = dateF.formatTime(`YYYY-mm-dd HH:MM:SS`, tomorrow)
  118. fromtoSql = `AND ad."endDate" >= '${todaySql}' AND ad."endDate" < '${yestodaySql}'`
  119. break;
  120. case 'toweek':
  121. const today = new Date();
  122. const dayOfWeek = today.getDay();
  123. const thisSun = new Date(today);
  124. thisSun.setDate(today.getDate() + (0 - dayOfWeek));
  125. thisSun.setHours(0, 0, 0, 0);
  126. const nextSun = new Date(thisSun);
  127. nextSun.setDate(thisSun.getDate() + 7);
  128. let thisSunSql = dateF.formatTime(`YYYY-mm-dd HH:MM:SS`, thisSun)
  129. let nextSunSql = dateF.formatTime(`YYYY-mm-dd HH:MM:SS`, nextSun)
  130. fromtoSql = `AND ad."endDate" >= '${thisSunSql}' AND ad."endDate" < '${nextSunSql}'`
  131. break;
  132. case 'tomonth':
  133. const now = new Date();
  134. const toMon = new Date(now.getFullYear(), now.getMonth(), 1, 0, 0, 0);
  135. const nextMon = new Date(now.getFullYear(), now.getMonth() + 1, 1, 0, 0, 0);
  136. let toMonSql = dateF.formatTime(`YYYY-mm-dd HH:MM:SS`, toMon)
  137. let nextMonSql = dateF.formatTime(`YYYY-mm-dd HH:MM:SS`, nextMon)
  138. fromtoSql = `AND ad."endDate" >= '${toMonSql}' AND ad."endDate" < '${nextMonSql}'`
  139. break;
  140. default:
  141. break;
  142. }
  143. let sql = `SELECT SUM(ad."steps") AS "totalSteps",SUM(ad."distance") AS "distance",SUM(ad."burnCalories") AS "burnCalories",SUM(ad."sportDate") AS "sportDate",ad."user",u."nickname",u."avatar"
  144. FROM "ActivityData" ad
  145. LEFT JOIN "_User" u ON u."objectId"=ad."user"
  146. WHERE ad."company"='${company}'
  147. AND ad."isDeleted" IS NOT TRUE
  148. AND ad."status" = 'end'
  149. ${limitSql||''}
  150. ${type?`AND ad."type" = '${type}'`:''}
  151. ${fromtoSql}
  152. GROUP BY ad."user",u."nickname",u."avatar"
  153. ORDER BY SUM(ad."steps") ${order||'DESC'}
  154. LIMIT ${limit||20} OFFSET ${skip||0}`
  155. // console.log(sql)
  156. let data = await request.customSQL(sql)
  157. // console.log(data)
  158. return data
  159. }
  160. /**
  161. * 获取用户排名
  162. * @param {*} uid 用户id 默认当前用户
  163. * @param {*} type 运动类型 默认不限制
  164. * @param {*} fromto 时间范围 today/toweek/tomonth/空 默认不限制
  165. */
  166. async function getUserRank(userid, type, fromto) {
  167. let fromtoSql = ``
  168. switch (fromto) {
  169. case 'today':
  170. let todate = new Date(new Date().setHours(0, 0, 0, 0))
  171. let tomorrow = new Date(new Date(todate).setDate(todate.getDate() + 1))
  172. let todaySql = dateF.formatTime(`YYYY-mm-dd HH:MM:SS`, todate)
  173. let yestodaySql = dateF.formatTime(`YYYY-mm-dd HH:MM:SS`, tomorrow)
  174. fromtoSql = `AND ad."endDate" >= '${todaySql}' AND ad."endDate" < '${yestodaySql}'`
  175. break;
  176. case 'toweek':
  177. const today = new Date();
  178. const dayOfWeek = today.getDay();
  179. const thisSun = new Date(today);
  180. thisSun.setDate(today.getDate() + (0 - dayOfWeek));
  181. thisSun.setHours(0, 0, 0, 0);
  182. const nextSun = new Date(thisSun);
  183. nextSun.setDate(thisSun.getDate() + 7);
  184. let thisSunSql = dateF.formatTime(`YYYY-mm-dd HH:MM:SS`, thisSun)
  185. let nextSunSql = dateF.formatTime(`YYYY-mm-dd HH:MM:SS`, nextSun)
  186. fromtoSql = `AND ad."endDate" >= '${thisSunSql}' AND ad."endDate" < '${nextSunSql}'`
  187. break;
  188. case 'tomonth':
  189. const now = new Date();
  190. const toMon = new Date(now.getFullYear(), now.getMonth(), 1, 0, 0, 0);
  191. const nextMon = new Date(now.getFullYear(), now.getMonth() + 1, 1, 0, 0, 0);
  192. let toMonSql = dateF.formatTime(`YYYY-mm-dd HH:MM:SS`, toMon)
  193. let nextMonSql = dateF.formatTime(`YYYY-mm-dd HH:MM:SS`, nextMon)
  194. fromtoSql = `AND ad."endDate" >= '${toMonSql}' AND ad."endDate" < '${nextMonSql}'`
  195. break;
  196. default:
  197. break;
  198. }
  199. let sql = `WITH RankedUsers AS (
  200. SELECT ad."user",
  201. RANK() OVER (ORDER BY SUM(ad."steps") DESC) AS "rank"
  202. FROM "ActivityData" ad
  203. LEFT JOIN "_User" u ON u."objectId" = ad."user"
  204. WHERE ad."company"='${company}'
  205. AND ad."isDeleted" IS NOT TRUE
  206. AND ad."status" = 'end'
  207. ${type?`AND ad."type" = '${type}'`:''}
  208. ${fromtoSql}
  209. GROUP BY ad."user"
  210. LIMIT 200
  211. )
  212. SELECT *
  213. FROM RankedUsers
  214. WHERE "user" = '${userid||uid}';`
  215. // console.log(sql)
  216. let data = await request.customSQL(sql)
  217. // console.log(data)
  218. return data
  219. }
  220. /**
  221. * 获取至今日连续 签到/运动 天数
  222. * @param {*} uid uid默认当前用户
  223. * @param {*} table 查询那一张表,签到EventLog/运动ActivityData,默认EventLog
  224. */
  225. async function getContinuousCount(user_id, table) {
  226. let todate = new Date(new Date().setHours(0, 0, 0, 0))
  227. let yestoday = new Date(new Date(todate).setDate(todate.getDate() - 1))
  228. let yesSql = dateF.formatTime(`YYYY-mm-dd HH:MM:SS`, yestoday)
  229. let sql = `SELECT * FROM (
  230. SELECT MAX(t3."created_date") AS "end_date",COUNT(t3."result") AS "c_count",t3."result"
  231. FROM(
  232. SELECT *,(t2."created_date"-(t2."row" * INTERVAL '1 day')) AS "result"
  233. FROM(
  234. SELECT DISTINCT (t1."created_date"),t1."user",
  235. ROW_NUMBER() OVER (PARTITION BY t1."user" ORDER BY DATE(t1."created_date")) AS "row"
  236. FROM (
  237. SELECT DISTINCT(DATE(el."createdAt")) AS "created_date",el."user"
  238. FROM "${table||'EventLog'}" el
  239. WHERE el."isDeleted" IS NOT TRUE
  240. AND el."company"='${company||''}'
  241. AND el."user"='${user_id||uid}'
  242. )t1
  243. )t2
  244. )t3
  245. GROUP BY t3."result"
  246. )t4
  247. WHERE t4."end_date" >='${yesSql}'
  248. ORDER BY t4."end_date" DESC
  249. LIMIT 1`
  250. // console.log(sql)
  251. let data = await request.customSQL(sql)
  252. // console.log(data)
  253. return data[0]?.c_count
  254. }
  255. /**
  256. * 获取至今日累计 签到/运动 天数
  257. * @param {*} uid uid默认当前用户
  258. * @param {*} table 查询那一张表,签到EventLog/运动ActivityData,默认EventLog
  259. */
  260. async function getChickCount(user_id, table) {
  261. let sql = `SELECT COUNT(*)
  262. FROM (
  263. SELECT DISTINCT(DATE(el."createdAt")) AS "created_date",el."user"
  264. FROM "${table||'EventLog'}" el
  265. WHERE el."isDeleted" IS NOT TRUE
  266. AND el."company"='${company||''}'
  267. AND el."user"='${user_id||uid}'
  268. )t1`
  269. // console.log(sql)
  270. let data = await request.customSQL(sql)
  271. // console.log(data)
  272. return data[0]?.count
  273. }
  274. /**获取当前位置信息 */
  275. async function getLocation() {
  276. let address=''
  277. wx.getLocation({
  278. type: 'wgs84',
  279. success: (res) => {
  280. const {
  281. latitude,
  282. longitude
  283. } = res;
  284. wx.request({
  285. url: 'https://api.map.baidu.com/reverse_geocoding/v3/?ak=sHZTomd7grslfP7sPKB8tRgT49FK9TEu&output=json&coordtype=gcj02&location=' + latitude + ',' + longitude,
  286. data: {},
  287. header: {
  288. 'Content-Type': 'application/json'
  289. },
  290. success: (ops) => {
  291. address = ops.data.result.formatted_address;
  292. console.log(address);
  293. },
  294. fail: function (resq) {
  295. wx.showModal({
  296. title: '信息提示',
  297. content: '请求失败',
  298. showCancel: false,
  299. confirmColor: '#f37938'
  300. });
  301. },
  302. })
  303. },
  304. fail: (err) => {
  305. console.error(err);
  306. wx.showToast({
  307. title: '获取位置失败',
  308. icon: 'none'
  309. });
  310. }
  311. });
  312. }
  313. module.exports = {
  314. getwalk,
  315. setEndSport,
  316. getRanking,
  317. getUserRank,
  318. getContinuousCount,
  319. getChickCount,
  320. getLocation
  321. };