Răsfoiți Sursa

1. 消息页面开发中

bjb 3 luni în urmă
părinte
comite
ff974f5360

+ 1 - 0
entry/src/main/ets/api/req/ReqJobs.ets

@@ -5,4 +5,5 @@ import { ReqPage } from './ReqPage';
  */
 export class ReqJobs extends ReqPage {
   public status: string | null = null
+  public key: string|null = null
 }

+ 1 - 0
entry/src/main/ets/api/req/ReqTasks.ets

@@ -5,4 +5,5 @@ import { ReqPage } from './ReqPage';
  */
 export class ReqTasks extends ReqPage {
   public approvalStatus: string | null = null
+  public key: string | null = null
 }

+ 15 - 0
entry/src/main/ets/api/rsp/Job.ets

@@ -1,3 +1,4 @@
+import { Pair } from '../../entry/Pair'
 import { Node } from './Node'
 
 export class Job {
@@ -37,5 +38,19 @@ export class Job {
   cancellationTime: number | null = null
   cancellationReason: string | null = null
   workflowWorkNodeDOList: Node[] | null = null
+
+  /**
+   * 获取等级名称和背景色
+   */
+  getLevelNameAndColor(): Pair<string, string> {
+    switch (this.urgencyLevel) {
+      case "1":
+        return new Pair("紧急", "#FFFF9800")
+      case "2":
+        return new Pair("非常紧急", "#FFFF4500")
+      default:
+        return new Pair("正常", "#FF1E90FF")
+    }
+  }
 }
 

+ 1 - 1
entry/src/main/ets/api/rsp/Message.ets

@@ -4,7 +4,7 @@ export class Message {
   userType: number = 0
   readStatus: Boolean = false
   createTime: number = -1
-  title: string | null = null
+  title: string = ""
   templateContent: string = ""
   isTitle: boolean = false
 }

+ 17 - 1
entry/src/main/ets/api/rsp/Task.ets

@@ -1,9 +1,11 @@
+import { Pair } from '../../entry/Pair'
+
 export class Task {
   workId: number = 0
   nodeId: number = 0
   orderNo: string = ""
   name: string = ""
-  urgencyLevel: string = ""
+  urgencyLevel: string = "0"
   completionTime: number | null = null
   cancellationTime: number | null = null
   cancellationReason: string | null = null
@@ -15,4 +17,18 @@ export class Task {
   currentNodeId: string | null = null
   currentNodeName: string | null = null
   approvalStatus: string = ""
+
+  /**
+   * 获取等级名称和背景色
+   */
+  getLevelNameAndColor(): Pair<string, string> {
+    switch (this.urgencyLevel) {
+      case "1":
+        return new Pair("紧急", "#FFFF9800")
+      case "2":
+        return new Pair("非常紧急", "#FFFF4500")
+      default:
+        return new Pair("正常", "#FF1E90FF")
+    }
+  }
 }

+ 19 - 0
entry/src/main/ets/api/rsp/User.ets

@@ -19,4 +19,23 @@ export class User {
   createTime: number = 0
   workstationIds: number[] | null = null
   type: string | null = null
+}
+
+/**
+ * 获取用户角色类型
+ * @param roles
+ * @returns
+ */
+export function getUserRolesName(roles: string[]): string {
+  if (roles.includes("super_admin")) {
+    return "超级管理员"
+  } else if (roles.includes("jtdrawer")) {
+    return "参与人"
+  } else if (roles.includes("jtlocker")) {
+    return "上锁人"
+  } else if (roles.includes("jtcolocker")) {
+    return "共锁人"
+  } else {
+    return ""
+  }
 }

+ 15 - 0
entry/src/main/ets/components/Empty.ets

@@ -0,0 +1,15 @@
+/**
+ * 通用空布局封装
+ */
+@Component
+export struct Empty {
+  // 属性,空提示
+  @Prop tips: string = ""
+
+  build() {
+    Column() {
+      Image($r("app.media.empty")).width(64).height(64).fillColor("#88333333").objectFit(ImageFit.Auto)
+      Text(this.tips).fontColor("#88333333").fontSize(14)
+    }.width("100%").height("100%").justifyContent(FlexAlign.Center).alignItems(HorizontalAlign.Center)
+  }
+}

+ 9 - 0
entry/src/main/ets/entry/Pair.ets

@@ -0,0 +1,9 @@
+export class Pair<A, B> {
+  first: A
+  second: B
+
+  constructor(first: A, second: B) {
+    this.first = first
+    this.second = second
+  }
+}

+ 2 - 1
entry/src/main/ets/pages/PageHome.ets

@@ -3,7 +3,7 @@ import { Storage } from '../utils/Storage'
 import { VMHome } from '../vm/VMHome'
 import { TabHome } from './PageHomeComponents/TabHome'
 import { TabJobs } from './PageHomeComponents/TabJobs'
-import { TabTasks } from './PageHomeComponents/TabTask'
+import { TabTasks } from './PageHomeComponents/TabTasks'
 import { TabSettings } from './PageHomeComponents/TabSettings'
 
 @Entry
@@ -104,6 +104,7 @@ struct PageHome {
         .borderRadius("50%")
         .fontColor(Color.White)
         .fontSize(10)
+        .padding({ left: 3, right: 3 })
         .position({ top: 2, left: "55%" })
         .constraintSize({ minWidth: 15, minHeight: 15 })
         .textAlign(TextAlign.Center)

+ 20 - 12
entry/src/main/ets/pages/PageHomeComponents/TabHome.ets

@@ -1,7 +1,7 @@
-import { Job } from '../../api/rsp/Job';
 import { Message } from '../../api/rsp/Message';
 import { Task } from '../../api/rsp/Task';
 import { CardContainer } from '../../components/CardContainer';
+import { getShowDateOrTime } from '../../utils/DateUtils';
 import { VMHome } from '../../vm/VMHome';
 
 /**
@@ -47,12 +47,13 @@ export struct TabHome {
         }
         .width(36)
         .height(36)
+        .clip(true)
         .borderRadius("50%")
         .backgroundColor("#FFD700")
 
         Column() {
           Text(this.vm.user.nickname).fontSize(16).fontColor(Color.White).fontWeight(FontWeight.Medium)
-          Text("角色类型").fontSize(12).fontColor(Color.White).opacity(0.8)
+          Text(this.vm.role).fontSize(12).fontColor(Color.White).opacity(0.8)
         }.layoutWeight(1).margin({ left: 10, right: 10 }).alignItems(HorizontalAlign.Start)
 
         Stack() {
@@ -176,14 +177,21 @@ export struct TabHome {
               Row() {
                 Text(task.name).fontSize(15).fontColor("#333333").fontWeight(FontWeight.Medium)
                 Row().layoutWeight(1)
-                // Text("待办")
-                //   .fontSize(12)
-                //   .fontColor("#333333")
-                //   .backgroundColor("#FFD700")
-                //   .borderRadius(20)
-                //   .height(24)
-                //   .padding({ left: 10, right: 10 })
-                //   .textAlign(TextAlign.Center)
+                if (task.urgencyLevel != "0") {
+                  Text(task.urgencyLevel == "1" ? "紧急" : "非常紧急")
+                    .fontSize(12)
+                    .lineHeight(18)
+                    .fontColor(Color.White)
+                    .backgroundColor(task.urgencyLevel == "1" ? "#FFFF9800" : "#FFFF4500")
+                    .borderRadius(20)
+                    .padding({
+                      left: 10,
+                      right: 10,
+                      top: 3,
+                      bottom: 3
+                    })
+                    .textAlign(TextAlign.Center)
+                }
               }
 
               Flex({ wrap: FlexWrap.Wrap, alignItems: ItemAlign.Center, direction: FlexDirection.Row }) {
@@ -228,7 +236,7 @@ export struct TabHome {
                   })
                   .fontSize(12)
                   .fontColor(Color.White)
-                Text("今天 14:00")
+                Text(task.workTime == null ? "--" : getShowDateOrTime(task.workTime))
                   .margin({ left: 10 })
                   .fontColor("#999999")
                   .fontSize(12)
@@ -271,7 +279,7 @@ export struct TabHome {
               Text(`${msg.templateContent}`).fontSize(13).fontColor("#666666").lineHeight(18)
               Row() {
                 Text("作业管理").fontSize(12).fontColor("#999999").layoutWeight(1)
-                Text("09:45").fontSize(12).fontColor("#999999")
+                Text(getShowDateOrTime(msg.createTime)).fontSize(12).fontColor("#999999")
               }.margin({ top: 6, bottom: -5 })
             }.width("100%").alignItems(HorizontalAlign.Start)
           }

+ 87 - 22
entry/src/main/ets/pages/PageHomeComponents/TabJobs.ets

@@ -1,5 +1,7 @@
 import { Job } from '../../api/rsp/Job'
 import { CardContainer } from '../../components/CardContainer'
+import { Empty } from '../../components/Empty'
+import { getShowDateOrTime } from '../../utils/DateUtils'
 import { VMHome } from '../../vm/VMHome'
 
 @Component
@@ -14,26 +16,58 @@ export struct TabJobs {
       // 任务分组栏
       this.TaskType()
       Refresh({ refreshing: $$this.vm.jobsPage.isRefreshing }) {
-        List() {
-          ForEach(this.vm.jobs, (item: Job, idx: number) => {
+        Stack() {
+          List() {
+            ForEach(this.vm.jobs, (item: Job, idx: number) => {
+              ListItem() {
+                this.ListItemContent(item)
+              }
+              .width("100%")
+              .clip(false)
+              .padding({ left: 16, right: 16 })
+              .margin({ top: 8, bottom: 8 })
+            })
             ListItem() {
-              this.ListItemContent(item)
+              Row() {
+                Text(this.vm.jobsNoMore ? "没有更多数据" : "加载更多数据中...").fontSize(12).fontColor("#88333333")
+              }.width("100%").height(26).justifyContent(FlexAlign.Center).margin({ bottom: 10 })
+            }.visibility(this.vm.jobs.length > 0 ? Visibility.Visible : Visibility.None)
+          }.width("100%").height("100%")
+          .scrollBar(BarState.Off)
+          .onScrollIndex((_start, end, _center) => {
+            const size = this.vm.jobs.length
+            if (end + 2 - size >= 0) {
+              this.vm.getJobsData({
+                pageNo: this.vm.jobsPage.pageNo + 1,
+                pageSize: 10,
+                type: this.vm.jobsPage.type,
+                isRefreshing: false,
+                isGetData: true,
+                keywords: this.vm.jobsPage.keywords
+              })
             }
-            .width("100%")
-            .clip(false)
-            .padding({ left: 16, right: 16 })
-            .margin({ top: 8, bottom: 8 })
           })
-        }.width("100%").height("100%").scrollBar(BarState.Off)
-      }.width("100%").layoutWeight(1).onRefreshing(() => {
+
+          // 空布局提示
+          if (this.vm.jobs.length <= 0) {
+            Empty({ tips: "暂无数据" })
+          }
+        }
+      }
+      .width("100%")
+      .layoutWeight(1)
+      .onRefreshing(() => {
         this.vm.getJobsData({
           pageNo: 1,
           pageSize: 10,
           type: this.vm.jobsPage.type,
           isRefreshing: true,
-          isGetData: true
+          isGetData: true,
+          keywords: this.vm.jobsPage.keywords
         })
       })
+      .width("100%")
+      .height("100%")
     }
     .width("100%")
     .height("100%")
@@ -56,7 +90,7 @@ export struct TabJobs {
           .layoutWeight(1)
 
         Stack() {
-          Image($r("app.media.add")).width(20).height(20).fillColor(Color.White)
+          Image($r("app.media.add")).width(24).height(24).fillColor(Color.White)
         }.width(36).height(24).onClick(() => {
         })
       }
@@ -74,9 +108,18 @@ export struct TabJobs {
           .lineHeight(22)
           .fontColor(Color.White)
           .backgroundColor(Color.Transparent)
-          .onChange((value) => {
-            // this.vm.updateCode(value)
+          .enterKeyType(EnterKeyType.Search)
+          .onSubmit((_key, event) => {
+            this.vm.getJobsData({
+              pageNo: 1,
+              pageSize: 10,
+              isRefreshing: true,
+              type: "",
+              isGetData: true,
+              keywords: event.text
+            })
           })
+
       }
       .height(40)
       .linearGradient({ angle: 90, colors: [['#FFA126', 0.0], ['#FFB126', 1.0]] })
@@ -117,6 +160,7 @@ export struct TabJobs {
             isRefreshing: true,
             type: "running",
             isGetData: true,
+            keywords: ""
           })
         })
       Text("待发布")
@@ -139,6 +183,7 @@ export struct TabJobs {
             isRefreshing: true,
             type: "unreleased",
             isGetData: true,
+            keywords: ""
           })
         })
       Text("已完成")
@@ -161,6 +206,7 @@ export struct TabJobs {
             isRefreshing: true,
             type: "completed",
             isGetData: true,
+            keywords: ""
           })
         })
       Text("全部")
@@ -183,6 +229,7 @@ export struct TabJobs {
             isRefreshing: true,
             type: "",
             isGetData: true,
+            keywords: ""
           })
         })
     }.margin({ top: 5, bottom: 5 })
@@ -202,14 +249,32 @@ export struct TabJobs {
         Row() {
           Text(job.name).fontSize(15).fontColor("#333333").fontWeight(FontWeight.Medium)
           Row().layoutWeight(1)
-          // Text("待办")
-          //   .fontSize(12)
-          //   .fontColor("#333333")
-          //   .backgroundColor("#FFD700")
-          //   .borderRadius(20)
-          //   .height(24)
-          //   .padding({ left: 10, right: 10 })
-          //   .textAlign(TextAlign.Center)
+          // ArkTs的语法问题不能在UI中调用方法,会导致奔溃,判断逻辑这里显示调用
+          if (job.urgencyLevel != "0") {
+            Text(job.urgencyLevel == "1" ? "紧急" : "非常紧急")
+              .fontSize(12)
+              .lineHeight(18)
+              .fontColor(Color.White)
+              .backgroundColor(job.urgencyLevel == "1" ? "#FFFF9800" : "#FFFF4500")
+              .borderRadius(20)
+              .padding({
+                left: 10,
+                right: 10,
+                top: 3,
+                bottom: 3
+              })
+              .textAlign(TextAlign.Center)
+          }
+          // if (job.urgencyLevel != "0") {
+          //   Text(job.getLevelNameAndColor().first)
+          //     .fontSize(12)
+          //     .fontColor(Color.White)
+          //     .backgroundColor(job.getLevelNameAndColor().second)
+          //     .borderRadius(20)
+          //     .height(24)
+          //     .padding({ left: 10, right: 10 })
+          //     .textAlign(TextAlign.Center)
+          // }
         }
 
         Flex({ wrap: FlexWrap.Wrap, alignItems: ItemAlign.Center, direction: FlexDirection.Row }) {
@@ -254,7 +319,7 @@ export struct TabJobs {
             })
             .fontSize(12)
             .fontColor(Color.White)
-          Text("今天 14:00")
+          Text(getShowDateOrTime(job.createTime))
             .margin({ left: 10 })
             .fontColor("#999999")
             .fontSize(12)

+ 15 - 1
entry/src/main/ets/pages/PageHomeComponents/TabSettings.ets

@@ -34,6 +34,7 @@ export struct TabSettings {
         }
         .width(36)
         .height(36)
+        .clip(true)
         .borderRadius("50%")
         .backgroundColor("#FFD700")
 
@@ -78,7 +79,20 @@ export struct TabSettings {
 
         Column() {
           Text(this.vm.user.nickname).fontSize(16).fontWeight(FontWeight.Bold).fontColor($r("app.color.text"))
-          Text("角色类型").fontSize(14).fontColor("#55333333").margin({ top: 5 })
+          Text(this.vm.role)
+            .fontSize(14)
+            .lineHeight(20)
+            .padding({
+              left: 7,
+              right: 7,
+              top: 3,
+              bottom: 3
+            })
+            .fontColor(Color.White)
+            .backgroundColor($r("app.color.main"))
+            .borderRadius("50%")
+            .textAlign(TextAlign.Center)
+            .margin({ top: 5 })
         }.layoutWeight(1).alignItems(HorizontalAlign.Start).padding({ left: 15, right: 15 })
 
         Image($r("app.media.back")).size({ width: 18, height: 18 }).rotate({ angle: 180 }).fillColor("#999999")

+ 77 - 20
entry/src/main/ets/pages/PageHomeComponents/TabTask.ets → entry/src/main/ets/pages/PageHomeComponents/TabTasks.ets

@@ -1,5 +1,7 @@
 import { Task } from '../../api/rsp/Task'
 import { CardContainer } from '../../components/CardContainer'
+import { Empty } from '../../components/Empty'
+import { getShowDateOrTime } from '../../utils/DateUtils'
 import { VMHome } from '../../vm/VMHome'
 
 @Component
@@ -14,24 +16,50 @@ export struct TabTasks {
       // 任务分组栏
       this.TaskType()
       Refresh({ refreshing: $$this.vm.tasksPage.isRefreshing }) {
-        List() {
-          ForEach(this.vm.tasks, (item: Task) => {
+        Stack() {
+          List() {
+            ForEach(this.vm.tasks, (item: Task) => {
+              ListItem() {
+                this.ListItemContent(item)
+              }
+              .width("100%")
+              .clip(false)
+              .padding({ left: 16, right: 16 })
+              .margin({ top: 8, bottom: 8 })
+            })
             ListItem() {
-              this.ListItemContent(item)
+              Row() {
+                Text(this.vm.tasksNoMore ? "没有更多数据" : "加载更多数据中...").fontSize(12).fontColor("#88333333")
+              }.width("100%").height(26).justifyContent(FlexAlign.Center).margin({ bottom: 10 })
+            }.visibility(this.vm.tasks.length > 0 ? Visibility.Visible : Visibility.None)
+          }.width("100%").height("100%").scrollBar(BarState.Off)
+          .onScrollIndex((_start, end, _center) => {
+            const size = this.vm.tasks.length
+            if (end + 2 - size >= 0) {
+              this.vm.getTasksData({
+                pageNo: this.vm.tasksPage.pageNo + 1,
+                pageSize: 10,
+                type: this.vm.tasksPage.type,
+                isRefreshing: false,
+                isGetData: true,
+                keywords: this.vm.tasksPage.keywords
+              })
             }
-            .width("100%")
-            .clip(false)
-            .padding({ left: 16, right: 16 })
-            .margin({ top: 8, bottom: 8 })
           })
-        }.width("100%").height("100%").scrollBar(BarState.Off)
+
+          // 空布局提示
+          if (this.vm.tasks.length <= 0) {
+            Empty({ tips: "暂无数据" })
+          }
+        }.width("100%").height("100%")
       }.width("100%").layoutWeight(1).onRefreshing(() => {
         this.vm.getTasksData({
           pageNo: 1,
           pageSize: 10,
           type: this.vm.tasksPage.type,
           isRefreshing: true,
-          isGetData: true
+          isGetData: true,
+          keywords: this.vm.tasksPage.keywords
         })
       })
     }
@@ -74,8 +102,16 @@ export struct TabTasks {
           .lineHeight(22)
           .fontColor(Color.White)
           .backgroundColor(Color.Transparent)
-          .onChange((value) => {
-            // this.vm.updateCode(value)
+          .enterKeyType(EnterKeyType.Search)
+          .onSubmit((_key, event) => {
+            this.vm.getTasksData({
+              pageNo: 1,
+              pageSize: 10,
+              isRefreshing: true,
+              type: "",
+              isGetData: true,
+              keywords: event.text
+            })
           })
       }
       .height(40)
@@ -117,6 +153,7 @@ export struct TabTasks {
             isRefreshing: true,
             type: "running",
             isGetData: true,
+            keywords: ""
           })
         })
       Text("已完成")
@@ -139,6 +176,7 @@ export struct TabTasks {
             isRefreshing: true,
             type: "approved",
             isGetData: true,
+            keywords: ""
           })
         })
       Text("全部")
@@ -161,6 +199,7 @@ export struct TabTasks {
             isRefreshing: true,
             type: "",
             isGetData: true,
+            keywords: ""
           })
         })
     }.margin({ top: 5, bottom: 5 })
@@ -180,14 +219,32 @@ export struct TabTasks {
         Row() {
           Text(task.name).fontSize(15).fontColor("#333333").fontWeight(FontWeight.Medium)
           Row().layoutWeight(1)
-          // Text("待办")
-          //   .fontSize(12)
-          //   .fontColor("#333333")
-          //   .backgroundColor("#FFD700")
-          //   .borderRadius(20)
-          //   .height(24)
-          //   .padding({ left: 10, right: 10 })
-          //   .textAlign(TextAlign.Center)
+          // ArkTs的语法问题不能在UI中调用方法,会导致奔溃,判断逻辑这里显示调用
+          if (task.urgencyLevel != "0") {
+            Text(task.urgencyLevel == "1" ? "紧急" : "非常紧急")
+              .fontSize(12)
+              .lineHeight(18)
+              .fontColor(Color.White)
+              .backgroundColor(task.urgencyLevel == "1" ? "#FFFF9800" : "#FFFF4500")
+              .borderRadius(20)
+              .padding({
+                left: 10,
+                right: 10,
+                top: 3,
+                bottom: 3
+              })
+              .textAlign(TextAlign.Center)
+          }
+          // if (task.urgencyLevel != "0") {
+          //   Text(task.getLevelNameAndColor().first)
+          //     .fontSize(12)
+          //     .fontColor(Color.White)
+          //     .backgroundColor(task.getLevelNameAndColor().second)
+          //     .borderRadius(20)
+          //     .height(24)
+          //     .padding({ left: 10, right: 10 })
+          //     .textAlign(TextAlign.Center)
+          // }
         }
 
         Flex({ wrap: FlexWrap.Wrap, alignItems: ItemAlign.Center, direction: FlexDirection.Row }) {
@@ -233,7 +290,7 @@ export struct TabTasks {
             })
             .fontSize(12)
             .fontColor(Color.White)
-          Text("今天 14:00")
+          Text(task.workTime != null ? getShowDateOrTime(task.workTime) : "--")
             .margin({ left: 10 })
             .fontColor("#999999")
             .fontSize(12)

+ 88 - 52
entry/src/main/ets/pages/PageMessage.ets

@@ -1,3 +1,6 @@
+import { Message } from '../api/rsp/Message';
+import { CardContainer } from '../components/CardContainer';
+import { getShowDate, getShowDateOrTime } from '../utils/DateUtils';
 import { VMMessage } from '../vm/VMMessage';
 
 @Entry
@@ -5,30 +8,42 @@ import { VMMessage } from '../vm/VMMessage';
 struct PageMessage {
   @State vm: VMMessage = new VMMessage()
 
+  aboutToAppear(): void {
+    this.vm.init()
+  }
+
   build() {
     Column() {
       this.TopBar()
-      Refresh({ refreshing: $$this.vm.isRefreshing }) {
-        List() {
-          ForEach(["今天", 2, 3, "昨天", 5, 6, 7, 8], (item: object, idx: number) => {
-            if (idx == 0 || idx == 3) {
-              ListItem() {
-                this.ListItemTitle(item.toString())
-              }
-            } else {
+      Refresh({ refreshing: $$this.vm.page.isRefreshing }) {
+        Stack() {
+          List() {
+            ForEach(this.vm.list, (item: Message, idx: number) => {
               ListItem() {
-                this.ListItemContent()
+                if (item.isTitle) {
+                  this.ListItemTitle(getShowDate(item.createTime))
+                } else {
+                  this.ListItemContent(item)
+                }
               }
               .width("100%")
-              .height(122)
-              .backgroundColor("#F8F9FA")
-              .borderRadius(12)
-              .border({ width: 1, color: "#EEEEEE" })
-              .margin({ bottom: idx + 1 == 3 ? 0 : 15 })
-              .padding(16)
-            }
+              .align(Alignment.TopStart)
+              .margin({ bottom: 16 })
+            })
+          }
+          .width("100%")
+          .height("100%")
+          .padding({ left: 16, right: 16 })
+          .scrollBar(BarState.Off)
+          .onScrollIndex((start, end, _center) => {
+            this.vm.updateTopItemIndex(start)
           })
-        }.width("100%").height("100%").padding({ left: 16, right: 16 }).scrollBar(BarState.Off)
+
+          // 顶部显示的当前日期
+          Row() {
+            Text(`${this.vm.topHeaderDate}`).fontColor("#333333").fontSize(16).height(45)
+          }.width("100%").padding({ left: 16, right: 16 }).backgroundColor(Color.White)
+        }.width("100%").height("100%").alignContent(Alignment.TopStart)
       }.width("100%").layoutWeight(1).onRefreshing(() => {
         this.vm.onRefresh()
       })
@@ -46,22 +61,36 @@ struct PageMessage {
   TopBar() {
     Column() {
       Row() {
+        Row() {
+          Image($r("app.media.back"))
+            .width(32)
+            .height(32)
+            .borderRadius("50%")
+            .backgroundColor("#FFFFA126")
+            .padding(8)
+            .fillColor(Color.White)
+            .onClick(() => {
+              this.getUIContext().getRouter().back()
+            })
+        }.layoutWeight(1).justifyContent(FlexAlign.Start)
+
         Text("消息中心")
           .fontSize(18)
           .fontColor(Color.White)
           .fontWeight(FontWeight.Medium)
           .height(36)
-          .layoutWeight(1)
 
-        Stack() {
-          Image($r("app.media.all_read")).width(20).height(20).fillColor(Color.White).objectFit(ImageFit.Auto)
-        }.width(36).height(24).onClick(() => {
-        })
+        Row() {
+          Stack() {
+            Image($r("app.media.all_read")).width(20).height(20).fillColor(Color.White).objectFit(ImageFit.Auto)
+          }.width(36).height(36).onClick(() => {
+          })
 
-        Stack() {
-          Image($r("app.media.delete")).width(18).height(18).fillColor(Color.White)
-        }.width(36).height(24).onClick(() => {
-        })
+          // Stack() {
+          //   Image($r("app.media.delete")).width(18).height(18).fillColor(Color.White)
+          // }.width(36).height(24).onClick(() => {
+          // })
+        }.layoutWeight(1).justifyContent(FlexAlign.End)
       }
       .width("100%")
       .padding({
@@ -72,40 +101,47 @@ struct PageMessage {
       })
     }
     .width("100%")
-    .backgroundColor("#FFA500")
+    .linearGradient({ angle: 90, colors: [["#FFFF8C00", 0], ["#FFFFA500", 1]] })
     .expandSafeArea([SafeAreaType.SYSTEM], [SafeAreaEdge.TOP])
   }
 
   @Builder
-  ListItemTitle(title: string) {
-    Text(title).fontColor("#333333").fontSize(16).height(45)
+  ListItemTitle(msg: string) {
+    Text(msg).fontColor("#333333").fontSize(16).height(45)
   }
 
   @Builder
-  ListItemContent() {
-    Row() {
-      Stack() {
-        Image($r("app.media.jobs")).fillColor(Color.White)
-      }
-      .width(40)
-      .height(40)
-      .padding(12)
-      .borderRadius("50%")
-      .backgroundColor("#1E90FF")
-      .alignSelf(ItemAlign.Start)
-      .clip(false)
-
-      Column() {
-        Text("新任务分配").fontSize(15).fontColor("#333333").fontWeight(FontWeight.Medium).margin({ bottom: 10 })
-        Text("您有新的作业任务待处理,作业票号:WO-2025-003").fontSize(13).fontColor("#666666").lineHeight(18)
-        Row().layoutWeight(1)
-        Row() {
-          Text("09:45").layoutWeight(1).fontSize(12).fontColor("#999999")
-          Text("作业管理").fontSize(12).fontColor("#999999")
+  ListItemContent(msg: Message) {
+    CardContainer() {
+      Row() {
+        Stack() {
+          Image($r("app.media.jobs")).fillColor(Color.White)
         }
-      }.layoutWeight(1).height("100%").padding({ left: 15, right: 10 }).alignItems(HorizontalAlign.Start)
+        .width(40)
+        .height(40)
+        .padding(12)
+        .borderRadius("50%")
+        .backgroundColor("#1E90FF")
+        .alignSelf(ItemAlign.Start)
+        .clip(false)
 
-      Row().width(8).height(8).backgroundColor("#FF4500").borderRadius("50%")
-    }.width("100%").height("100%")
+        Column() {
+          Text(msg.title).fontSize(15).fontColor("#333333").fontWeight(FontWeight.Medium).margin({ bottom: 10 })
+          Text(msg.templateContent).fontSize(13).fontColor("#666666").lineHeight(18)
+          Row().layoutWeight(1)
+          Row() {
+            Text(getShowDateOrTime(msg.createTime)).layoutWeight(1).fontSize(12).fontColor("#999999")
+            Text("作业管理").fontSize(12).fontColor("#999999")
+          }
+        }.layoutWeight(1).height("100%").padding({ left: 15, right: 10 }).alignItems(HorizontalAlign.Start)
+
+        Row()
+          .width(8)
+          .height(8)
+          .backgroundColor("#FF4500")
+          .borderRadius("50%")
+          .visibility(msg.readStatus ? Visibility.Hidden : Visibility.Visible)
+      }.width("100%").height(122)
+    }
   }
 }

+ 103 - 0
entry/src/main/ets/utils/DateUtils.ets

@@ -0,0 +1,103 @@
+/**
+ * 将时间戳转换为可以显示的日期和时间
+ *
+ * @param timestamp 毫秒级别的时间戳
+ * @returns
+ */
+export function getShowDateOrTime(timestamp: number): string {
+  const localTs = (new Date()).getTime()
+  const localDat = format(localTs).split(" ")
+  const localDate = localDat[0]
+  // val localTime = localDat[1]
+  // 显示逻辑
+  // 当天显示 今天+时间
+  // 昨天显示 昨天+时间
+  // 本年显示 日期 + 时间
+  // 他年显示 年月日 + 时间
+  // 执行时间戳的转换
+  const dat = format(timestamp).split(" ")
+  const date = dat[0].split("-")
+  const year = date[0]
+  const month = date[1]
+  const day = date[2]
+  const time = dat[1]
+  let out = ""
+  if (localDate == dat[0]) {
+    // 说明是当天
+    out = `今天 ${time}`
+  } else if (localDate == `${year}-${month}-${(Number.parseInt(day) + 1).toString().padStart(2, '0')}`) {
+    // 说明是昨天
+    out = `昨天 ${time}`
+  } else if (localDate.startsWith(`${year}-`)) {
+    // 说明是本年度
+    out = `${month}-${day} ${time}`
+  } else {
+    out = `${dat[0]} ${dat[1]}`
+  }
+  return out
+}
+
+/**
+ * 将时间戳转换为可以显示的日期和时间
+ *
+ * @param timestamp 毫秒级别的时间戳
+ * @returns
+ */
+export function getShowDate(timestamp: number): string {
+  const localTs = (new Date()).getTime()
+  const localDat = format(localTs).split(" ")
+  const localDate = localDat[0]
+  // 显示逻辑
+  // 当天显示 今天+时间
+  // 昨天显示 昨天+时间
+  // 本年显示 日期 + 时间
+  // 他年显示 年月日 + 时间
+  // 执行时间戳的转换
+  const dat = format(timestamp).split(" ")
+  const date = dat[0].split("-")
+  const year = date[0]
+  const month = date[1]
+  const day = date[2]
+  let out = ""
+  if (localDate == dat[0]) {
+    // 说明是当天
+    out = `今天`
+  } else if (localDate == `${year}-${month}-${(Number.parseInt(day) + 1).toString().padStart(2, '0')}`) {
+    // 说明是昨天
+    out = `昨天`
+  } else if (localDate.startsWith(`${year}-`)) {
+    // 说明是本年度
+    out = `${month}-${day}`
+  } else {
+    out = `${dat[0]}`
+  }
+  return out
+}
+
+/**
+ * 将时间戳格式化为想要的格式
+ *
+ * @param timestamp 时间戳
+ * @param pattern   格式化的具体格式
+ *
+ * @returns
+ */
+export function format(timestamp: number, pattern: string = "yyyy-MM-dd HH:mm:ss"): string {
+  const date = new Date(timestamp)
+  const year = date.getFullYear()
+  const month = date.getMonth() + 1
+  const day = date.getDate()
+  const hours = date.getHours()
+  const minutes = date.getMinutes()
+  const seconds = date.getSeconds()
+  const ms = date.getMilliseconds()
+  // 组装时间
+  return pattern
+    .replace("yyyy", `${year}`)
+    .replace("MM", `${month}`.padStart(2, "0"))
+    .replace("dd", `${day}`.padStart(2, "0"))
+    .replace("HH", `${hours}`.padStart(2, "0"))
+    .replace("mm", `${minutes}`.padStart(2, "0"))
+    .replace("ss", `${seconds}`.padStart(2, "0"))
+    .replace("SSS", `${ms}`.padStart(3, "0"))
+}

+ 9 - 3
entry/src/main/ets/utils/HttpClient.ets

@@ -33,13 +33,19 @@ async function requestHttp<T>(url: string = '',
   // Get方法需要自己拼接
   if (method == http.RequestMethod.GET) {
     // 如果data里面有值并且里面有对象的时候
+
     if (data && Object.keys(data).length) {
+      const keyLen = Object.keys(data).length
+      let idx = 0
       reqUrl += "?" + Object.keys(data).map(key => {
+        idx++
         if (data[key]) {
-          return `${key}=${data[key]}` // a=1 =>
+          const value = encodeURIComponent(data[key])
+          return idx == keyLen ? `${key}=${value}` : `${key}=${value}&`
+        } else {
+          return ""
         }
-        return ""
-      }).join('&') //['a=1','b=2','c=3']
+      }).join("")
     }
   }
   // 设置请求对象

+ 53 - 21
entry/src/main/ets/vm/VMHome.ets

@@ -2,7 +2,7 @@ import { ApiRequest } from '../api/req/ApiRequest'
 import { Job } from '../api/rsp/Job'
 import { Message } from '../api/rsp/Message'
 import { Task } from '../api/rsp/Task'
-import { User } from '../api/rsp/User'
+import { getUserRolesName, User } from '../api/rsp/User'
 import { Loading } from '../components/loading/Loading'
 
 @Observed
@@ -26,13 +26,19 @@ export class VMHome {
   // 获取最近三条通知
   homeMessages: Message[] = []
   // 作业页面Page加载器
-  jobsPage: HomePageLoad = new HomePageLoad()
+  jobsPage: PageLoader = new PageLoader()
   // 作业列表
   jobs: Job[] = []
+  // 是否还有更多数据
+  jobsNoMore = false
   // 任务页面Page加载器
-  tasksPage: HomePageLoad = new HomePageLoad()
+  tasksPage: PageLoader = new PageLoader()
   // 任务列表
   tasks: Task[] = []
+  // 是否还有更多数据
+  tasksNoMore = false
+  // 处理角色类型
+  role: string = ""
 
   /**
    * 初始化首页数据
@@ -61,14 +67,25 @@ export class VMHome {
       // 获取未读消息数
       const msgCountRsp = await ApiRequest.getMessagesUnread()
       // 查询进行中的作业,主要为了获取当前进行中的作业数
-      const jobsRsp = await ApiRequest.getJobs({ pageNo: 1, pageSize: 1, status: "running" })
+      const jobsRsp = await ApiRequest.getJobs({
+        pageNo: 1,
+        pageSize: 1,
+        status: "running",
+        key: null
+      })
       // 查询最近三条任务
-      const tasksRsp = await ApiRequest.getTasks({ pageNo: 1, pageSize: 3, approvalStatus: "running" })
+      const tasksRsp = await ApiRequest.getTasks({
+        pageNo: 1,
+        pageSize: 3,
+        approvalStatus: "running",
+        key: null
+      })
       // 获取最新三条通知
       const msgRsp = await ApiRequest.getMessages({ pageNo: 1, pageSize: 3 })
       // 查询进行中的任务
       // 赋值操作放到最后,统一性
       this.user = upRsp.data?.user ?? new User()
+      this.role = getUserRolesName(upRsp.data?.roles ?? [])
       this.taskProgressCount = statisticsRsp.data?.inProgressCount ?? 0
       this.taskFinishedCount = statisticsRsp.data?.completedCount ?? 0
       this.jobProgressCount = jobsRsp.data?.total ?? 0
@@ -96,10 +113,6 @@ export class VMHome {
     })
   }
 
-  onTabTaskRefresh() {
-
-  }
-
   /**
    * 更新当前选中状态
    * @param index
@@ -113,7 +126,7 @@ export class VMHome {
    *
    * @param page
    */
-  getJobsData(page: HomePageLoad) {
+  getJobsData(page: PageLoader) {
     // 如果当前正在获取数据,则不进行获取
     if (this.jobsPage.isGetData) {
       return
@@ -123,9 +136,15 @@ export class VMHome {
       pageSize: this.jobsPage.pageSize,
       type: page.type,
       isRefreshing: page.isRefreshing,
-      isGetData: true
+      isGetData: true,
+      keywords: page.keywords
     }
-    ApiRequest.getJobs({ pageNo: page.pageNo, pageSize: page.pageSize, status: page.type })
+    ApiRequest.getJobs({
+      pageNo: page.pageNo,
+      pageSize: page.pageSize,
+      status: page.type,
+      key: page.keywords
+    })
       .then((rsp) => {
         setTimeout(() => {
           if (page.pageNo <= 1) {
@@ -133,12 +152,14 @@ export class VMHome {
           } else {
             this.jobs.push(...rsp.data?.list ?? [])
           }
+          this.jobsNoMore = this.jobs.length == (rsp.data?.total ?? 0)
           this.jobsPage = {
             pageNo: page.pageNo,
             pageSize: this.jobsPage.pageSize,
             type: this.jobsPage.type,
             isRefreshing: false,
-            isGetData: false
+            isGetData: false,
+            keywords: page.keywords
           }
         }, 500)
       }).catch(() => {
@@ -148,7 +169,8 @@ export class VMHome {
           pageSize: this.jobsPage.pageSize,
           type: this.jobsPage.type,
           isRefreshing: false,
-          isGetData: false
+          isGetData: false,
+          keywords: page.keywords
         }
       }, 500)
     })
@@ -159,7 +181,7 @@ export class VMHome {
    *
    * @param page 当前加载的页
    */
-  getTasksData(page: HomePageLoad) {
+  getTasksData(page: PageLoader) {
     // 如果当前正在获取数据,则不进行获取
     if (this.tasksPage.isGetData) {
       return
@@ -169,9 +191,15 @@ export class VMHome {
       pageSize: this.tasksPage.pageSize,
       type: page.type,
       isRefreshing: page.isRefreshing,
-      isGetData: true
+      isGetData: true,
+      keywords: page.keywords
     }
-    ApiRequest.getTasks({ pageNo: page.pageNo, pageSize: page.pageSize, approvalStatus: page.type })
+    ApiRequest.getTasks({
+      pageNo: page.pageNo,
+      pageSize: page.pageSize,
+      approvalStatus: page.type,
+      key: page.keywords
+    })
       .then((rsp) => {
         setTimeout(() => {
           if (page.pageNo <= 1) {
@@ -179,12 +207,14 @@ export class VMHome {
           } else {
             this.tasks.push(...rsp.data?.list ?? [])
           }
+          this.tasksNoMore = this.tasks.length == (rsp.data?.total ?? 0)
           this.tasksPage = {
             pageNo: page.pageNo,
             pageSize: this.tasksPage.pageSize,
             type: this.tasksPage.type,
             isRefreshing: false,
-            isGetData: false
+            isGetData: false,
+            keywords: page.keywords
           }
         }, 500)
       }).catch(() => {
@@ -194,7 +224,8 @@ export class VMHome {
           pageSize: this.tasksPage.pageSize,
           type: this.tasksPage.type,
           isRefreshing: false,
-          isGetData: false
+          isGetData: false,
+          keywords: page.keywords
         }
       }, 500)
     })
@@ -202,12 +233,13 @@ export class VMHome {
 }
 
 /**
- * 首页Page加载器
+ * Page加载器
  */
-export class HomePageLoad {
+export class PageLoader {
   public pageNo: number = 1
   public pageSize: number = 10
   public type: string = ""
   public isRefreshing: boolean = false
   public isGetData: boolean = false
+  public keywords: string = ""
 }

+ 99 - 5
entry/src/main/ets/vm/VMMessage.ets

@@ -1,11 +1,105 @@
+import { ApiRequest } from '../api/req/ApiRequest'
+import { Message } from '../api/rsp/Message'
+import { Loading } from '../components/loading/Loading'
+import { getShowDate } from '../utils/DateUtils'
+import { PageLoader } from './VMHome'
+
+/**
+ * 通知页面数据处理
+ */
 @Observed
 export class VMMessage {
-  isRefreshing: boolean = false
+  // 页面数据加载器
+  page: PageLoader = new PageLoader()
+  // 展示的消息列表
+  list: Message[] = []
+  // 列表最顶部item位置
+  topHeaderDate: string = ""
+
+  /**
+   * 首次初始化加载
+   */
+  init() {
+    this.page = new PageLoader()
+    this.getPageData(this.page, true)
+  }
 
+  /**
+   * 下拉刷新数据
+   */
   onRefresh() {
-    this.isRefreshing = true
-    setTimeout(() => {
-      this.isRefreshing = false
-    }, 3000)
+    this.page = {
+      isRefreshing: true,
+      pageNo: 1,
+      pageSize: 10,
+      isGetData: false,
+      type: "",
+      keywords: ""
+    }
+    this.getPageData(this.page)
+  }
+
+  updateTopItemIndex(idx: number) {
+    this.topHeaderDate = getShowDate(this.list[idx].createTime)
+  }
+
+  /**
+   * 获取页面数据
+   *
+   * @param page
+   */
+  getPageData(page: PageLoader, showLoading: boolean = false) {
+    if (this.page.isGetData) {
+      return
+    }
+    if (showLoading) {
+      Loading.showLoading()
+    }
+    this.page = {
+      isRefreshing: page.isRefreshing,
+      pageNo: this.page.pageNo,
+      pageSize: page.pageSize,
+      isGetData: true,
+      type: "",
+      keywords: ""
+    }
+    ApiRequest.getMessages({ pageNo: page.pageNo, pageSize: page.pageSize }).then((rsp) => {
+      const data = rsp.data?.list ?? []
+      if (page.pageNo == 1) {
+        this.list = []
+      }
+      data.forEach((msg: Message) => {
+        // 查找是否有和日期相同的标题,如果没有则插入
+        const findTitle = this.list.find((base: Message) => base.isTitle && (getShowDate(base.createTime) == getShowDate(msg.createTime)))
+        if (!findTitle) {
+          const m = new Message()
+          m.isTitle = true
+          m.createTime = msg.createTime
+          this.list.push(m)
+        }
+        this.list.push(msg)
+      })
+      setTimeout(() => {
+        this.page = {
+          isRefreshing: false,
+          pageNo: page.pageNo,
+          pageSize: page.pageSize,
+          isGetData: false,
+          type: "",
+          keywords: ""
+        }
+        Loading.hideLoading()
+      }, 500)
+    }).catch(() => {
+      this.page = {
+        isRefreshing: false,
+        pageNo: this.page.pageNo,
+        pageSize: page.pageSize,
+        isGetData: false,
+        type: "",
+        keywords: ""
+      }
+      Loading.hideLoading()
+    })
   }
 }

Fișier diff suprimat deoarece este prea mare
+ 0 - 0
entry/src/main/resources/base/media/empty.svg


Unele fișiere nu au fost afișate deoarece prea multe fișiere au fost modificate în acest diff