Metric.tsx 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388
  1. import { View, Text, ScrollView } from "@tarojs/components";
  2. import './Metric.scss'
  3. import { setAuth } from "../hooks/werun";
  4. import { usePullDownRefresh, useReady } from "@tarojs/taro";
  5. import { useSelector } from "react-redux";
  6. import { useEffect, useRef, useState } from "react";
  7. import Taro from "@tarojs/taro";
  8. import { metricCards, uploadMetric, uploadSteps } from "@/services/trackSomething";
  9. import { TimeFormatter } from "@/utils/time_format";
  10. import MetricItem from "./MetricItem";
  11. import { get } from "http";
  12. import Modal from "@/components/Modal";
  13. import PickerViews from "@/components/PickerViews";
  14. import LimitPickers from "@/components/LimitPickers";
  15. import SlidngScale from "@/components/SlidngScale";
  16. import NoData from "@/components/NoData";
  17. import { alphaToHex } from "@/utils/tools";
  18. export default function Component(props: any) {
  19. const user = useSelector((state: any) => state.user);
  20. const [list, setList] = useState([])
  21. const [isModalOpen, setIsModalOpen] = useState(false);
  22. const [isTimePickerOpen, setIsTimePickerOpen] = useState(false);
  23. const [pickerValue, setPickerValue] = useState([]);
  24. const [pickerItems, setPickerItems] = useState([]);
  25. const [isPoint, setIsPoint] = useState(false)
  26. const [metricItem, setMetricItem] = useState({})
  27. const [strTime, setStrTime] = useState('')
  28. const [time, setTime] = useState(0)
  29. const [showErrorPage, setErrorPage] = useState(false)
  30. const [setupTime, setSetupTime] = useState(0)
  31. const [triggered, setTriggered] = useState(true)
  32. const limitPickerRef = useRef<any>(null);
  33. //未登录<->已登录 状态切换时,执行一次授权检查
  34. useEffect(() => {
  35. getCards();
  36. }, [user.isLogin])
  37. const openModal = () => {
  38. setSetupTime(new Date().getTime())
  39. setIsModalOpen(true);
  40. };
  41. const closeModal = () => {
  42. setIsModalOpen(false);
  43. };
  44. global.refreshMetric = () => {
  45. getCards()
  46. }
  47. function getCards() {
  48. setTriggered(true)
  49. console.log('get Cards')
  50. metricCards().then(res => {
  51. setErrorPage(false)
  52. setList((res as any).cards)
  53. setTriggered(false)
  54. }).catch(e => {
  55. if (list.length == 0) {
  56. setErrorPage(true)
  57. }
  58. setTriggered(false)
  59. // console.log('请求超时')
  60. })
  61. }
  62. //ts 把数组items: [{code: "_walk", value: 2180},{code: "_walk", value: 4444}]中的value取出来,/分割,组成字符串,如2180/4444
  63. function getValues(items) {
  64. var values = ''
  65. items.map((item, index) => {
  66. if (index == 0) {
  67. values = item.value
  68. }
  69. else {
  70. values = values + '/' + item.value
  71. }
  72. })
  73. return values
  74. }
  75. function goDetail(item) {
  76. if (user.isLogin) {
  77. if (!item.latest_record) {
  78. return
  79. }
  80. Taro.navigateTo({
  81. url: '/pages/RecordsHistory?type=metric&refreshList=getCards&code=' + item.code
  82. })
  83. }
  84. else {
  85. Taro.navigateTo({
  86. url: '/pages/ChooseAuth'
  87. })
  88. }
  89. }
  90. function record(item: any) {
  91. if (user.isLogin) {
  92. var now = new Date();
  93. var t = (now.getHours() < 10 ? '0' + now.getHours() : now.getHours()) + ":" + (now.getMinutes() < 10 ? '0' + now.getMinutes() : now.getMinutes());
  94. setStrTime(t)
  95. setTime(now.getTime())
  96. setMetricItem(item)
  97. openModal()
  98. console.log(item)
  99. }
  100. else {
  101. Taro.navigateTo({
  102. url: '/pages/ChooseAuth'
  103. })
  104. }
  105. }
  106. function pointPicker(item: any) {
  107. var min = item.min
  108. var max = item.max
  109. var step = item.step
  110. var value = item.default_value
  111. console.log(value)
  112. var items: number[] = []
  113. var items2: number[] = []
  114. var value0Index = 0
  115. var value1Index = 0
  116. for (var i = min; i <= max; i++) {
  117. if (i == Math.floor(value)) {
  118. value0Index = i - min
  119. }
  120. items.push(i)
  121. // items2.push(i)
  122. }
  123. for (var i = 0; i <= 9; i++) {
  124. items2.push(i)
  125. }
  126. value1Index = Math.round(10 * (value - Math.floor(value)));
  127. console.log(value1Index)
  128. setPickerValue([value0Index, value1Index] as any)
  129. setPickerItems([items, items2] as any)
  130. setIsPoint(true)
  131. openModal()
  132. }
  133. function singlePicker(item: any) {
  134. var min = item.min
  135. var max = item.max
  136. var step = 1//item.step
  137. var value = item.default_value
  138. var items: number[] = []
  139. for (var i = min; i <= max; i += step) {
  140. if (i == value) {
  141. setPickerValue([i - min] as any)
  142. }
  143. items.push(i)
  144. }
  145. setPickerItems([items] as any)
  146. setIsPoint(false)
  147. openModal()
  148. }
  149. function pickerChanged(e) {
  150. closeModal();
  151. var params = {}
  152. var date = new Date(time)
  153. var strDate = (date.getFullYear() + '') + (date.getMonth() + 1 < 10 ? '0' + (date.getMonth() + 1) : (date.getMonth() + 1)) + (date.getDate() < 10 ? '0' + date.getDate() : date.getDate());
  154. if ((metricItem as any).schemas[0].type == 'DECIMAL') {
  155. var array = pickerItems;
  156. var value = array[0][e[0]] + '.' + array[1][e[1]]
  157. console.log(value)
  158. params = {
  159. code: (metricItem as any).code,
  160. timestamp: time,
  161. date: strDate,
  162. items: [{ code: (metricItem as any).schemas[0].code, value: value }]
  163. }
  164. }
  165. else if ((metricItem as any).schemas.length > 1) {
  166. }
  167. else {
  168. var array = pickerItems;
  169. var value = array[0][e[0]] + ''
  170. console.log(value)
  171. params = {
  172. code: (metricItem as any).code,
  173. timestamp: time,
  174. date: strDate,
  175. items: [{ code: (metricItem as any).schemas[0].code, value: value }]
  176. }
  177. }
  178. uploadMetric(params).then(res => {
  179. list.map((item, index) => {
  180. if ((item as any).code == (res as any).code) {
  181. (item as any).latest_record = (res as any).latest_record
  182. }
  183. })
  184. debugger
  185. setList(list)
  186. // getCards();
  187. })
  188. }
  189. function showTimePicker() {
  190. setIsTimePickerOpen(true)
  191. }
  192. function chooseTime(e) {
  193. setTime(e);
  194. setStrTime(TimeFormatter.formatTimestamp(e))
  195. setIsTimePickerOpen(false)
  196. }
  197. function cancelModal() {
  198. (metricItem as any).schemas.map((item, index) => {
  199. item.tempValue = ''
  200. })
  201. closeModal()
  202. }
  203. function confirmModal() {
  204. closeModal()
  205. var date = new Date(time)
  206. var strDate = (date.getFullYear() + '') + (date.getMonth() + 1 < 10 ? '0' + (date.getMonth() + 1) : (date.getMonth() + 1)) + (date.getDate() < 10 ? '0' + date.getDate() : date.getDate());
  207. var array: any[] = [];
  208. (metricItem as any).schemas.map((item, index) => {
  209. array.push({
  210. code: item.code,
  211. value: item.tempValue && item.tempValue.length > 0 ? item.tempValue : item.default_value
  212. })
  213. })
  214. var params = {
  215. code: (metricItem as any).code,
  216. timestamp: time,
  217. date: strDate,
  218. items: array,
  219. extra: {
  220. set_time: setupTime,
  221. confirm_time: new Date().getTime()
  222. }
  223. }
  224. uploadMetric(params).then(res => {
  225. // getCards();
  226. (metricItem as any).schemas.map((item, index) => {
  227. item.tempValue = ''
  228. })
  229. list.map((item, index) => {
  230. if ((item as any).code == (res as any).code) {
  231. (item as any).latest_record = (res as any).latest_record
  232. }
  233. })
  234. setList(JSON.parse(JSON.stringify(list)))
  235. })
  236. }
  237. const limit = new Date().getTime() - 180 * 3600 * 1000 * 24;
  238. function detail() {
  239. return <View className="metric_container">
  240. {
  241. list.map((item: any, index: number) => {
  242. var unit = ''
  243. var value = '无记录'
  244. var desc = '记录解锁趋势'
  245. if (item.latest_record) {
  246. unit = item.schemas[0].default_unit
  247. value = getValues(item.latest_record.items)
  248. desc = TimeFormatter.formatTimestamp(item.latest_record.timestamp)
  249. }
  250. return <MetricItem title={item.name}
  251. value={value}
  252. unit={unit}
  253. desc={desc}
  254. btnText='记录'
  255. isDisabled={false}
  256. themeColor={item.theme_color}
  257. onClickDetail={() => { goDetail(item) }}
  258. onClick={() => { record(item) }}
  259. />
  260. })
  261. }
  262. <View className="space_width" />
  263. </View>
  264. }
  265. // return showErrorPage ? <NoData refresh={() => { getCards() }} /> : detail()
  266. return <View style={{ display: 'flex', flex: 1, height: '100%' }}>
  267. <ScrollView style={{ backgroundColor: '#000' }} scrollY refresherEnabled={true}
  268. refresherThreshold={100} refresherBackground="#000"
  269. refresherDefaultStyle="white" onRefresherRefresh={getCards}
  270. refresherTriggered={triggered}>
  271. {showErrorPage ? <NoData refresh={() => { getCards() }} /> : detail()}
  272. <View style={{ height: 100 }} />
  273. </ScrollView>
  274. {
  275. isModalOpen && <Modal dismiss={closeModal} title={(metricItem as any).name}
  276. themeColor={(metricItem as any).theme_color}
  277. confirm={confirmModal}>
  278. <View style={{
  279. display: 'flex', flexDirection: 'column',
  280. width: '100%', color: '#000'
  281. }}>
  282. <Text className='modal_title' style={{ color: (metricItem as any).theme_color }}>{props.title ? props.title : '测试标题 '}</Text>
  283. <View style={{ position: 'relative' }}>
  284. {
  285. (metricItem as any).schemas.map((item, index) => {
  286. return <View key={index}>
  287. {
  288. (metricItem as any).schemas.length > 1 && <Text style={{
  289. textAlign: 'center', width: '100%', display: 'flex',
  290. justifyContent: 'center', color: (metricItem as any).theme_color
  291. }}>{item.name}</Text>
  292. }
  293. <SlidngScale step={item.step} min={item.min} max={item.max} default_value={item.default_value}
  294. unit={item.default_unit}
  295. themeColor={(metricItem as any).theme_color}
  296. changed={(e) => { item.tempValue = e }} />
  297. </View>
  298. })
  299. }
  300. </View>
  301. <View className="change_time_bg ">
  302. <View className="gray1 time_bg" onClick={showTimePicker}>
  303. <Text className="time" >{strTime}</Text>
  304. </View>
  305. </View>
  306. <View className='modal_operate'>
  307. <View className='modal_btn' style={{ backgroundColor: (metricItem as any).theme_color + alphaToHex(0.4) }} onClick={cancelModal}>
  308. <Text className='modal_cancel_text' style={{ color: (metricItem as any).theme_color }}>取消</Text>
  309. </View>
  310. <View className='btn_space' />
  311. <View className='modal_btn' style={{ backgroundColor: (metricItem as any).theme_color }} onClick={confirmModal}>
  312. <Text className='modal_confirm_text' style={{ color: '#000' }}>确定</Text>
  313. </View>
  314. </View>
  315. {/* <View style={{ marginBottom: 20, marginTop: 20, display: 'flex', flexDirection: 'row', width: '100%' }}>
  316. <Text style={{ flex: 1, textAlign: 'center', height: 50 }} onClick={cancelModal}>取消</Text>
  317. <Text style={{ flex: 1, textAlign: 'center', height: 50 }} onClick={confirmModal}>确认</Text>
  318. </View> */}
  319. </View>
  320. </Modal>
  321. }
  322. {
  323. isTimePickerOpen && <Modal
  324. themeColor={(metricItem as any).theme_color}
  325. dismiss={() => setIsTimePickerOpen(false)} confirm={() => {
  326. var picker = limitPickerRef.current;
  327. chooseTime((picker as any).getConfirmData());
  328. setIsTimePickerOpen(false);
  329. }}>
  330. <LimitPickers ref={limitPickerRef} isRealTime={true} time={time} limit={limit} limitDay={180} onCancel={() => { setIsTimePickerOpen(false) }} onChange={(e) => {
  331. chooseTime(e)
  332. // pickerConfirm(e)
  333. // hidePicker()
  334. }} />
  335. </Modal>
  336. }
  337. </View>
  338. }