RecodView.ets 17 KB

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