RecodView.ets 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490
  1. import { AppStorageKeyCollect, IBestToast, userInfo, UserInfo, YTAvoid, yTRouter } from 'basic'
  2. import { DateInfo } from '../models/DateInfo'
  3. import { RecodeViewModel } from '../viewModels/RecodeViewModel'
  4. import { DiaryDatePicker } from '../components/DiaryDatePicker'
  5. import { DiaryTimePicker } from '../components/DiaryTimePicker'
  6. import { DateUtils } from '../utils/DateUtils'
  7. import { DiaryData, PageStatus } from '../models'
  8. import { CollaborationCameraStateDialog } from '@hms.collaboration.camera'
  9. import { LoginComponent } from '../components/LoginComponent'
  10. /**
  11. * 记录页面
  12. */
  13. @Component
  14. export struct RecodView {
  15. @StorageProp(YTAvoid.SAFE_BOTTOM_KEY) bottom: number = 0
  16. @StorageProp(YTAvoid.SAFE_TOP_KEY) safeTop: number = 0
  17. @State Vm: RecodeViewModel = new RecodeViewModel()
  18. @State heightList: number[] = []
  19. // 去登录界面
  20. @State ShowLoginDialog: boolean = false
  21. @StorageProp(UserInfo.KEY) @Watch('loginStateChanged') userInfo: UserInfo = userInfo
  22. private linearInfo: LinearGradientOptions = {
  23. colors: [ ['#B9FD2A', 0.01], ['#F5FD6D', 1] ],
  24. angle: 110
  25. }
  26. selectDateChange = (index: number) => {
  27. this.Vm.selectedDate = index
  28. this.Vm.changeDataByIndex()
  29. console.log('改变了选择的日期')
  30. }
  31. /**
  32. * 登录状态发生变化
  33. */
  34. loginStateChanged(){
  35. console.log('登录状态发生变化 登录状态为 ' + this.userInfo.checkLogin())
  36. const loginState = this.userInfo.checkLogin()
  37. if(loginState){
  38. this.ShowLoginDialog = false
  39. this.loadDataList(DateUtils.formatDateToCustomString(new Date(), false))
  40. } else {
  41. this.Vm.recodeList = []
  42. }
  43. }
  44. // 加载小记录数据列表
  45. async loadDataList(targetDate: string) {
  46. if(this.userInfo.checkLogin()) {
  47. this.Vm.queryNoteList(targetDate)
  48. } else {
  49. this.ShowLoginDialog = true
  50. }
  51. }
  52. /**
  53. * 更新小记录时间
  54. * @param index
  55. * @param time
  56. */
  57. async updateNoteTime(index: number, time: string) {
  58. let currentNote: DiaryData = this.Vm.recodeList[index]
  59. currentNote.noteTime = currentNote.noteTime?.split(' ')[0] + ' ' + time + ':00'
  60. let ans = await this.Vm.updateNoteTime(currentNote)
  61. if(ans) {
  62. this.Vm.changeDataByIndex()
  63. IBestToast.show('更改成功')
  64. } else {
  65. IBestToast.show('更改失败')
  66. }
  67. }
  68. /**
  69. * 跳转至添加小记录页面
  70. * @param id
  71. */
  72. routerAddNote(id?: number) {
  73. yTRouter.pushPathByName("IncreaseDiaryPage", {
  74. 'id': id,
  75. 'PageStatus': PageStatus.RECODE
  76. } as Record<string, boolean | number | string>);
  77. }
  78. aboutToAppear(): void {
  79. this.Vm.selectedDateChange = this.selectDateChange
  80. this.loadDataList(DateUtils.formatDateToCustomString(new Date(), false))
  81. }
  82. build() {
  83. Stack(){
  84. Column(){
  85. Row(){
  86. Image($r("app.media.RecodeTitle"))
  87. .width(140)
  88. .height(44)
  89. Image($r("app.media.calendar"))
  90. .width(30)
  91. .aspectRatio(1)
  92. .onClick(() => {
  93. animateToImmediately({
  94. duration: 200
  95. }, () => {
  96. if(this.Vm.showDatePicker) {
  97. this.Vm.showDatePicker = false
  98. } else {
  99. this.Vm.showDatePicker = true
  100. this.Vm.showTimePicker = -1
  101. }
  102. })
  103. })
  104. }
  105. .width("100%")
  106. .height(76)
  107. .justifyContent(FlexAlign.SpaceBetween)
  108. .alignItems(VerticalAlign.Center)
  109. .padding({ left: 17, right: 17, bottom: 17, top: 17})
  110. .onClick(() => {
  111. this.Vm.showTimePicker = -1
  112. this.Vm.showDatePicker = false
  113. })
  114. // 时间选择器 - 使用区域变换实现
  115. if(this.Vm.showTimePicker != -1) {
  116. DiaryTimePicker({
  117. timeStr: this.Vm.getTime(this.Vm.showTimePicker),
  118. onConfirm: (time: string) => {
  119. this.updateNoteTime(this.Vm.showTimePicker, time)
  120. this.Vm.showTimePicker = -1
  121. },
  122. onCancel: () => {
  123. this.Vm.showTimePicker = -1
  124. }
  125. })
  126. .position({
  127. // x: 5,
  128. // y: 35
  129. x: this.Vm.getPostion('x'),
  130. y: this.Vm.getPostion('y')
  131. })
  132. .zIndex(100)
  133. }
  134. // 主体内容
  135. Stack({alignContent: Alignment.TopEnd}){
  136. Column(){
  137. // 日期选择
  138. Swiper(this.Vm.swiperController){
  139. LazyForEach(this.Vm.weekLoop, (item: DateInfo, index: number) => {
  140. Column({space: 2}) {
  141. Column({space: 15}){
  142. Text(item.week)
  143. // ${item.month}-
  144. Text(`${item.day}`)
  145. }
  146. .width("100%")
  147. .padding({ top: 5, bottom: 5 })
  148. .borderRadius(10)
  149. .linearGradient(this.Vm.selectedDate === index ? this.linearInfo : null)
  150. // TODO 表示某天有数据 - 暂无接口,待定
  151. if(false) {
  152. Row()
  153. .width(6)
  154. .height(6)
  155. .borderRadius(3)
  156. .backgroundColor('#BAFE2B')
  157. }
  158. }
  159. .width(50)
  160. .height(80)
  161. .padding({
  162. left: 7,
  163. right: 7,
  164. top: 9,
  165. })
  166. .onClick(() => {
  167. this.selectDateChange(index)
  168. })
  169. }, (item: DateInfo, index: number) => { return item.id.toString() })
  170. }
  171. .loop(false)
  172. .displayCount(7)
  173. .indicator(false)
  174. .direction(Direction.Rtl)
  175. .onChange((index: number) => {
  176. this.Vm.swiperOnChange(index)
  177. })
  178. // 记录内容主体
  179. Stack({alignContent: Alignment.BottomEnd}){
  180. List({space: 10}) {
  181. ListItem()
  182. .height(20)
  183. .onClick(() => {
  184. this.Vm.showTimePicker = -1
  185. this.Vm.showDatePicker = false
  186. })
  187. ForEach(this.Vm.recodeList, (item: DiaryData, index: number) => {
  188. ListItem(){
  189. Row({space: 20}){
  190. // 时间 和 分隔线
  191. Column({space: 5}){
  192. Row(){
  193. Text(this.Vm.getTime(index))
  194. .fontSize(14)
  195. .padding({
  196. top: 5,
  197. left: 8,
  198. right: 8,
  199. bottom: 5
  200. })
  201. .fontWeight(400)
  202. .borderRadius(8)
  203. .fontColor(Color.Black)
  204. .linearGradient(this.linearInfo)
  205. }
  206. .width(54)
  207. .height(30)
  208. .alignItems(VerticalAlign.Center)
  209. .justifyContent(FlexAlign.Center)
  210. .onClick(() => {
  211. if(this.Vm.showTimePicker === index) {
  212. this.Vm.showTimePicker = -1
  213. } else {
  214. this.Vm.showTimePicker = index
  215. this.Vm.showDatePicker = false
  216. }
  217. })
  218. // 分隔线
  219. Column(){
  220. Row() {
  221. Row()
  222. .width(7)
  223. .aspectRatio(1)
  224. .borderRadius(4)
  225. .backgroundColor(Color.White)
  226. }
  227. .width(10)
  228. .aspectRatio(1)
  229. .borderRadius(5)
  230. .backgroundColor('#B9FD2A')
  231. .alignItems(VerticalAlign.Center)
  232. .justifyContent(FlexAlign.Center)
  233. Row()
  234. .width(3)
  235. .backgroundColor('#E9E9EC')
  236. .layoutWeight(1)
  237. Row() {
  238. Row()
  239. .width(7)
  240. .aspectRatio(1)
  241. .borderRadius(4)
  242. .backgroundColor(Color.White)
  243. }
  244. .width(10)
  245. .aspectRatio(1)
  246. .borderRadius(5)
  247. .backgroundColor('#B9FD2A')
  248. .alignItems(VerticalAlign.Center)
  249. .justifyContent(FlexAlign.Center)
  250. }
  251. .width(30)
  252. .height(this.heightList[index] + 15)
  253. }
  254. // .layoutWeight(1)
  255. // 标题 和 内容
  256. Column({space: 5}){
  257. Row(){
  258. Text(item.title)
  259. .fontSize(14)
  260. .fontWeight(600)
  261. .padding({
  262. top: 5,
  263. left: 8,
  264. right: 8,
  265. bottom: 5
  266. })
  267. }
  268. .height(30)
  269. .alignItems(VerticalAlign.Center)
  270. .justifyContent(FlexAlign.Center)
  271. // 内容
  272. Column({space: 8}){
  273. Text(item.content)
  274. .fontSize(12)
  275. .fontColor('#212245')
  276. .opacity(0.5)
  277. // 图片显示
  278. Scroll(){
  279. Row({space: 5}){
  280. ForEach(item.imageUrls, (url: string, index: number) => {
  281. Image(url)
  282. .width(100)
  283. .height(150)
  284. .borderRadius(12)
  285. })
  286. }
  287. }
  288. .scrollable(ScrollDirection.Horizontal)
  289. .scrollBar(BarState.Off)
  290. }
  291. .alignItems(HorizontalAlign.Start)
  292. .justifyContent(FlexAlign.Start)
  293. .onAreaChange((_o: Area, _n: Area) => {
  294. this.heightList[index] = _n.height as number
  295. })
  296. Blank().height(15)
  297. }
  298. .layoutWeight(1)
  299. .alignItems(HorizontalAlign.Start)
  300. .justifyContent(FlexAlign.Start)
  301. .onClick(() => {
  302. this.routerAddNote(item.id!)
  303. this.Vm.showDatePicker = false
  304. this.Vm.showTimePicker = -1
  305. })
  306. .gesture(
  307. LongPressGesture()
  308. .onAction(() => {
  309. console.log("长按了哦")
  310. this.Vm.onDelRecode(item.id!)
  311. })
  312. )
  313. }
  314. .onClick(() => {
  315. this.Vm.showTimePicker = -1
  316. this.Vm.showDatePicker = false
  317. })
  318. .onAreaChange((_o: Area, _n: Area) => {
  319. console.log('位置信息' + JSON.stringify(_n.globalPosition))
  320. let postion = this.Vm.postionList
  321. postion[index] = _n.globalPosition
  322. this.Vm.postionList = postion
  323. })
  324. }
  325. })
  326. // 空数据页面
  327. if(this.Vm.recodeList.length === 0) {
  328. ListItem(){
  329. Column({space: 12}){
  330. Row({space: 8}){
  331. Text("+")
  332. Text("去添加")
  333. }
  334. .borderRadius(8)
  335. .linearGradient(this.linearInfo)
  336. .alignItems(VerticalAlign.Center)
  337. .justifyContent(FlexAlign.Center)
  338. .border({width: 1, color: Color.Black})
  339. .padding({ left: 16, top: 12, right: 16, bottom: 12})
  340. .onClick(() => {
  341. this.routerAddNote()
  342. })
  343. Text("暂无记录~")
  344. .fontSize(14)
  345. .fontWeight(400)
  346. }
  347. .width("100%")
  348. .height("100%")
  349. .alignItems(HorizontalAlign.Center)
  350. .padding({ top: '30%'})
  351. // .justifyContent(FlexAlign.Center)
  352. }
  353. .layoutWeight(1)
  354. .width("100%")
  355. }
  356. }
  357. .width("100%")
  358. .height("100%")
  359. .scrollBar(BarState.Off)
  360. .padding({top: 10})
  361. .onScrollIndex(() => {
  362. this.Vm.showTimePicker = -1
  363. })
  364. // 增加日记按钮
  365. Row() {
  366. Image($r("app.media.add_Img"))
  367. .width("100%")
  368. .aspectRatio(1)
  369. }
  370. .onClick(() => {
  371. this.routerAddNote()
  372. })
  373. .width(40)
  374. .aspectRatio(1)
  375. .borderRadius(20)
  376. .margin({ bottom: 16 })
  377. .alignItems(VerticalAlign.Center)
  378. .justifyContent(FlexAlign.Center)
  379. .linearGradient(this.linearInfo)
  380. }
  381. .width("100%")
  382. .layoutWeight(1)
  383. .padding({
  384. bottom: 20, left: 24, right: 24
  385. })
  386. // 记录内容主体
  387. // Stack({ alignContent: Alignment.BottomEnd }){
  388. //
  389. // // 增加日记按钮
  390. // Row() {
  391. // Image($r("app.media.add"))
  392. // .width(20)
  393. // .aspectRatio(1)
  394. // }
  395. // .onClick(() => {
  396. // this.routerAddNote()
  397. // })
  398. // .width(40)
  399. // .aspectRatio(1)
  400. // .borderRadius(20)
  401. // .padding(8)
  402. // // .border({ width: 1 })
  403. // .margin({ bottom: 16 })
  404. // // .backgroundColor(Color.White)
  405. // .alignItems(VerticalAlign.Center)
  406. // .justifyContent(FlexAlign.Center)
  407. // .linearGradient(this.linearInfo)
  408. // }
  409. // .width("100%")
  410. // .layoutWeight(1)
  411. }
  412. // 日期选择器
  413. if(this.Vm.showDatePicker) {
  414. DiaryDatePicker({
  415. selectedDate: this.Vm.weekLoop.getData(this.Vm.swiperCurrentIndex).id,
  416. selectDateBack: (date: Date) => {
  417. this.Vm.showDatePicker = false
  418. this.Vm.jumpToDate(date)
  419. }
  420. })
  421. .width(267)
  422. }
  423. }
  424. .width("100%")
  425. .layoutWeight(1)
  426. .backgroundColor(Color.White)
  427. .borderRadius({
  428. topLeft: 20,
  429. topRight: 20
  430. })
  431. }
  432. .width("100%")
  433. .height("100%")
  434. .padding({ top: this.safeTop})
  435. .linearGradient({
  436. colors: [ ['#B9FD2A', 0.01], ['#F5FD6D', 1] ],
  437. angle: 150
  438. })
  439. .onVisibleAreaChange([0, 1], (isExpanding: boolean, currentRatio: number) => {
  440. if(isExpanding) {
  441. console.log("组件出来了")
  442. this.loadDataList(this.Vm.getSelectedDate())
  443. } else {
  444. console.log("组件退了")
  445. }
  446. })
  447. if(this.ShowLoginDialog){
  448. LoginComponent()
  449. }
  450. }
  451. .width("100%")
  452. .height("100%")
  453. }
  454. }