Преглед изворни кода

feat: 初始化项目, 新增多种弹窗功能

YuJing пре 1 месец
родитељ
комит
5e01cbf190

+ 1 - 1
commons/basic/src/main/ets/components/generalComp/YTDiaLogComp.ets

@@ -1,4 +1,4 @@
-import { YTDiaLogModel } from 'feature/src/main/ets/model/YTDiaLogModel'
+import { YTDiaLogModel } from '../../models/YTDiaLogModel'
 import { yTRouter } from '../../utils/YTRouter'
 
 @ComponentV2

+ 5 - 3
commons/basic/src/main/ets/models/UserInfo.ets

@@ -21,7 +21,7 @@ export class UserInfo {
   private memberScore?: number
   private declare pushToken: string
 
-  private constructor() {
+  constructor() {
   }
 
   /**
@@ -39,7 +39,7 @@ export class UserInfo {
    * 设置用户信息并且设置登录状态
    * @param _userInfo
    */
-  setUserInfoAndLogin(_userInfo: UserInfo) {
+  setUserInfoAndLogin(_userInfo: UserInfo, isEmitter: boolean = true) {
     userInfo.isLogin = true
     if (_userInfo.token) {
       userInfo.token = _userInfo.token
@@ -52,7 +52,9 @@ export class UserInfo {
     userInfo.aiCount = _userInfo.aiCount
     userInfo.memberPhone = _userInfo.memberPhone
 
-    emitter.emit(EmitterKeyCollection.LOGIN)
+    if(isEmitter){
+      emitter.emit(EmitterKeyCollection.LOGIN)
+    }
     AppStorage.setOrCreate(UserInfo.KEY, userInfo)
   }
 

+ 2 - 1
commons/basic/src/main/ets/models/YTDiaLogModel.ets

@@ -12,7 +12,7 @@ export enum DiaLogPageEnum{
   // 数字输入
   NumBerInput,
   // 文本输入
-  TextInput,
+  // TextInput,
   // 对话框 - 确认
   Confirm,
   // 底部菜单
@@ -21,6 +21,7 @@ export enum DiaLogPageEnum{
 
 export interface DiaLogParam{
   pageEnum: DiaLogPageEnum,
+  align?: YTDiaLogModel,
   param?: BasicType,
   params?: Array<BasicType>
 }

+ 1 - 1
commons/basic/src/main/ets/utils/YTRouter.ets

@@ -74,7 +74,7 @@ class YTRouter extends NavPathStack {
     yTRouter.pop()
   }
 
-
+  // 打开路由弹窗
   router2NaviDiaLog(param: DiaLogParam, back?: Callback<PopInfo>){
     yTRouter.pushPathByName('YTNaviDiaLog', param, back, false)
   }

+ 331 - 0
features/feature/src/main/ets/components/NumberKeyboard.ets

@@ -0,0 +1,331 @@
+export class NumberKeyBoardStyle {
+  private static instance: NumberKeyBoardStyle
+  //重写所有点击事件 慎用 参数一为下标 参数二为当前textInputValue的值
+  rebuildAllClick?: (_: string, __: number) => void
+  private border: BorderOptions = { width: 1, color: '#FF1A7DD8' }
+  private borderRadius: Length | BorderRadiuses | LocalizedBorderRadiuses = 6
+  private commonButtonBackgroundColor: ResourceColor = Color.White
+  //0的背景颜色
+  private zeroBackGround: ResourceColor = '#FFACD7FF'
+  //完成的背景颜色
+  private finishBackGround: ResourceColor = '#FF186EBD'
+  //删除按钮的图标
+  private deleteIcon: ResourceStr = $r('app.media.app_icon')
+  //完成按钮的text
+  private finishText: ResourceStr = '完成'
+  private rowsGap: Length = 4.62
+  private columnsGap: Length = 4.62
+  //大按钮的高
+  private longHeight: Length = 101.69
+  //普通按钮的高
+  private shortHeight: Length = 48.59
+  //字体样式
+  private fontSize: number = 20
+  private fonsWeight: number = 500
+  private fontFamily: string = 'Source Han Sans SC'
+
+  constructor() {
+    if (!NumberKeyBoardStyle.instance) {
+      NumberKeyBoardStyle.instance = this
+    }
+    return NumberKeyBoardStyle.instance
+  }
+
+  getFontSize() {
+    return this.fontSize
+  }
+
+  setFontSize(fontSize: number) {
+    this.fontSize = fontSize
+    return this
+  }
+
+  getFontWeight() {
+    return this.fonsWeight
+  }
+
+  setFontWeight(fontWeight: number) {
+    this.fonsWeight = fontWeight
+    return this
+  }
+
+  getFontFamily() {
+    return this.fontFamily
+  }
+
+  setFontFamily(fontFamily: string) {
+    this.fontFamily = fontFamily
+    return this
+  }
+
+  getShortHeight() {
+    return this.shortHeight
+  }
+
+  setShortHeight(height: Length) {
+    this.shortHeight = height
+    return this
+  }
+
+  getLongHeight() {
+    return this.longHeight
+  }
+
+  setLongHeight(height: Length) {
+    this.longHeight = height
+    return this
+  }
+
+  getRowsGap() {
+    return this.rowsGap
+  }
+
+  setColumnsGap(columnsGap: number) {
+    this.columnsGap = columnsGap
+    return this
+  }
+
+  setRowsGap(rowsGap: number) {
+    this.rowsGap = rowsGap
+    return this
+  }
+
+  getColumnsGap() {
+    return this.columnsGap
+  }
+
+  getBorder() {
+    return this.border
+  }
+
+  setBorder(border: BorderOptions) {
+    this.border = border
+    return this
+  }
+
+  getBorderRadius() {
+    return this.borderRadius
+  }
+
+  setBorderRadius(borderRadius: Length | BorderRadiuses | LocalizedBorderRadiuses) {
+    this.borderRadius = borderRadius
+    return this
+  }
+
+  getZeroBackGround() {
+    return this.zeroBackGround
+  }
+
+  setZeroBackGround(zeroBackGround: ResourceColor) {
+    this.zeroBackGround = zeroBackGround
+    return this
+  }
+
+  getFinishBackGround() {
+    return this.finishBackGround
+  }
+
+  setFinishBackGround(finishBackGround: ResourceColor) {
+    this.finishBackGround = finishBackGround
+    return this
+  }
+
+  getDeleteIcon() {
+    return this.deleteIcon
+  }
+
+  setDeleteIcon(deleteIcon: ResourceStr) {
+    this.deleteIcon = deleteIcon
+    return this
+  }
+
+  getCommonButtonBackground() {
+    return this.commonButtonBackgroundColor
+  }
+
+  setCommonButtonBackground(commonButtonBackground: ResourceColor) {
+    this.commonButtonBackgroundColor = commonButtonBackground
+    return this
+  }
+
+  getFinishText() {
+    return this.finishText
+  }
+
+  setFinishText(finishText: ResourceStr) {
+    this.finishText = finishText
+    return this
+  }
+}
+
+@Extend(Text)
+function TextStyle(style: NumberKeyBoardStyle) {
+  .fontSize(style.getFontSize())
+  .fontWeight(style.getFontWeight())
+  .fontFamily(style.getFontFamily())
+}
+
+
+/**
+ * @description 自定义数字按钮键盘
+ */
+@Component
+export struct NumberKeyBoard {
+  //初始值
+  @Prop @Require textInputValue: string
+  //最大输入数
+  maxInputNum: number = 5
+  //样式设置 支持链式设置 允许动态修改 但是如果在父组件使用链式调用需要重新赋值,因为链式调用会导致装饰器失效
+  @Prop keyBoardStyle: NumberKeyBoardStyle
+  //完成字体的样式 自己实现AttributeModifier<TextAttribute>来传 AttributeModifier不支持响应式 如果需要动态刷新需要同步更改其它具有响应式的属性
+  textModifier?: AttributeModifier<TextAttribute>
+  //grid计算器的排序规则
+  private layoutOptions: GridLayoutOptions = {
+    regularSize: [1, 1],
+    irregularIndexes: Array.from<undefined>({ length: 13 }).map((_,
+      index) => index),
+    onGetIrregularSizeByIndex: (index: number) => {
+      if (index < 10) {
+        if (index == 3) {
+          return [2, 3]
+        }
+        return [1, 3]
+      } else if (index == 10) {
+        return [2, 3]
+      } else if (index == 11) {
+        return [1, 4]
+      } else {
+        return [1, 5]
+      }
+
+    }
+  };
+  //点击完成所需要的逻辑
+  onFinishClick = (_: string) => {
+  }
+  //输入值变化
+  onTextInputValueChange = (_: string) => {
+  }
+
+  @Styles
+  pressStyles() {
+    .opacity(0.7)
+  }
+
+  @Styles
+  normalStyles() {
+    .opacity(1)
+  }
+
+  build() {
+
+    Grid(undefined, this.layoutOptions) {
+      ForEach(Array.from({ length: 13 }), (_: undefined, index) => {
+        GridItem() {
+          Column() {
+            if (index == 3) {
+              Image(this.keyBoardStyle.getDeleteIcon())
+                .width(20)
+                .aspectRatio(2)
+            } else if (index == 10) {
+              Text(this.keyBoardStyle.getFinishText())
+                .TextStyle(this.keyBoardStyle)
+                .attributeModifier(this.textModifier)
+            } else if (index == 11) {
+              Text('0')
+                .TextStyle(this.keyBoardStyle)
+            } else if (index == 12) {
+              Text('.')
+                .TextStyle(this.keyBoardStyle)
+            } else if (index < 3) {
+              Text((index + 1).toString())
+                .TextStyle(this.keyBoardStyle)
+            } else {
+              Text(index.toString())
+                .TextStyle(this.keyBoardStyle)
+            }
+          }
+          .backgroundColor(index == 11 ? this.keyBoardStyle.getZeroBackGround() :
+            index == 10 ? this.keyBoardStyle.getFinishBackGround() : this.keyBoardStyle.getCommonButtonBackground())
+          .width('100%')
+          .height(this.calcGridItemHeight(index))
+          .borderRadius(this.keyBoardStyle.getBorderRadius())
+          .justifyContent(FlexAlign.Center)
+          .border(this.keyBoardStyle.getBorder())
+          .stateStyles({
+            pressed: this.pressStyles,
+            normal: this.normalStyles
+          })
+          .onClick(() => {
+            if (this.keyBoardStyle.rebuildAllClick) {
+              this.keyBoardStyle.rebuildAllClick(this.textInputValue, index)
+              return
+            }
+            if (index == 3) {
+              if (this.textInputValue.length > 0) {
+                this.textInputValue = this.textInputValue.slice(0, this.textInputValue.length - 1)
+              }
+              if (this.textInputValue == '') {
+                this.textInputValue = '0'
+              }
+
+              this.onTextInputValueChange(this.textInputValue)
+              return
+            }
+            if (index == 10) {
+              this.onFinishClick(this.textInputValue)
+              return
+            }
+            if (this.textInputValue.length >= this.maxInputNum) {
+              if (this.textInputValue.length > this.maxInputNum) {
+                //裁剪为最大长度
+                this.textInputValue = this.textInputValue.slice(0, this.maxInputNum)
+              }
+              return
+            }
+
+            if (index == 11) {
+              if (parseInt(this.textInputValue) > 0) {
+                this.textInputValue = this.textInputValue.concat('0')
+              }
+            } else if (index == 12) {
+              if (!this.textInputValue.includes('.')) {
+                this.textInputValue = this.textInputValue.concat('.')
+              }
+            } else if (index < 3) {
+              if (parseInt(this.textInputValue) > 0) {
+                this.textInputValue = this.textInputValue.concat((index + 1).toString())
+              } else {
+                this.textInputValue = (index + 1).toString()
+              }
+
+            } else {
+              if (parseInt(this.textInputValue) > 0|| this.textInputValue.includes('.')) {
+                this.textInputValue = this.textInputValue.concat(index.toString())
+              } else {
+                this.textInputValue = index.toString()
+              }
+            }
+
+            this.onTextInputValueChange(this.textInputValue)
+
+          })
+        }
+      })
+    }
+    .rowsGap(this.keyBoardStyle.getRowsGap())
+    .columnsGap(this.keyBoardStyle.getColumnsGap())
+    .columnsTemplate('repeat(12, 1fr)')
+    // .layoutWeight(1)
+    .width('100%')
+  }
+
+  //计算渲染grid的高
+  private calcGridItemHeight(index: number): Length {
+    if (index == 3 || index == 10) {
+      return this.keyBoardStyle.getLongHeight()
+    } else {
+      return this.keyBoardStyle.getShortHeight()
+    }
+  }
+}

+ 196 - 0
features/feature/src/main/ets/components/YTDiaLogBuild.ets

@@ -0,0 +1,196 @@
+import { BasicType } from 'basic'
+import { DiaLogPageEnum, DiaLogParam } from 'basic/src/main/ets/models/YTDiaLogModel'
+import { NumberKeyBoard, NumberKeyBoardStyle } from './NumberKeyboard'
+import { YtDatePicker } from './YtDatePicker'
+import { _YtHeader } from './_YtHeader'
+
+
+@Builder
+export function getBuilder(param: DiaLogParam, onBack: (ans?: string) => void){
+  if(param.pageEnum == DiaLogPageEnum.BottomMenu) BottomMenu(onBack, param.params)
+  else if (param.pageEnum == DiaLogPageEnum.DatePicker) DatePickerBuilder(onBack, param.param)
+  else if (param.pageEnum == DiaLogPageEnum.NumBerInput) NumberInputBuilder({onBack: onBack, param: param.param})
+  else if (param.pageEnum == DiaLogPageEnum.Confirm) DoubleConfirm(onBack, param.param)
+}
+
+// 底部菜单
+@Builder
+function BottomMenu(onBack: (ans:string) => void, params?: Array<BasicType>) {
+  Column(){
+    ForEach(params, (item: BasicType, index) => {
+      Row(){
+        Text(item.text)
+          .fontSize(16)
+          .textAlign(TextAlign.Center)
+      }
+      .width("100%")
+      .alignItems(VerticalAlign.Center)
+      .justifyContent(FlexAlign.Center)
+      .padding({ top: 24, bottom: 24 })
+      .onClick(() => {
+        let ans = item.message ?? item.text ?? `${index}`
+        onBack(ans)
+      })
+
+      Divider().width("80%").height(1).backgroundColor('#000000F2')
+    })
+  }
+  .width("100%")
+  .padding({ bottom: 30 })
+  .backgroundColor(Color.White)
+  .justifyContent(FlexAlign.Center)
+  .alignItems(HorizontalAlign.Center)
+  .borderRadius({ topLeft: 8, topRight: 8 })
+}
+
+// 时间选择器
+@Builder
+function DatePickerBuilder(onBack: (ans:string) => void, param?: BasicType){
+  YtDatePicker({selectDateBack: (date: Date) => {
+    // 转换为 YY-MM-DD HH:mm:ss 格式
+    const year = date.getFullYear().toString();
+    const month = (date.getMonth() + 1).toString().padStart(2, '0');
+    const day = date.getDate().toString().padStart(2, '0');
+
+    const result = `${year}-${month}-${day}`;
+    onBack(result)
+  }, selectedDate: param?.date ? new Date(param.date) : new Date()})
+}
+
+// 对话框
+@Builder
+function DoubleConfirm(onBack: (ans?:string) => void, param?: BasicType) {
+  Column() {
+    if(param?.text)
+      Text(param.text)
+        .fontColor($r('sys.color.mask_secondary'))
+        .lineHeight(18)
+        .fontSize(18)
+        .margin({ bottom: 18 })
+    Row() {
+      Text('取消')
+        .fontSize(16)
+        .fontWeight(400)
+        .borderRadius(36)
+        .fontColor(Color.Black)
+        .backgroundColor('#F5F5F7')
+        .padding({ left: 36, top: 9, right: 36, bottom: 9})
+        .onClick(() => {
+          onBack()
+        })
+
+      Text('确定')
+        .fontSize(16)
+        .fontWeight(400)
+        .borderRadius(36)
+        .fontColor(Color.Black)
+        .padding({ left: 36, top: 9, right: 36, bottom: 9})
+        .linearGradient({
+          colors: [ ['#30E3CE', 0.4], ['#91F1FF', 0.8]],
+          angle: 200
+        })
+        .onClick(() => {
+          onBack('true')
+        })
+    }
+    .justifyContent(FlexAlign.SpaceBetween)
+    .width('100%')
+  }
+  // .height(160)
+  .width(280)
+  .padding({ top: 28, left: 32, right: 32, bottom: 20 })
+  .backgroundColor(Color.White)
+  .borderRadius(8)
+}
+
+// 数字输入框
+@ComponentV2
+struct NumberInputBuilder{
+  @Event onBack: (ans:string) => void
+  @Param @Require param: BasicType
+
+  @Local ans: string = ''
+
+  aboutToAppear(): void {
+    this.ans = this.param.text ?? ''
+  }
+
+
+  build() {
+    Column(){
+      RelativeContainer(){
+        _YtHeader({ title: this.param?.text ?? '', isShowBackComp: false, })
+          .height(44)
+          .id('_title')
+          .width("100%")
+          .alignRules({
+            top: { anchor: "__container__", align: VerticalAlign.Top},
+            left: { anchor: "__container__", align: HorizontalAlign.Start}
+          })
+
+        Text(this.ans)
+          .fontSize(32)
+          .fontWeight(500)
+          .fontColor('#30E3CE')
+          .id('weight')
+          .padding({left: 58, right: 58, bottom: 10, top: 60})
+          .alignRules({
+            top: { anchor: "_title", align: VerticalAlign.Bottom},
+            middle: { anchor: "__container__", align: HorizontalAlign.Center}
+          })
+
+        Row()
+          .width(151)
+          .height(3)
+          .backgroundColor('#30E3CE')
+          .borderRadius(8)
+          .alignRules({
+            top: { anchor: "weight", align: VerticalAlign.Bottom},
+            middle: { anchor: "__container__", align: HorizontalAlign.Center}
+          })
+
+        Text(this.param?.message ?? '')
+          .fontSize(20)
+          .fontWeight(500)
+          .padding({ bottom: 10 })
+          .fontColor('rgba(0, 0, 0, 0.5)')
+          .alignRules({
+            bottom: { anchor: "weight", align: VerticalAlign.Bottom},
+            right: { anchor: "weight", align: HorizontalAlign.End}
+          })
+      }
+      .height(210)
+      .backgroundColor(Color.White)
+
+      Column(){
+        NumberKeyBoard({
+          textInputValue: this.ans,
+          maxInputNum: 3,
+          keyBoardStyle: new NumberKeyBoardStyle()
+            .setFinishBackGround('#30E3CE')
+            .setZeroBackGround(Color.White)
+            .setBorder({ width: 0 })
+            .setDeleteIcon($r('app.media.icon_delback')),
+          onTextInputValueChange: (textInputValue: string) => {
+            this.ans = textInputValue
+          },
+          onFinishClick: (text: string) => {
+            if(!text || text == '0' || text == '0.') return
+            if(text.charAt(text.length-1) === '.') this.ans += '0'
+            this.onBack(this.ans!)
+          }
+        })
+      }
+      .height(260)
+      .width("100%")
+      .backgroundColor('#F5F6FA')
+      .padding({ top: 10, bottom: 35, left: 10, right: 10})
+    }
+    // .height(470)
+    .width("100%")
+    .backgroundColor(Color.White)
+    .padding({
+      top: 24,
+    })
+  }
+}

+ 70 - 0
features/feature/src/main/ets/components/YtDatePicker.ets

@@ -0,0 +1,70 @@
+
+// 日期选择器
+@ComponentV2
+export struct YtDatePicker{
+  @Once @Param selectedDate: Date = new Date();
+
+  @Param linearInfo: LinearGradientOptions = {
+    colors: [['#ACF4EB', 0.01], ['#D3F9FF', 0.2] ],
+    angle: 150
+  }
+
+  @Event selectDateBack: (date: Date) => void = (date: Date) => {
+    console.log("选择的日期" + date.toLocaleString())
+  }
+
+  build() {
+    Column({space: 15}){
+      Row(){
+        Text("今天")
+          .fontSize(18)
+          .fontWeight(700)
+          .onClick(() => {
+            this.selectedDate = new Date()
+          })
+        Text("确认")
+          .fontSize(16)
+          .fontWeight(500)
+          .borderRadius(32)
+          .linearGradient(this.linearInfo)
+          .padding({ left: 16, right: 16, top: 4, bottom: 4})
+          .onClick(() => {
+            this.selectDateBack(this.selectedDate)
+          })
+      }
+      .width("100%")
+      .justifyContent(FlexAlign.SpaceBetween)
+      .padding({ left: 16, right: 16, top: 16, bottom: 16})
+
+
+      Stack({alignContent: Alignment.Center}){
+        Row()
+          .width("100%")
+          .height(55)
+          .borderRadius(8)
+          .linearGradient(this.linearInfo)
+
+        DatePicker({
+          end: new Date(),
+          selected: this.selectedDate,
+        })
+          .selectedTextStyle({
+            color: Color.Black,
+          })
+          .onDateChange((date: Date) => {
+            this.selectedDate = date
+          })
+      }
+      .padding({ left: 13, right: 13})
+    }
+    .width("100%")
+    .borderRadius(12)
+    .padding({ top: 20, bottom: 20 })
+    .backgroundColor(Color.White)
+    .shadow({
+      radius: 10,
+      type: ShadowType.COLOR,
+      color: Color.Black
+    })
+  }
+}

+ 58 - 0
features/feature/src/main/ets/components/_YtHeader.ets

@@ -0,0 +1,58 @@
+@ComponentV2
+export struct _YtHeader {
+  @Param isShowBackComp: boolean = true
+  @Param @Require title: string
+  @Param _h: Length = 54
+
+  @BuilderParam rightComp: () => void
+  @BuilderParam leftComp: () => void
+
+  @Event _onBackPress: () => void = () => {  }
+  @Event _onClickTitle: () => void = () => {}
+  @Event _onClickRightComp: () => void = () => {}
+
+  build() {
+      RelativeContainer() {
+        Row(){
+          if(this.isShowBackComp) {
+            Image($r('[basic].media.ic_back'))
+              .width(24)
+              .aspectRatio(1)
+              .onClick(this._onBackPress)
+          } else if(this.leftComp) {
+            this.leftComp()
+          } else {
+            Text()
+          }
+
+
+          Row(){
+            if(this.rightComp) {
+              this.rightComp()
+            }
+          }
+          .onClick(this._onClickRightComp)
+        }
+        .id('back_icon')
+        .width("100%")
+        .alignItems(VerticalAlign.Center)
+        .justifyContent(FlexAlign.SpaceBetween)
+        .alignRules({
+          top: { anchor: "__container__", align: VerticalAlign.Top},
+          left: { anchor: "__container__", align: HorizontalAlign.Start}
+        })
+
+        Text(this.title)
+          .fontSize(20)
+          .fontWeight(500)
+          .alignRules({
+            center: { anchor: "back_icon", align: VerticalAlign.Center},
+            middle: { anchor: "back_icon", align: HorizontalAlign.Center}
+          })
+          .onClick(this._onClickTitle)
+      }
+      .width("100%")
+      .height(this._h)
+      .padding({top: 12, bottom: 12})
+  }
+}

+ 70 - 0
features/feature/src/main/ets/components/ytBuildComp.ets

@@ -0,0 +1,70 @@
+import { EmitterKeyCollection, UserInfo, userInfo, yTRouter } from "basic"
+import { emitter } from "@kit.BasicServicesKit"
+import { AppStorageV2 } from "@kit.ArkUI"
+
+@ComponentV2
+export struct ytBuildComp {
+  @BuilderParam main: () => void
+
+  @Local isLogin: boolean = false
+  // 用户信息
+  @Local userInfo: UserInfo = AppStorageV2.connect<UserInfo>(UserInfo, 'UserInfo', () => userInfo)!
+
+  toLogin = () => {
+    yTRouter.router2LoginPage(false)
+  }
+
+  aboutToAppear(): void {
+    emitter.on(EmitterKeyCollection.LOGIN, () => {
+      this.isLogin = true
+    })
+    emitter.on(EmitterKeyCollection.LOGOUT, () => {
+      this.isLogin = false
+    })
+    this.isLogin = this.userInfo.checkLogin()
+  }
+
+  build() {
+    RelativeContainer(){
+      Column(){
+        this.main()
+      }
+      .width("100%")
+      .height("100%")
+      .alignRules({
+        top: { anchor: "__container__", align: VerticalAlign.Top},
+        left: { anchor: "__container__", align: HorizontalAlign.Start},
+      })
+
+      if(!this.isLogin){
+        Row() {
+          Text("登录使用更多功能")
+            .fontSize(20)
+            .fontWeight(400)
+            .fontColor(Color.White)
+
+          Text("马上登录")
+            .fontSize(14)
+            .fontWeight(500)
+            .borderRadius(20)
+            .padding({ top: 5, bottom: 5, left: 10, right: 10 })
+            .linearGradient({
+              colors: [['#30E3CE', 0.5], ['#91F1FF', 1]]
+            })
+            .onClick(this.toLogin)
+        }
+        .width("100%")
+        .alignItems(VerticalAlign.Center)
+        .justifyContent(FlexAlign.SpaceBetween)
+        .padding({ left: 20, right: 20, top:  18, bottom: 18 })
+        .backgroundColor('rgba(0, 0, 0, 0.5)')
+        .alignRules({
+          bottom: { anchor: "__container__", align: VerticalAlign.Bottom},
+          left: { anchor: "__container__", align: HorizontalAlign.Start},
+        })
+      }
+    }
+    .width("100%")
+    .height("100%")
+  }
+}

+ 9 - 35
features/feature/src/main/ets/pages/YTNaviDiaLog.ets

@@ -1,18 +1,21 @@
-import { BasicType, yTRouter } from 'basic'
+import { yTRouter } from 'basic'
 import { YTDiaLogComp } from 'basic/src/main/ets/components/generalComp/YTDiaLogComp'
 import { DiaLogParam, YTDiaLogModel } from 'basic/src/main/ets/models/YTDiaLogModel'
+import { getBuilder } from '../components/YTDiaLogBuild'
 
 @ComponentV2
 struct YTNaviDiaLog {
   @Local param: DiaLogParam = {} as DiaLogParam
   @Local isPop: boolean = false
-  @Local routerAns: string = ''
+  @Local routerAns?: string
 
   _onBackPress = () => {
-    yTRouter.pop(this.routerAns, false)
+    if(this.routerAns) yTRouter.pop(this.routerAns, true)
+    else yTRouter.pop(false)
   }
 
-  onBack(){
+  onBack = (ans?: string) =>{
+    this.routerAns = ans
     this.isPop = !this.isPop
   }
 
@@ -21,39 +24,10 @@ struct YTNaviDiaLog {
   }
 
   build() {
-    YTDiaLogComp({ Align: YTDiaLogModel.Bottom, _onPop: this._onBackPress, isBack: this.isPop }){
-      this.BottomMenu()
+    YTDiaLogComp({ Align: this.param.align ?? YTDiaLogModel.Bottom, _onPop: this._onBackPress, isBack: this.isPop }){
+      getBuilder(this.param, this.onBack)
     }
   }
-
-  // 底部菜单
-  @Builder BottomMenu() {
-    Column(){
-      ForEach(this.param.params, (item: BasicType, index) => {
-        Row(){
-          Text(item.text)
-            .fontSize(16)
-            .textAlign(TextAlign.Center)
-        }
-        .width("100%")
-        .alignItems(VerticalAlign.Center)
-        .justifyContent(FlexAlign.Center)
-        .padding({ top: 24, bottom: 24 })
-        .onClick(() => {
-          this.routerAns = item.message ?? item.text ?? `${index}`
-          this.onBack()
-        })
-
-        Divider().width("80%").height(1).backgroundColor('#000000F2')
-      })
-    }
-    .width("100%")
-    .padding({ bottom: 30 })
-    .backgroundColor(Color.White)
-    .justifyContent(FlexAlign.Center)
-    .alignItems(HorizontalAlign.Center)
-    .borderRadius({ topLeft: 8, topRight: 8 })
-  }
 }
 
 @Builder

+ 111 - 46
features/feature/src/main/ets/view/MainView.ets

@@ -1,59 +1,124 @@
-import { BackgroundPageModifier, DateOption, YTAddressSelectorDialog, YTDateUtil } from 'basic'
-import { UnitType } from 'basic/src/main/ets/datepicker/DatePickerEnums'
-import { promptAction } from '@kit.ArkUI'
+import { ytBuildComp } from "../components/ytBuildComp"
 
-@Component
+@ComponentV2
 export struct MainView {
+  aboutToAppear(): void {
+  }
+
   build() {
-    Column() {
-      Text('打开日历')
-        .onClick(() => {
-          //以下内容都可以不传 有默认值
-          const date: Date = new Date()
-          const yTDateDialog = new YTAddressSelectorDialog(this.getUIContext())
-          let dateOption = new DateOption() //选项配置类
-          dateOption.date = date //当前日期  默认今天
-          dateOption.minDate = new Date(2000, 0, 1) //最小选择的日期 默认10年前的今天
-          dateOption.maxDate = new Date(2048, 12, 30) //最大选择的日期 默认10年后的今天
-          dateOption.unitType = UnitType.YEAR_MONTH_DAY //日期单位 默认年月日 可选年月、月日等组合
-          dateOption.confirm = (date: Date) => { //确认选择回调函数
-            console.log('确认', YTDateUtil.formatDate(date))
-            promptAction.openToast({ message: YTDateUtil.formatDate(date) })
+    ytBuildComp(){
+      Column(){
+        // title - 标题
+        RelativeContainer(){
+          Row({ space: 5 }){
+            Text( '无')
+              .fontSize(20)
+              .fontWeight(500)
+            Image($r('app.media.icon_BottomOpen'))
+              .width(18)
+              .height(9)
           }
-          dateOption.headerLeftBuilder = wrapBuilder(headerLeftBuilder) //头部左侧按钮 默认返回按钮
-          dateOption.headerRightBuilder = wrapBuilder(headerLeftBuilder) //头部右侧按钮 默认确认按钮
-          dateOption.highlightBackgroundColor = Color.Pink //选中高亮背景色
-          dateOption.highlightBorderColor = Color.Red //选中高亮边框色
-          dateOption.textStyle = {
-            //日期文字样式
-            font: { size: 20, weight: 400 },
-            color: Color.Gray
+          .bindMenu(this._Menu)
+          .alignRules({
+            top: { anchor: "__container__", align: VerticalAlign.Top},
+            middle: { anchor: "__container__", align: HorizontalAlign.Center}
+          })
+
+       }
+        .height(40)
+        .width("100%")
+
+        // avatar-Card - 头像卡片
+        RelativeContainer(){
+          // 文字描述
+          Text() {
+            Span("宝宝")
+
+            Span('0')
+              .fontWeight(700)
+              .fontColor(Color.Red)
+
+            Span("了")
           }
-          dateOption.selectedTextStyle = {
-            //选中日期文字样式
-            font: { size: 25, weight: 400 },
-            color: Color.Yellow
+          .fontSize(20)
+          .fontWeight(400)
+          .fontColor(Color.Black)
+          .alignRules({
+            middle: { anchor: "__container__", align: HorizontalAlign.Center},
+            center: { anchor: "__container__", align: VerticalAlign.Center}
+          })
+
+          /**
+           * 编辑宝宝信息按钮
+           * 如果是亲友团宝宝,则不可进行编辑
+           */
+          Image($r('app.media.icon_edit'))
+            .width(20)
+            .aspectRatio(1)
+            .onClick(() => {  })
+            .alignRules({
+              center: { anchor: "__container__", align: VerticalAlign.Center},
+              right: { anchor: "__container__", align: HorizontalAlign.End}
+            })
+
+
+
+          // 头像
+          Row(){
+            Image($r('[basic].media.default_avatar'))
+              .width(54)
+              .borderRadius(36)
+              .aspectRatio(1)
           }
-          yTDateDialog.show(dateOption) //设置好配置之后打开日历的函数
+          .width(70)
+          .aspectRatio(1)
+          .borderRadius(36)
+          .backgroundColor('#AAE5E2')
+          .alignItems(VerticalAlign.Center)
+          .justifyContent(FlexAlign.Center)
+          .alignRules({
+            left: { anchor: "__container__", align: HorizontalAlign.Start},
+            bottom: { anchor: "__container__", align: VerticalAlign.Center}
+          })
+        }
+        .height(120)
+        .width("100%")
+        .borderRadius(12)
+        .padding({ left: 17, right: 17 })
+        .border({ width: 1, color: '#30E3CE8C' })
+        .linearGradient({
+          colors: [ ['#ABF5EC', 0.01], ['#FFFFFF', 0.8]],
+          angle: 270
         })
 
-      Image('https://hm-static.ytpm.net/upload/20250821/处暑-1755757002591.jpg')
-        .width('100%')
-        .height(300)
+      }
+      .width("100%")
+      .height("100%")
+      .padding({ top: 12, left: 16, right: 16 })
+      .linearGradient({
+        colors: [ ['#30E3CE', 0.01], ['#91F1FF', 0.03], ['#F1F1F1', 0.3] ],
+        angle: 200
+      })
     }
-    .attributeModifier(new BackgroundPageModifier(true))
-
   }
-}
 
-@Builder
-function headerLeftBuilder() {
-  Image($r('app.media.app_icon'))
-    .width(24)
+  // 菜单结构
+  @Builder _Menu(){
+    Menu() {
+      // ForEach(this.vm.babyList, (item: BabyInfoList, index: number) => {
+      //   MenuItem({ content: item.developmentBabyInfo?.name ?? '无' })
+      //     .onClick(() => { this.vm.updateBabyInfo(index) })
+      // }, (item: BabyInfoList) => item.developmentBabyInfo?.id)
+
+      MenuItem({ content: '添加宝宝' })
+        .onClick(() => {
+          // if(this.vm.userInfo.checkLogin()){
+          //   this.vm.goToAddBaby()
+          // } else {
+          //   yTRouter.router2LoginPage(true)
+          // }
+        })
+    }
+  }
 }
 
-@Builder
-function headerRightBuilder() {
-  Image($r("app.media.app_icon"))
-    .width(24)
-}

+ 1 - 0
features/feature/src/main/resources/base/media/icon_BottomOpen.svg

@@ -0,0 +1 @@
+<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1756712543410" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="4394" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M80 288c0 10.88 3.84 22.4 11.52 31.36l384 448c8.96 10.88 22.4 16.64 36.48 16.64s27.52-6.4 36.48-16.64l384-448c17.28-19.84 14.72-50.56-5.12-67.84s-50.56-14.72-67.84 5.12L512 662.4 164.48 256.64a48.384 48.384 0 0 0-67.84-5.12c-10.88 9.6-16.64 23.04-16.64 36.48z" p-id="4395"></path></svg>

+ 1 - 0
features/feature/src/main/resources/base/media/icon_delback.svg

@@ -0,0 +1 @@
+<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1757054455372" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="6252" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M610.133333 520.533333l106.666667-106.666666c4.266667-4.266667 8.533333-17.066667 0-21.333334-4.266667-4.266667-17.066667-4.266667-21.333333 0l-106.666667 106.666667-106.666667-106.666667c-4.266667-4.266667-17.066667-8.533333-21.333333 0-4.266667 4.266667-8.533333 17.066667 0 21.333334l106.666667 106.666666-106.666667 106.666667c-4.266667 4.266667-8.533333 17.066667 0 21.333333 4.266667 4.266667 17.066667 4.266667 21.333333 0l106.666667-106.666666 106.666667 106.666666c4.266667 4.266667 17.066667 8.533333 21.333333 0 4.266667-4.266667 8.533333-17.066667 0-21.333333l-106.666667-106.666667z m-452.266666 12.8c-12.8-12.8-12.8-34.133333 0-46.933333L384 260.266667c8.533333-4.266667 21.333333-12.8 29.866667-12.8h362.666666c55.466667 0 98.133333 42.666667 98.133334 98.133333v328.533333c0 55.466667-42.666667 98.133333-98.133334 98.133334H413.866667c-8.533333 0-21.333333-4.266667-29.866667-12.8l-226.133333-226.133334z m0 0" p-id="6253"></path></svg>

BIN
features/feature/src/main/resources/base/media/icon_edit.png


+ 36 - 35
products/entry/src/main/ets/pages/Index.ets

@@ -39,46 +39,47 @@ struct Index {
   build() {
     Navigation(yTRouter) {
       Column() {
-        Tabs({ controller: this.tabsController }) {
-          ForEach(this.contentList, (_: BasicType<undefined>, index) => {
-            TabContent() {
-              if (index == 0) {
-                //放对应组件
-                MainView()
-              } else if (index == 1) {
-                SecondView()
-              } else if (index == 2) {
-                ThirdView()
-              } else {
-                Mine()
-              }
-            }
-          })
-        }
-        .onChange((index) => {
-          this.currentIndex = index
-        })
-        .barHeight(0)
-        .layoutWeight(1)
-        .scrollable(false)
+        // Tabs({ controller: this.tabsController }) {
+        //   ForEach(this.contentList, (_: BasicType<undefined>, index) => {
+        //     TabContent() {
+        //       if (index == 0) {
+        //         //放对应组件
+        //         MainView()
+        //       } else if (index == 1) {
+        //         SecondView()
+        //       } else if (index == 2) {
+        //         ThirdView()
+        //       } else {
+        //         Mine()
+        //       }
+        //     }
+        //   })
+        // }
+        // .onChange((index) => {
+        //   this.currentIndex = index
+        // })
+        // .barHeight(0)
+        // .layoutWeight(1)
+        // .scrollable(false)
 
-        Row() {
-          ForEach(this.contentList, (item: BasicType<undefined>, index) => {
-            this.barBuilder((() => {
-              item.index = index
-              return item
-            })())
-          })
-        }
-        .justifyContent(FlexAlign.SpaceAround)
-        .width('100%')
-        .padding({ bottom: this.bottom })
-        .shadow({ offsetY: -13, radius: 16, color: '#0A000000' })
+        // Row() {
+        //   ForEach(this.contentList, (item: BasicType<undefined>, index) => {
+        //     this.barBuilder((() => {
+        //       item.index = index
+        //       return item
+        //     })())
+        //   })
+        // }
+        // .justifyContent(FlexAlign.SpaceAround)
+        // .width('100%')
+        // .padding({ bottom: this.bottom })
+        // .shadow({ offsetY: -13, radius: 16, color: '#0A000000' })
+
+        MainView()
       }
       .width('100%')
       .height('100%')
       .backgroundColor(Color.White)
-
     }
     .mode(NavigationMode.Stack)
     .hideToolBar(true)