Bläddra i källkod

feat: 完成座位页面下的 静态UI 和 相对应的交互逻辑。

YuJing 1 månad sedan
förälder
incheckning
846db0d536

+ 6 - 3
commons/basic/src/main/ets/models/YTDiaLogModel.ets

@@ -17,11 +17,14 @@ export enum DiaLogPageEnum{
   Confirm,
   // 底部菜单
   BottomMenu,
+
+  // 添加座位表
+  AddSeatTable,
 }
 
-export interface DiaLogParam{
+export interface DiaLogParam<T = ESObject>{
   pageEnum: DiaLogPageEnum,
   align?: YTDiaLogModel,
-  param?: BasicType,
-  params?: Array<BasicType>
+  param?: BasicType<T>,
+  params?: Array<BasicType<T>>
 }

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

@@ -122,14 +122,14 @@ class YTRouter extends NavPathStack {
   }
 
   /**
-   * 事件选择器弹窗
-   * @param param date 作为默认选中的时间
+   * 时间选择器弹窗
+   * @param param date 作为默认选中的时间 YY-MM-DD 形式
    * @param back 返回选中的时间  YY-MM-DD 形式
    */
-  router2EventPickerDiaLog(param: BasicType, back?: Callback<PopInfo>){
+  router2DatePickerDiaLog(date: string, color: ResourceColor, back?: Callback<PopInfo>){
     let p: DiaLogParam = {
       pageEnum: DiaLogPageEnum.DatePicker,
-      param: param,
+      param: { date: date, color: color },
       align: YTDiaLogModel.Bottom
     }
     this.router2NaviDiaLog(p, back)

+ 133 - 2
features/feature/src/main/ets/components/YtComp/YTDiaLogBuild.ets

@@ -1,5 +1,6 @@
-import { BasicType, IBestToast } from 'basic'
+import { BasicType, DateFormat, IBestToast, YTDateUtil, yTRouter } from 'basic'
 import { DiaLogPageEnum, DiaLogParam } from 'basic/src/main/ets/models/YTDiaLogModel'
+import { AddSeatTablePageModel } from '../../model/RouterModel'
 import { NumberKeyBoard, NumberKeyBoardStyle } from './NumberKeyboard'
 import { YtDatePicker } from './YtDatePicker'
 import { _YtHeader } from './_YtHeader'
@@ -14,6 +15,8 @@ export function getBuilder(param: DiaLogParam, onBack: (ans?: string) => void){
   else if (param.pageEnum == DiaLogPageEnum.TextInput) InputComp({onBack: onBack, param: param.param})
 
   /********  额外的   ***********/
+  else if (param.pageEnum == DiaLogPageEnum.AddSeatTable) AddSeatTableComp({onBack: onBack, param: param.param})
+
 }
 
 // 底部菜单
@@ -61,7 +64,7 @@ function DatePickerBuilder(onBack: (ans?:string) => void, param?: BasicType){
     onBack(result)
   },
     selectedDate: param?.date ? new Date(param.date) : new Date(),
-    linearInfo: { colors: [['#95C50A', 1]] },
+    linearInfo: { colors: [[param?.color ?? '#95C50A', 1]] },
     needCancel: true
   })
 }
@@ -268,6 +271,134 @@ struct InputComp{
   }
 }
 
+// 添加座位表
+@ComponentV2
+struct AddSeatTableComp{
+  @Event onBack: (ans?:string) => void
+  @Param @Require param: BasicType<AddSeatTablePageModel>
+
+  // 选择开始时间
+  @Local startTime: string = ''
+  @Local endTime: string = ''
+  @Local name: string = ''
+
+  selectTime(isStart: boolean = true){
+    yTRouter.router2DatePickerDiaLog(isStart ? this.startTime : this.endTime, '#7186F9', (res)=>{
+      let date = res.result as string
+      if(date) {
+        if(isStart) {
+          this.startTime = date
+        } else {
+          this.endTime = date
+        }
+      }
+    })
+  }
+
+  aboutToAppear(): void {
+    let now = YTDateUtil.formatDate(new Date(), DateFormat.UNDERLINE)
+    this.startTime = this.param.generics?.startDate ?? now
+    this.endTime = this.param.generics?.endDate ?? now
+    this.name = this.param.generics?.name ?? ''
+  }
+
+  build() {
+    Column({space: 30}) {
+      Text('添加座位表')
+        .fontColor(Color.Black)
+        .fontSize(20)
+        .lineHeight(18)
+        .fontWeight(500)
+        .textAlign(TextAlign.Center)
+
+      Column({space: 15}){
+        Row({space: 25}){
+          Text('名  称')
+            .fontSize(18)
+            .fontWeight(500)
+
+          TextInput({placeholder: '请输入座位表名称', text: $$this.name})
+            .padding(0)
+            .layoutWeight(1)
+            .borderRadius(0)
+            .backgroundColor(Color.Transparent)
+            .border({ width: {bottom: 1.5}, color: '#ECECEC' })
+        }
+        .width("100%")
+        .padding({right: 15})
+        .justifyContent(FlexAlign.SpaceBetween)
+
+        Row({space: 25}){
+          Text('日  期')
+            .fontSize(18)
+            .fontWeight(500)
+
+          Row(){
+            Text(this.startTime)
+              .borderRadius(8)
+              .border({width: 1, color: '#ECECEC'})
+              .padding({left: 9, top: 5, right: 9, bottom: 5})
+              .onClick(() => { this.selectTime(true) })
+
+            Divider()
+              .width(13)
+              .height(1.5)
+              .backgroundColor(this.param.color)
+
+            Text(this.endTime)
+              .borderRadius(8)
+              .border({width: 1, color: '#ECECEC'})
+              .padding({left: 9, top: 5, right: 9, bottom: 5})
+              .onClick(() => { this.selectTime(false) })
+          }
+          .alignItems(VerticalAlign.Center)
+          .layoutWeight(1)
+        }
+        .width("100%")
+        .justifyContent(FlexAlign.SpaceBetween)
+      }
+
+      // 确定 和 取消
+      Row() {
+        Text('取消')
+          .fontSize(16)
+          .fontWeight(400)
+          .borderRadius(this.param?.number ?? 36)
+          .fontColor(Color.Black)
+          .backgroundColor('#F5F5F7')
+          .padding({ left: 36, top: 9, right: 36, bottom: 9})
+          .onClick(() => {
+            this.onBack()
+          })
+
+        Text('确定')
+          .fontSize(16)
+          .fontWeight(400)
+          .borderRadius(this.param?.number ?? 36)
+          .fontColor(Color.Black)
+          .padding({ left: 36, top: 9, right: 36, bottom: 9})
+          .linearGradient({
+            colors: [ this.param?.color ? [this.param.color, 1 ] : ['#30E3CE', 0.4], ['#91F1FF', 0.8] ],
+            angle: 200
+          })
+          .onClick(() => {
+            let ans: AddSeatTablePageModel = {
+              name: this.name,
+              startDate: this.startTime,
+              endDate: this.endTime
+            }
+            this.onBack(JSON.stringify(ans))
+          })
+      }
+      .justifyContent(FlexAlign.SpaceBetween)
+      .width('100%')
+    }
+    .width(335)
+    .padding(16)
+    .borderRadius(8)
+    .backgroundColor(Color.White)
+  }
+}
 
 
 

+ 8 - 0
features/feature/src/main/ets/model/RouterModel.ets

@@ -1,3 +1,11 @@
+// 添加学生信息页面参数
 export interface IncreaseStudentPageModel{
   id?: string
+}
+
+// 添加座位表弹窗参数
+export interface AddSeatTablePageModel{
+  name?: string
+  startDate?: string
+  endDate?: string
 }

+ 14 - 2
features/feature/src/main/ets/utils/RouterUtils.ets

@@ -1,5 +1,6 @@
-import { yTRouter } from "basic"
-import { IncreaseStudentPageModel } from "../model/RouterModel"
+import { BasicType, yTRouter } from "basic"
+import { DiaLogPageEnum, DiaLogParam, YTDiaLogModel } from "basic/src/main/ets/models/YTDiaLogModel"
+import { AddSeatTablePageModel, IncreaseStudentPageModel } from "../model/RouterModel"
 
 class RouterUtils{
   router2MainPage(param: ESObject, back: Callback<PopInfo>){
@@ -18,6 +19,17 @@ class RouterUtils{
   getIncreaseStudentPageParam(): IncreaseStudentPageModel{
     return yTRouter.getParamByName('IncreaseStudentPage').pop() as IncreaseStudentPageModel
   }
+
+  // DiaLog
+  // 添加座位表弹窗
+  router2AddSeatTableDialog(param: BasicType<AddSeatTablePageModel>, back: Callback<PopInfo>){
+    let p: DiaLogParam<AddSeatTablePageModel> = {
+      pageEnum: DiaLogPageEnum.AddSeatTable,
+      param: param,
+      align: YTDiaLogModel.Center
+    }
+    yTRouter.router2NaviDiaLog(p, back)
+  }
 }
 
 export const iRouter = new RouterUtils()

+ 84 - 196
features/feature/src/main/ets/view/SecondView.ets

@@ -1,214 +1,102 @@
-import { textToSpeech } from '@kit.CoreSpeechKit';
-import { BusinessError } from '@kit.BasicServicesKit';
+import { EmptyComp } from "../components/EmptyComp"
+import { SecondViewModel } from "../viewModel/SecondViewModel"
 
-let ttsEngine: textToSpeech.TextToSpeechEngine;
-
-
-@Component
+@ComponentV2
 export struct SecondView {
-  @State createCount: number = 0;
-  @State voiceInfo: string = "";
-  @State originalText: string = "支付宝到账[n2]1000000元";
+  @Local vm:SecondViewModel = new SecondViewModel()
 
   build() {
-    Column() {
-      Scroll() {
-        Column() {
-          TextArea({ placeholder: 'Please enter tts original text', text: `${this.originalText}` })
-            .margin(20)
-            .border({
-              width: 5,
-              color: 0x317AE7,
-              radius: 10,
-              style: BorderStyle.Solid
-            })
-            .onChange((value: string) => {
-              this.originalText = value;
-              console.info(`original text: ${this.originalText}`);
-            })
-          Button() {
-            Text("CreateEngineByCallback")
-              .fontColor(Color.White)
-              .fontSize(20)
-          }
-          .type(ButtonType.Capsule)
-          .backgroundColor("#0x317AE7")
-          .width("80%")
-          .height(50)
-          .margin(10)
-          .onClick(() => {
-            this.createCount++;
-            console.info(`CreateTtsEngine:createCount:${this.createCount}`);
-            this.createByCallback();
-          })
-
-          Button() {
-            Text("speak")
-              .fontColor(Color.White)
-              .fontSize(20)
-          }
-          .type(ButtonType.Capsule)
-          .backgroundColor("#0x317AE7")
-          .width("80%")
-          .height(50)
-          .margin(10)
-          .onClick(() => {
-            this.createCount++;
-            this.speak();
-          })
-
-          Button() {
-            Text("listVoicesCallback")
-              .fontColor(Color.White)
-              .fontSize(20)
-          }
-          .type(ButtonType.Capsule)
-          .backgroundColor("#0x317AE7")
-          .width("80%")
-          .height(50)
-          .margin(10)
-          .onClick(() => {
-            this.listVoicesCallback();
-          })
+    Column(){
+      Row(){
+        Text('座位表')
+          .fontSize(24)
+          .fontWeight(600)
+          .fontColor('#333333')
+        Text('添加')
+          .fontSize(18)
+          .fontWeight(500)
+          .borderRadius(8)
+          .fontColor(Color.White)
+          .backgroundColor(Color.Black)
+          .padding({left: 15, top: 7, right: 15, bottom: 7})
+          .onClick(() => { this.vm._onAddSeatTable() })
+      }
+      .width("100%")
+      .justifyContent(FlexAlign.SpaceBetween)
 
-          Button() {
-            Text("stop")
-              .fontColor(Color.White)
-              .fontSize(20)
-          }
-          .type(ButtonType.Capsule)
-          .backgroundColor("#0x317AE7")
-          .width("80%")
-          .height(50)
-          .margin(10)
-          .onClick(() => {
-            // 停止播报
-            console.info("Stop button clicked.");
-            ttsEngine.stop();
-          })
+      Column(){
+        EmptyComp({ isEmpty: this.vm.dataSource.length == 0 }){
+          List({space: 16}){
+            ForEach(this.vm.dataSource, (item: string, index) => {
+              ListItem(){
+                Column({space: 5}){
+                  Text(item)
+                    .fontSize(20)
+                    .fontWeight(500)
 
-          Button() {
-            Text("isBusy")
-              .fontColor(Color.White)
-              .fontSize(20)
-          }
-          .type(ButtonType.Capsule)
-          .backgroundColor("#0x317AE7")
-          .width("80%")
-          .height(50)
-          .margin(10)
-          .onClick(() => {
-            // 查询播报状态
-            let isBusy = ttsEngine.isBusy();
-            console.info(`isBusy: ${isBusy}`);
-          })
-
-          Button() {
-            Text("shutdown")
-              .fontColor(Color.White)
-              .fontSize(20)
+                  Text('2025.11.10-2025.9-19')
+                    .fontSize(14)
+                    .fontColor('#666666')
+                }
+                .width("97%")
+                .borderRadius(15)
+                .margin({left: 3})
+                .justifyContent(FlexAlign.Start)
+                .alignItems(HorizontalAlign.Start)
+                .backgroundImageSize(ImageSize.Cover)
+                .backgroundImage($r('app.media.seatBg'))
+                .shadow({ radius: 6, color: '#1a000000' })
+                .padding({left: 12, top: 20, right: 12, bottom: 20})
+              }
+              .align(Alignment.Center)
+              .swipeAction({
+                end: () => { this.swiperAction(index) }
+              })
+            })
           }
-          .type(ButtonType.Capsule)
-          .backgroundColor("#0x317AA7")
-          .width("80%")
-          .height(50)
-          .margin(10)
-          .onClick(() => {
-            // 释放引擎
-            ttsEngine.shutdown();
-          })
+          .width("100%")
+          .height("100%")
+          .padding({top: 16, bottom: 16})
+          .scrollBar(BarState.Off)
         }
-        .layoutWeight(1)
       }
       .width('100%')
-      .height('100%')
+      .layoutWeight(1)
     }
+    .width('100%')
+    .height('100%')
+    .alignItems(HorizontalAlign.Center)
+    .justifyContent(FlexAlign.Start)
+    .padding({top: this.vm.safeTop, left: 16, right: 16})
   }
 
-  // 创建引擎,通过callback形式返回
-  private createByCallback() {
-    // 设置创建引擎参数
-    let extraParam: Record<string, Object> = { "style": 'interaction-broadcast', "locate": 'CN', "name": 'EngineName' };
-    let initParamsInfo: textToSpeech.CreateEngineParams = {
-      language: 'zh-CN',
-      person: 0,
-      online: 1,
-      extraParams: extraParam
-    };
-    // 调用createEngine方法
-    textToSpeech.createEngine(initParamsInfo,
-      (err: BusinessError, textToSpeechEngine: textToSpeech.TextToSpeechEngine) => {
-        if (!err) {
-          console.info('Succeeded in creating engine.');
-          // 接收创建引擎的实例
-          ttsEngine = textToSpeechEngine;
-        } else {
-          console.error(`Failed to create engine. Code: ${err.code}, message: ${err.message}.`);
-        }
-      });
-  };
+  @Builder
+  swiperAction(index: number){
+    Row(){
+      Row(){
+        Image($r('app.media.icon_edit'))
+          .width(25)
+          .aspectRatio(1)
+      }
+      .backgroundColor('#BFBFBF')
+      .alignItems(VerticalAlign.Center)
+      .justifyContent(FlexAlign.Center)
+      .padding({ left: 18, top: 30, right: 18, bottom: 30 })
+      .onClick(() => { this.vm._onEditSeatTable() })
 
-  // 调用speak播报方法
-  private speak() {
-    let speakListener: textToSpeech.SpeakListener = {
-      // 开始播报回调
-      onStart(requestId: string, response: textToSpeech.StartResponse) {
-        console.info(`onStart, requestId: ${requestId} response: ${JSON.stringify(response)}`);
-      },
-      // 完成播报回调
-      onComplete(requestId: string, response: textToSpeech.CompleteResponse) {
-        console.info(`onComplete, requestId: ${requestId} response: ${JSON.stringify(response)}`);
-      },
-      // 停止播报完成回调,调用stop方法并完成时会触发此回调
-      onStop(requestId: string, response: textToSpeech.StopResponse) {
-        console.info(`onStop, requestId: ${requestId} response: ${JSON.stringify(response)}`);
-      },
-      // 返回音频流
-      onData(requestId: string, audio: ArrayBuffer, response: textToSpeech.SynthesisResponse) {
-        console.info(`onData, requestId: ${requestId} sequence: ${JSON.stringify(response)} audio: ${JSON.stringify(audio)}`);
-      },
-      // 错误回调,播报过程发生错误时触发此回调
-      onError(requestId: string, errorCode: number, errorMessage: string) {
-        console.error(`onError, requestId: ${requestId} errorCode: ${errorCode} errorMessage: ${errorMessage}`);
+      Row(){
+        Image($r('app.media.icon_del'))
+          .width(25)
+          .aspectRatio(1)
       }
-    };
-    // 设置回调
-    ttsEngine.setListener(speakListener);
-    // 设置播报相关参数
-    let extraParam: Record<string, Object> = {
-      "queueMode": 0,
-      "speed": 1,
-      "volume": 2,
-      "pitch": 1,
-      "languageContext": 'zh-CN',
-      "audioType": "pcm",
-      "soundChannel": 3,
-      "playType": 1
+      .backgroundColor('#FF3B30')
+      .alignItems(VerticalAlign.Center)
+      .justifyContent(FlexAlign.Center)
+      .borderRadius({topRight: 15, bottomRight: 15})
+      .padding({ left: 18, top: 30, right: 18, bottom: 30 })
+      .onClick(() => { this.vm._onDeleteSeatTable() })
     }
-    let speakParams: textToSpeech.SpeakParams = {
-      requestId: '123456-a', // requestId在同一实例内仅能用一次,请勿重复设置
-      extraParams: extraParam
-    };
-    // 调用speak播报方法
-    ttsEngine.speak(this.originalText, speakParams);
-  };
+    .borderRadius({topRight: 15, bottomRight: 15})
+  }
 
-  // 查询语种音色信息,以callback形式返回
-  private listVoicesCallback() {
-    // 设置查询相关参数
-    let voicesQuery: textToSpeech.VoiceQuery = {
-      requestId: '123456-b', // requestId在同一实例内仅能用一次,请勿重复设置
-      online: 1
-    };
-    // 调用listVoices方法,以callback返回语种音色查询结果
-    ttsEngine.listVoices(voicesQuery, (err: BusinessError, voiceInfo: textToSpeech.VoiceInfo[]) => {
-      if (!err) {
-        // 接收目前支持的语种音色等信息
-        this.voiceInfo = JSON.stringify(voiceInfo);
-        console.info(`Succeeded in listing voices, voiceInfo is ${voiceInfo}`);
-      } else {
-        console.error(`Failed to list voices. Code: ${err.code}, message: ${err.message}`);
-      }
-    });
-  };
 }

+ 50 - 0
features/feature/src/main/ets/viewModel/SecondViewModel.ets

@@ -0,0 +1,50 @@
+import { YTAvoid, yTRouter } from "basic"
+import { iRouter } from "../utils/RouterUtils"
+
+@ObservedV2
+export class SecondViewModel{
+
+  @Trace safeTop: number = 0
+  @Trace dataSource: string[] = new Array(15).fill('第二次月考座位表')
+
+  constructor() {
+    this.safeTop = AppStorage.get(YTAvoid.SAFE_TOP_KEY) as number
+  }
+
+  // 添加座位表
+  _onAddSeatTable() {}
+
+  // 删除
+  _onDeleteSeatTable() {
+    yTRouter.router2DoubleConfirmDiaLog({
+      text: '是否确认删除?',
+      color: '#7186F9'
+    }, (res) => {
+      if (res?.result && res.result == 'true') {
+
+      }
+    })
+  }
+
+  // 编辑
+  _onEditSeatTable() {
+    iRouter.router2AddSeatTableDialog({
+      color: '#5668FC',
+      generics: {
+        name: '座位表1',
+        startDate: '2025.11.10',
+        endDate: '2025.9.19'
+      }
+    }, () => {
+
+    })
+  }
+  /**
+   * 重写的返回逻辑
+   * @returns
+   */
+  _onBackPressed(){
+    yTRouter.pop('')
+    return true;
+  }
+}

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