|
|
@@ -0,0 +1,194 @@
|
|
|
+import { DateInfo } from "../models/DateInfo";
|
|
|
+import { DateUtils, WEEK_MAP } from "../utils/DateUtils";
|
|
|
+
|
|
|
+@Component
|
|
|
+@CustomDialog
|
|
|
+export struct DiaryCalendarPicker {
|
|
|
+ // 年月
|
|
|
+ @State year: number = 2025;
|
|
|
+ @State month: number = 8;
|
|
|
+ // 开始是星期几
|
|
|
+ @State weekStart: number = 1;
|
|
|
+ // 本月的天数
|
|
|
+ @State daysInMonth: number = 31;
|
|
|
+ // 渲染用的月份数组
|
|
|
+ @State monthArray: DateInfo[] = [];
|
|
|
+ @State showDatePickerMenu: boolean = false
|
|
|
+ @State selectDay: Date = new Date()
|
|
|
+
|
|
|
+ private declare range: TextCascadePickerRangeContent[]
|
|
|
+ private years = Array.from<number, number>({ length: new Date().getFullYear() - 1970 + 1 }, (_: number, i: number) => 1970 + i)
|
|
|
+ //当前年月选择的下标
|
|
|
+ private selectedIndex: number[] = [new Date().getFullYear() - 1970, new Date().getMonth()]
|
|
|
+ private linearInfo: LinearGradientOptions = {
|
|
|
+ colors: [['#B9FD2A', 0.01], ['#F5FD6D', 1]],
|
|
|
+ angle: 110
|
|
|
+ }
|
|
|
+
|
|
|
+ // 取消
|
|
|
+ @Require onCancel: () => void = () => {}
|
|
|
+ // 确定
|
|
|
+ @Require onConfirm: (date: Date) => void = () => {}
|
|
|
+ // yy-mm-dd
|
|
|
+ @Require dateList: string[] = []
|
|
|
+
|
|
|
+ controll?: CustomDialogController
|
|
|
+
|
|
|
+ // 更改月份
|
|
|
+ changeMonth(year: number, month: number) {
|
|
|
+ // 1. 获取当前月份的天数
|
|
|
+ this.daysInMonth = DateUtils.getDaysInMonth(year, month);
|
|
|
+
|
|
|
+ // 2. 获取当月的第一天是星期几
|
|
|
+ this.weekStart = new Date(year, month - 1, 1).getDay() + 1;
|
|
|
+
|
|
|
+ // 3. 初始化月份数组
|
|
|
+ this.monthArray = [...new Array(this.weekStart - 1).fill({} as DateInfo),
|
|
|
+ ...DateUtils.generateBackwardDateArray(new Date(year, month - 1, 1), this.daysInMonth, false)];
|
|
|
+
|
|
|
+ return this.monthArray
|
|
|
+ }
|
|
|
+
|
|
|
+ aboutToAppear(): void {
|
|
|
+ this.changeMonth(2025, 8);
|
|
|
+
|
|
|
+ const monthsRange =
|
|
|
+ Array.from<number, number>({ length: 12 }, (_: number, i: number) => 1 + i).map(month => {
|
|
|
+ return { text: month.toString() } as TextCascadePickerRangeContent
|
|
|
+ })
|
|
|
+ this.range = this.years.map(year => {
|
|
|
+ return { text: year.toString(), children: monthsRange } as TextCascadePickerRangeContent
|
|
|
+ })
|
|
|
+ }
|
|
|
+
|
|
|
+ build() {
|
|
|
+ Column({space: 20}) {
|
|
|
+ Row() {
|
|
|
+ // 时间选择
|
|
|
+ Row({ space: 8 }) {
|
|
|
+ Text(`${this.year}-${this.month.toString().padStart(2, '0')}`)
|
|
|
+ .fontSize(16)
|
|
|
+ .fontWeight(600)
|
|
|
+
|
|
|
+ Image($r('app.media.Diary_DateOpen'))
|
|
|
+ .width(14)
|
|
|
+ .height(8)
|
|
|
+ }
|
|
|
+ .onClick(() => {
|
|
|
+ this.showDatePickerMenu = true
|
|
|
+ })
|
|
|
+ .bindMenu(this.showDatePickerMenu, this.dateSelectMenu, {
|
|
|
+ onDisappear: () => {
|
|
|
+ this.showDatePickerMenu = false
|
|
|
+ this.year = this.range[this.selectedIndex[0]].text.valueOf() as number
|
|
|
+ this.month = this.range[this.selectedIndex[0]].children![this.selectedIndex[1]].text.valueOf() as number
|
|
|
+ this.changeMonth(this.year, this.month)
|
|
|
+ },
|
|
|
+ placement: Placement.Bottom
|
|
|
+ })
|
|
|
+
|
|
|
+ // 确认和取消
|
|
|
+ Row({ space: 14 }) {
|
|
|
+ Text("取消")
|
|
|
+ .borderRadius(36)
|
|
|
+ .backgroundColor('#F6F6F6')
|
|
|
+ .padding({left: 20, top: 5, right: 20, bottom: 5})
|
|
|
+ .onClick(this.onCancel)
|
|
|
+ Text("确认")
|
|
|
+ .borderRadius(36)
|
|
|
+ .linearGradient(this.linearInfo)
|
|
|
+ .padding({left: 20, top: 5, right: 20, bottom: 5})
|
|
|
+ .onClick(() => {
|
|
|
+ this.onConfirm(this.selectDay)
|
|
|
+ })
|
|
|
+ }
|
|
|
+ }
|
|
|
+ .width("100%")
|
|
|
+ .alignItems(VerticalAlign.Center)
|
|
|
+ .justifyContent(FlexAlign.SpaceBetween)
|
|
|
+
|
|
|
+ Row() {
|
|
|
+ ForEach(WEEK_MAP, (item: string, index: number) => {
|
|
|
+ Text(item)
|
|
|
+ .width(32)
|
|
|
+ .textAlign(TextAlign.Center)
|
|
|
+ })
|
|
|
+ }
|
|
|
+ .width("100%")
|
|
|
+ .justifyContent(FlexAlign.SpaceBetween)
|
|
|
+
|
|
|
+ Grid() {
|
|
|
+ ForEach(this.monthArray, (item: DateInfo, index: number) => {
|
|
|
+ GridItem() {
|
|
|
+ Column({space: 3}) {
|
|
|
+ if (item.id) {
|
|
|
+ Row() {
|
|
|
+ Text(item.day + '')
|
|
|
+ .fontSize(12)
|
|
|
+ .fontColor(DateUtils.isSameDay(item.id, this.selectDay) ? Color.Black : '#979797')
|
|
|
+ }
|
|
|
+ .width(32)
|
|
|
+ .aspectRatio(1)
|
|
|
+ .borderRadius(8)
|
|
|
+ .linearGradient(DateUtils.isSameDay(item.id, this.selectDay) ? this.linearInfo : {
|
|
|
+ colors: [['#F6F6F6', 1]],
|
|
|
+ })
|
|
|
+ .alignItems(VerticalAlign.Center)
|
|
|
+ .justifyContent(FlexAlign.Center)
|
|
|
+ .onClick(() => {
|
|
|
+ this.selectDay = item.id
|
|
|
+ })
|
|
|
+
|
|
|
+ Text()
|
|
|
+ .width(4)
|
|
|
+ .aspectRatio(1)
|
|
|
+ .borderRadius(2)
|
|
|
+ .linearGradient(this.dateList.indexOf(DateUtils.formatDateToCustomString(item.id, false)) !== -1 ? this.linearInfo : null)
|
|
|
+ } else {
|
|
|
+ Text('')
|
|
|
+ Text('')
|
|
|
+ }
|
|
|
+ }
|
|
|
+ .width(49)
|
|
|
+ .aspectRatio(1)
|
|
|
+ .alignItems(HorizontalAlign.Center)
|
|
|
+ .justifyContent(FlexAlign.Center)
|
|
|
+ }
|
|
|
+ })
|
|
|
+ }
|
|
|
+ .columnsTemplate('repeat(7, 1fr)')
|
|
|
+ .width("100%")
|
|
|
+ }
|
|
|
+ .width("100%")
|
|
|
+ .height(400)
|
|
|
+ .backgroundColor(Color.White)
|
|
|
+ .padding({left: 15, right: 15, top: 20, bottom: 4})
|
|
|
+ }
|
|
|
+
|
|
|
+ @Builder
|
|
|
+ private dateSelectMenu() {
|
|
|
+ Stack({ alignContent: Alignment.Center }) {
|
|
|
+ TextPicker({ range: this.range, selected: this.selectedIndex })
|
|
|
+ .selectedTextStyle({ color: '#FF353C46', font: { weight: 500, size: 16 } })
|
|
|
+ .defaultPickerItemHeight(36)
|
|
|
+ .divider(null)
|
|
|
+ .onScrollStop((value, index) => {
|
|
|
+ console.log(`testLog ${value} ${index}`)
|
|
|
+ this.selectedIndex = index as number[]
|
|
|
+ })
|
|
|
+
|
|
|
+ //自定义选择遮罩
|
|
|
+ Column() {
|
|
|
+
|
|
|
+ }
|
|
|
+ .width('100%')
|
|
|
+ .height(36)
|
|
|
+ .backgroundColor('#52D9D9D9')
|
|
|
+ .borderRadius(8)
|
|
|
+ }
|
|
|
+ .height(140)
|
|
|
+ .width(160)
|
|
|
+ .padding(12)
|
|
|
+ .borderRadius(8)
|
|
|
+ }
|
|
|
+}
|