bjb 4 месяцев назад
Родитель
Сommit
63f49be659

+ 5 - 1
bozzys_sdk/build-profile.json5

@@ -4,7 +4,11 @@
     "externalNativeOptions": {
     "externalNativeOptions": {
       "path": "./src/main/cpp/CMakeLists.txt",
       "path": "./src/main/cpp/CMakeLists.txt",
       "arguments": "",
       "arguments": "",
-      "cppFlags": ""
+      "cppFlags": "",
+      "abiFilters": [
+        "arm64-v8a",
+        "x86_64"
+      ]
     },
     },
     "resOptions": {
     "resOptions": {
       "copyCodeResource": {
       "copyCodeResource": {

+ 5 - 5
build-profile.json5

@@ -5,13 +5,13 @@
         "name": "default",
         "name": "default",
         "type": "HarmonyOS",
         "type": "HarmonyOS",
         "material": {
         "material": {
-          "certpath": "C:\\Users\\ISCS\\.ohos\\config\\default_Bozzys_HMOS_IJZctqqYeqIPOdk4yyWMI1byWLyPOaDXRx-iocotmiI=.cer",
+          "certpath": "C:\\Users\\ISCS\\.ohos\\config\\default_HMOS_Bozzys_HP5OM4eVV84UM2fMSmeCbI2qYo1z8QX2kkiC2cONM8Y=.cer",
           "keyAlias": "debugKey",
           "keyAlias": "debugKey",
-          "keyPassword": "0000001B8083B87E72425B072D91488198CFB0D70F22F2AEBEA5F57D6D97B6CB471C0180E5A0E7CF983AA5",
-          "profile": "C:\\Users\\ISCS\\.ohos\\config\\default_Bozzys_HMOS_IJZctqqYeqIPOdk4yyWMI1byWLyPOaDXRx-iocotmiI=.p7b",
+          "keyPassword": "0000001BA4611120FAA29D85A4F2452B7A14F842CEA20AFB5A7569656E4D417F10A5E1C542B5134A58817C",
+          "profile": "C:\\Users\\ISCS\\.ohos\\config\\default_HMOS_Bozzys_HP5OM4eVV84UM2fMSmeCbI2qYo1z8QX2kkiC2cONM8Y=.p7b",
           "signAlg": "SHA256withECDSA",
           "signAlg": "SHA256withECDSA",
-          "storeFile": "C:\\Users\\ISCS\\.ohos\\config\\default_Bozzys_HMOS_IJZctqqYeqIPOdk4yyWMI1byWLyPOaDXRx-iocotmiI=.p12",
-          "storePassword": "0000001B8DA6312148966308E49E360C499133CBAF5079D736B4F7B945F2D367F85CC3C7564114A11F7FF4"
+          "storeFile": "C:\\Users\\ISCS\\.ohos\\config\\default_HMOS_Bozzys_HP5OM4eVV84UM2fMSmeCbI2qYo1z8QX2kkiC2cONM8Y=.p12",
+          "storePassword": "0000001BE34B50440810C37CD0E204691198BC6FE26E1F6F3DBDAA7E49F37886FDB4BFCB01136883738F8D"
         }
         }
       }
       }
     ],
     ],

+ 22 - 2
entry/src/main/ets/api/req/ReqApi.ets

@@ -1,7 +1,8 @@
 import { Request } from '../../utils/HttpClient';
 import { Request } from '../../utils/HttpClient';
 import { Rsp } from '../rsp/Rsp';
 import { Rsp } from '../rsp/Rsp';
-import { RspLogin } from '../rsp/RspLogin';
+import { Login } from '../rsp/Login';
 import { ReqLogin } from './ReqLogin';
 import { ReqLogin } from './ReqLogin';
+import { Permission } from '../rsp/Permission';
 
 
 export class ReqApi {
 export class ReqApi {
   /**
   /**
@@ -11,8 +12,27 @@ export class ReqApi {
    * @param pwd       密码
    * @param pwd       密码
    * @returns
    * @returns
    */
    */
-  static login(username: string, pwd: string): Promise<Rsp<RspLogin>> {
+  static login(username: string, pwd: string): Promise<Rsp<Login>> {
     const req = new ReqLogin(username, pwd)
     const req = new ReqLogin(username, pwd)
     return Request.post("/admin-api/system/auth/login", req)
     return Request.post("/admin-api/system/auth/login", req)
   }
   }
+
+  /**
+   * 获取用户权限信息
+   *
+   * @returns
+   */
+  static getUserPermission(): Promise<Rsp<Permission>> {
+    return Request.get("/admin-api/system/auth/get-permission-info")
+  }
+
+  /**
+   * 刷新token操作
+   *
+   * @param refreshToken
+   * @returns
+   */
+  static refreshToken(refreshToken: string): Promise<Rsp<Login>> {
+    return Request.post("/admin-api/system/auth/refresh-token?refreshToken=" + refreshToken)
+  }
 }
 }

+ 1 - 1
entry/src/main/ets/api/rsp/RspLogin.ets → entry/src/main/ets/api/rsp/Login.ets

@@ -1,4 +1,4 @@
-export class RspLogin {
+export class Login {
   // 用户id
   // 用户id
   id: number = 0
   id: number = 0
   // 用户昵称
   // 用户昵称

+ 8 - 0
entry/src/main/ets/api/rsp/Permission.ets

@@ -0,0 +1,8 @@
+import { User } from './User'
+
+export class Permission {
+  // 当前用户
+  user: User = new User()
+  // 角色列表
+  roles: string[] = []
+}

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

@@ -0,0 +1,22 @@
+@Observed
+export class User {
+  id: number = 0
+  userId: number | null = null
+  username: string = ""
+  nickname: string = ""
+  cardNfc: string | null = null
+  remark: string = ""
+  deptId: number = 0
+  deptName: string | null = null
+  postIds: number[] = []
+  email: string | null = null
+  mobile: string | null = null
+  sex: number = 0
+  avatar: string = ""
+  status: number = 0
+  loginIp: string = ""
+  loginDate: number = 0
+  createTime: number = 0
+  workstationIds: number[] | null = null
+  type: string | null = null
+}

+ 14 - 8
entry/src/main/ets/components/CardContainer.ets

@@ -1,24 +1,30 @@
 @Component
 @Component
 export struct CardContainer {
 export struct CardContainer {
-  @Prop radius: number = 16
+  @Prop radius: number | string = 16
+  @Prop bgColor: string = '#FFFFFF'
   @Prop shadowColor: string = '#000000'
   @Prop shadowColor: string = '#000000'
-  @Prop shadowOpacity: number = 0.15
-  @Prop blurRadius: number = 20
+  @Prop shadowOpacity: number = 0.2
+  @Prop blurRadius: number = 50
   @Prop cardColor: Color = Color.White
   @Prop cardColor: Color = Color.White
-  @Prop paddings: number = 16
+  @Prop paddings: number = 0
+  @Prop margins: Margin = {}
+  // 是否裁剪超出部分
+  @Prop needClip: boolean = true
   @BuilderParam children: () => void = this.content
   @BuilderParam children: () => void = this.content
 
 
   build() {
   build() {
-    Column() {
+    Stack() {
       // 内容插槽
       // 内容插槽
-      this.content()
+      this.children()
     }
     }
     .padding(this.paddings)
     .padding(this.paddings)
-    .backgroundColor(this.cardColor)
     .borderRadius(this.radius)
     .borderRadius(this.radius)
+    .backgroundColor(this.bgColor)
+    .margin(this.margins)
+    .clip(this.needClip)
     .shadow({
     .shadow({
       radius: this.blurRadius,
       radius: this.blurRadius,
-      color: this.shadowColor,
+      color: this.shadowColor.replace("#", "#" + Math.round(this.shadowOpacity * 255).toString(16).padStart(2, '0')),
       offsetX: 0,
       offsetX: 0,
       offsetY: 0
       offsetY: 0
     })
     })

+ 3 - 0
entry/src/main/ets/entry/Entry.ets

@@ -3,6 +3,7 @@ import { hilog } from '@kit.PerformanceAnalysisKit';
 import { window } from '@kit.ArkUI';
 import { window } from '@kit.ArkUI';
 import { Storage } from '../utils/Storage';
 import { Storage } from '../utils/Storage';
 import { Loading } from '../components/loading/Loading';
 import { Loading } from '../components/loading/Loading';
+import { EventBus } from '../utils/EventBus';
 
 
 const DOMAIN = 0x0000;
 const DOMAIN = 0x0000;
 
 
@@ -15,6 +16,8 @@ export default class EntryAbility extends UIAbility {
     }
     }
     // 初始化存储工具
     // 初始化存储工具
     Storage.init(this.context)
     Storage.init(this.context)
+    // 初始化事件工具
+    EventBus.init(this.context)
     hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onCreate');
     hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onCreate');
   }
   }
 
 

+ 19 - 0
entry/src/main/ets/pages/PageHome.ets

@@ -1,3 +1,5 @@
+import { EventBus } from '../utils/EventBus'
+import { Storage } from '../utils/Storage'
 import { VMHome } from '../vm/VMHome'
 import { VMHome } from '../vm/VMHome'
 import { TabHome } from './PageHomeComponents/TabHome'
 import { TabHome } from './PageHomeComponents/TabHome'
 import { TabJobs } from './PageHomeComponents/TabJobs'
 import { TabJobs } from './PageHomeComponents/TabJobs'
@@ -9,6 +11,23 @@ import { TabSettings } from './PageHomeComponents/TabSettings'
 struct PageHome {
 struct PageHome {
   @State vm: VMHome = new VMHome()
   @State vm: VMHome = new VMHome()
 
 
+  aboutToAppear(): void {
+    const ctx = this.getUIContext()
+    const router = ctx.getRouter()
+    EventBus.on("EVENT_LOGOUT", () => {
+      // 先解绑事件,再处理退出登录操作
+      EventBus.off("EVENT_LOGOUT")
+      // 标记当前账号为未登录状态
+      Storage.setLogin(false)
+      router.clear()
+      router.replaceUrl({ url: "pages/PageLogin" }).catch()
+    })
+  }
+
+  aboutToDisappear(): void {
+    EventBus.off("EVENT_LOGOUT")
+  }
+
   build() {
   build() {
     Tabs({ barPosition: BarPosition.End, index: this.vm.tabIndex }) {
     Tabs({ barPosition: BarPosition.End, index: this.vm.tabIndex }) {
       TabContent() {
       TabContent() {

+ 6 - 8
entry/src/main/ets/pages/PageHomeComponents/TabHome.ets

@@ -1,6 +1,4 @@
 import { VMHome } from '../../vm/VMHome';
 import { VMHome } from '../../vm/VMHome';
-import { abilityAccessCtrl } from '@kit.AbilityKit';
-import { BleManager } from 'bozzys_sdk/src/main/ets/ble/BleManager';
 
 
 /**
 /**
  * 首页Tab页面
  * 首页Tab页面
@@ -17,13 +15,13 @@ export struct TabHome {
   build() {
   build() {
     Column() {
     Column() {
       this.TopBar()
       this.TopBar()
-      Refresh({ refreshing: $$this.vm.isRefreshing }) {
+      Refresh({ refreshing: $$this.vm.isTabHomeRefreshing }) {
         Column() {
         Column() {
           this.TODOStatus()
           this.TODOStatus()
           this.TODOList()
           this.TODOList()
         }.width("100%").height("100%")
         }.width("100%").height("100%")
       }.width("100%").layoutWeight(1).onRefreshing(() => {
       }.width("100%").layoutWeight(1).onRefreshing(() => {
-        this.vm.onRefresh()
+        this.vm.onTabHomeRefresh()
       })
       })
     }
     }
     .width("100%")
     .width("100%")
@@ -40,17 +38,17 @@ export struct TabHome {
     Column() {
     Column() {
       Row() {
       Row() {
         Stack() {
         Stack() {
-          Image($r("app.media.user")).fillColor(Color.White)
+          Image($r("app.media.user")).fillColor(Color.White).margin(8)
+          Image(this.vm.user.avatar)
         }
         }
         .width(36)
         .width(36)
         .height(36)
         .height(36)
         .borderRadius("50%")
         .borderRadius("50%")
         .backgroundColor("#FFD700")
         .backgroundColor("#FFD700")
-        .padding(8)
 
 
         Column() {
         Column() {
-          Text(this.vm.username).fontSize(16).fontColor(Color.White).fontWeight(FontWeight.Medium)
-          Text("操作员 电气维护组").fontSize(12).fontColor(Color.White).opacity(0.8)
+          Text(this.vm.user.nickname).fontSize(16).fontColor(Color.White).fontWeight(FontWeight.Medium)
+          Text("角色类型").fontSize(12).fontColor(Color.White).opacity(0.8)
         }.layoutWeight(1).margin({ left: 10, right: 10 }).alignItems(HorizontalAlign.Start)
         }.layoutWeight(1).margin({ left: 10, right: 10 }).alignItems(HorizontalAlign.Start)
 
 
         Stack() {
         Stack() {

+ 48 - 5
entry/src/main/ets/pages/PageHomeComponents/TabSettings.ets

@@ -9,9 +9,9 @@ export struct TabSettings {
   build() {
   build() {
     Column() {
     Column() {
       this.TopBar()
       this.TopBar()
-      CardContainer({children:()=>{
-        Column().width(120).height(120)
-      }})
+      this.UserCard()
+      Column().layoutWeight(1)
+      this.Logout()
     }
     }
     .width("100%")
     .width("100%")
     .height("100%")
     .height("100%")
@@ -27,13 +27,13 @@ export struct TabSettings {
     Column() {
     Column() {
       Row() {
       Row() {
         Stack() {
         Stack() {
-          Image($r("app.media.user")).fillColor(Color.White)
+          Image($r("app.media.user")).fillColor(Color.White).margin(8)
+          Image(this.vm.user.avatar)
         }
         }
         .width(36)
         .width(36)
         .height(36)
         .height(36)
         .borderRadius("50%")
         .borderRadius("50%")
         .backgroundColor("#FFD700")
         .backgroundColor("#FFD700")
-        .padding(8)
 
 
         Column() {
         Column() {
           Text("设置").fontSize(16).fontColor(Color.White).fontWeight(FontWeight.Medium)
           Text("设置").fontSize(16).fontColor(Color.White).fontWeight(FontWeight.Medium)
@@ -52,4 +52,47 @@ export struct TabSettings {
     .linearGradient({ angle: 90, colors: [['#FF8C00', 0.0], ['#FFA500', 1.0]] })
     .linearGradient({ angle: 90, colors: [['#FF8C00', 0.0], ['#FFA500', 1.0]] })
     .expandSafeArea([SafeAreaType.SYSTEM], [SafeAreaEdge.TOP])
     .expandSafeArea([SafeAreaType.SYSTEM], [SafeAreaEdge.TOP])
   }
   }
+
+  @Builder
+  UserCard() {
+    CardContainer({ margins: { top: 16, left: 16, right: 16 } }) {
+      Row() {
+        Stack() {
+          CardContainer({ radius: "50%" }) {
+            Stack().width("100%").height("100%").linearGradient({ angle: 135, colors: [['#FFAE00', 0.0], ['#F7C700', 1.0]] })
+            Text("P").fontSize(20).fontWeight(FontWeight.Bold)
+            Image(this.vm.user.avatar).size({ width: 60, height: 60 })
+          }
+
+          Stack() {
+            CardContainer() {
+              Image($r("app.media.camera")).fillColor($r("app.color.main")).padding(4)
+            }
+          }.size({ width: 20, height: 20 }).position({ bottom: 0, right: 0 })
+        }.size({ width: 60, height: 60 })
+
+        Column() {
+          Text(this.vm.user.nickname).fontSize(16).fontWeight(FontWeight.Bold).fontColor($r("app.color.text"))
+          Text("角色类型").fontSize(14).fontColor("#55333333").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")
+      }.width("100%").height(90).padding({ left: 20, right: 20 })
+      .linearGradient({ angle: 90, colors: [['#FFF9E5', 0.0], ['#FFFEFB', 1.0]] })
+    }
+  }
+
+  @Builder
+  Logout() {
+    Row() {
+      Text("退出登录").fontSize(18).fontWeight(FontWeight.Bold).fontColor(Color.White)
+      Image($r("app.media.logout")).width(24).height(24).fillColor(Color.White).margin({ left: 5 })
+    }
+    .width(335)
+    .height(46)
+    .margin({ top: 10, bottom: 10 })
+    .backgroundColor("#FA666C")
+    .borderRadius(6)
+    .justifyContent(FlexAlign.Center)
+  }
 }
 }

+ 1 - 1
entry/src/main/ets/pages/PageLogin.ets

@@ -98,7 +98,7 @@ struct PageLogin {
             .onClick(() => {
             .onClick(() => {
               this.vm.login(() => {
               this.vm.login(() => {
                 setTimeout(() => {
                 setTimeout(() => {
-                  this.getUIContext().getRouter().replaceUrl({ url: 'pages/PageHome' })
+                  this.getUIContext().getRouter().replaceUrl({ url: 'pages/PageHome' }).catch()
                 }, 1500)
                 }, 1500)
               })
               })
             })
             })

+ 22 - 0
entry/src/main/ets/utils/EventBus.ets

@@ -0,0 +1,22 @@
+import { common } from '@kit.AbilityKit';
+
+export class EventBus {
+  // 携带对象
+  private static ctx: common.UIAbilityContext
+
+  static init(ctx: common.UIAbilityContext) {
+    EventBus.ctx = ctx
+  }
+
+  static emit(event: string, ...args: Object[]) {
+    EventBus.ctx.eventHub.emit(event, args)
+  }
+
+  static on(event: string, callback: Function) {
+    EventBus.ctx.eventHub.on(event, callback)
+  }
+
+  static off(event: string, callback: Function | undefined = undefined) {
+    EventBus.ctx.eventHub.off(event, callback)
+  }
+}

+ 36 - 16
entry/src/main/ets/utils/HttpClient.ets

@@ -1,9 +1,10 @@
 import { http } from '@kit.NetworkKit'
 import { http } from '@kit.NetworkKit'
 import { promptAction } from '@kit.ArkUI'
 import { promptAction } from '@kit.ArkUI'
 import { Rsp } from '../api/rsp/Rsp'
 import { Rsp } from '../api/rsp/Rsp'
-
-// 传输参数token
-export const TOKEN_KEY: string = 'token'
+import { Storage } from './Storage'
+import { EventBus } from './EventBus'
+import { ReqApi } from '../api/req/ReqApi'
+import { Login } from '../api/rsp/Login'
 
 
 // 请求网络的基址
 // 请求网络的基址
 // 外网IP "http://120.27.232.27:48080"
 // 外网IP "http://120.27.232.27:48080"
@@ -12,11 +13,19 @@ export const BASE_URL: string = 'http://120.27.232.27:48080'
 
 
 interface EmptyInterface {}
 interface EmptyInterface {}
 
 
-
-//Next版本不支持在箭头函数上写纯泛型,
-// function requestHttp(url: url地址, method: 请求方法类型,默认为get, data?: 参数类型) : 返回类型是: Promise里面的T类型的数据
-async function requestHttp<T>(url: string = '', method: http.RequestMethod = http.RequestMethod.GET,
-  data?: object): Promise<Rsp<T>> {
+/**
+ * 执行网络请求
+ *
+ * @param url         请求地址
+ * @param method      请求方式
+ * @param data        携带的数据
+ * @param retryCount  尝试次数 默认一次
+ * @returns
+ */
+async function requestHttp<T>(url: string = '',
+  method: http.RequestMethod = http.RequestMethod.GET,
+  data?: object,
+  retryCount: number = 1): Promise<Rsp<T>> {
   // 创建一个网络请求
   // 创建一个网络请求
   const httpRequest = http.createHttp()
   const httpRequest = http.createHttp()
   // 拼接地址
   // 拼接地址
@@ -46,7 +55,7 @@ async function requestHttp<T>(url: string = '', method: http.RequestMethod = htt
     // 请求头
     // 请求头
     header: {
     header: {
       'Content-Type': 'application/json',
       'Content-Type': 'application/json',
-      "Authorization": AppStorage.get(TOKEN_KEY) as string || '',
+      "Authorization": Storage.getToken(),
       "tenant-id": "1" // 租户id
       "tenant-id": "1" // 租户id
     }
     }
   }
   }
@@ -57,14 +66,8 @@ async function requestHttp<T>(url: string = '', method: http.RequestMethod = htt
     console.log(method, '<---', reqUrl, res.responseCode, res.result)
     console.log(method, '<---', reqUrl, res.responseCode, res.result)
     // res.responseCode响应状态码,这里的401还会认为是请求成功
     // res.responseCode响应状态码,这里的401还会认为是请求成功
     if (res.responseCode === 401) {
     if (res.responseCode === 401) {
-      // 401 token超时
-      // 删除持久化数据token
-      AppStorage.set<string>(TOKEN_KEY, '')
       promptAction.openToast({ message: 'token timeout' }).catch()
       promptAction.openToast({ message: 'token timeout' }).catch()
-      // 回登录
-      // router.replaceUrl({ url: 'pages/Login/LoginPage' })
-      // 返回错误 终止
-      return Promise.reject(new Error('token timeout'))
+      return Promise.reject(new Error("token unused"))
     } else if (res.responseCode === 404) {
     } else if (res.responseCode === 404) {
       promptAction.openToast({ message: 'not find' }).catch()
       promptAction.openToast({ message: 'not find' }).catch()
       return Promise.reject(new Error('not find'))
       return Promise.reject(new Error('not find'))
@@ -74,6 +77,23 @@ async function requestHttp<T>(url: string = '', method: http.RequestMethod = htt
       // 再判断返回的状态码进行处理,不是0,200都是失败
       // 再判断返回的状态码进行处理,不是0,200都是失败
       if ([0, 200].includes(apiRsp.code)) {
       if ([0, 200].includes(apiRsp.code)) {
         return apiRsp as Rsp<T>
         return apiRsp as Rsp<T>
+      } else if (apiRsp.code == 401) {
+        // 未登录,需要刷新token
+        const rtRsp = await ReqApi.refreshToken(Storage.getRefreshToken()).catch(() => {
+          const err = new Rsp<Login>()
+          err.code = 401
+          err.msg = "Login expired"
+          return err
+        })
+        if ([0, 200].includes(rtRsp.code)) {
+          Storage.setToken(rtRsp.data?.accessToken ?? "")
+          Storage.setRefreshToken(rtRsp.data?.refreshToken ?? "")
+          return requestHttp(url, method, data)
+        } else {
+          EventBus.emit("EVENT_LOGOUT")
+          promptAction.openToast({ message: apiRsp.msg }).catch()
+          return Promise.reject(new Error(apiRsp.msg))
+        }
       } else {
       } else {
         promptAction.openToast({ message: apiRsp.msg }).catch()
         promptAction.openToast({ message: apiRsp.msg }).catch()
         return Promise.reject(new Error(apiRsp.msg))
         return Promise.reject(new Error(apiRsp.msg))

+ 9 - 8
entry/src/main/ets/utils/Storage.ets

@@ -75,30 +75,31 @@ export class Storage {
   }
   }
 
 
   /**
   /**
-   * 将用户名存储到本地
+   * 将登录时携带的刷新token存储到本地
    *
    *
    * @param value
    * @param value
    */
    */
-  static setUsername(value: string) {
+  static setRefreshToken(value: string) {
     try {
     try {
-      Storage.instance.putSync("username", value)
+      Storage.instance.putSync("refresh_token", value)
       Storage.instance.flushSync()
       Storage.instance.flushSync()
     } catch (error) {
     } catch (error) {
-      console.log("Storage", "setUsername() failed", error)
+      console.log("Storage", "setRefreshToken() failed", error)
     }
     }
   }
   }
 
 
   /**
   /**
-   * 获取用户名
+   * 获取存储本地的刷新Token
    *
    *
    * @returns
    * @returns
    */
    */
-  static getUsername(): string {
+  static getRefreshToken(): string {
     try {
     try {
-      return Storage.instance.getSync('username', "") as string
+      return Storage.instance.getSync('refresh_token', "") as string
     } catch (error) {
     } catch (error) {
-      console.log("Storage", "getUsername() failed", error)
+      console.log("Storage", "getRefreshToken() failed", error)
       return ""
       return ""
     }
     }
   }
   }
+
 }
 }

+ 27 - 13
entry/src/main/ets/vm/VMHome.ets

@@ -1,27 +1,43 @@
-import { Storage } from "../utils/Storage"
+import { ReqApi } from '../api/req/ReqApi'
+import { User } from '../api/rsp/User'
 
 
 @Observed
 @Observed
 export class VMHome {
 export class VMHome {
   // 底部导航栏选择的位置
   // 底部导航栏选择的位置
   tabIndex: number = 0
   tabIndex: number = 0
   // 顶部用户名
   // 顶部用户名
-  username: string = ""
+  user: User = new User()
   // 是否刷新中
   // 是否刷新中
-  isRefreshing: boolean = false
+  isTabHomeRefreshing: boolean = false
 
 
   /**
   /**
    * 初始化首页数据
    * 初始化首页数据
    */
    */
-  init() {
-    // 更新用户名
-    this.username = Storage.getUsername()
+  async init() {
+    this.refreshAllData()
   }
   }
 
 
-  onRefresh() {
-    this.isRefreshing = true
-    setTimeout(() => {
-      this.isRefreshing = false
-    }, 3000)
+  /**
+   * 刷新首页所有数据
+   */
+  private async refreshAllData(): Promise<boolean> {
+    try {
+      // 获取权限和用户信息
+      const upRsp = await ReqApi.getUserPermission()
+      this.user = upRsp.data?.user ?? new User()
+    } catch (e) {
+      return false
+    }
+    return true
+  }
+
+  onTabHomeRefresh() {
+    this.isTabHomeRefreshing = true
+    this.refreshAllData().then(() => {
+      setTimeout(() => {
+        this.isTabHomeRefreshing = false
+      }, 1000)
+    })
   }
   }
 
 
   /**
   /**
@@ -31,6 +47,4 @@ export class VMHome {
   updateTabIndex(index: number) {
   updateTabIndex(index: number) {
     this.tabIndex = index
     this.tabIndex = index
   }
   }
-
-
 }
 }

+ 1 - 1
entry/src/main/ets/vm/VMLogin.ets

@@ -34,7 +34,7 @@ export class VMLogin {
     ReqApi.login(this.account.trim(), this.code).then((rsp) => {
     ReqApi.login(this.account.trim(), this.code).then((rsp) => {
       Storage.setLogin(true)
       Storage.setLogin(true)
       Storage.setToken(rsp.data?.accessToken ?? "")
       Storage.setToken(rsp.data?.accessToken ?? "")
-      Storage.setUsername(rsp.data?.nickname ?? "")
+      Storage.setRefreshToken(rsp.data?.refreshToken ?? "")
       Loading.hideLoading()
       Loading.hideLoading()
       promptAction.openToast({ message: '登录成功' }).catch()
       promptAction.openToast({ message: '登录成功' }).catch()
       skip()
       skip()

+ 4 - 0
entry/src/main/resources/base/element/color.json

@@ -3,6 +3,10 @@
     {
     {
       "name": "main",
       "name": "main",
       "value": "#FFA500"
       "value": "#FFA500"
+    },
+    {
+      "name": "text",
+      "value": "#333333"
     }
     }
   ]
   ]
 }
 }

+ 1 - 0
entry/src/main/resources/base/media/back.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="1766112384912" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="8239" xmlns:xlink="http://www.w3.org/1999/xlink" width="32" height="32"><path d="M229.974 468.566c-23.841 24.422-23.841 64.015 0 88.441l434.358 445.964c23.836 24.416 62.495 24.416 86.341 0 23.852-24.433 23.852-64.019 0-88.442L359.388 512.787l391.285-401.744c23.852-24.426 23.852-64.019 0-88.436-23.836-24.432-62.495-24.432-86.341 0L229.974 468.566z" fill="#2c2c2c" p-id="8240"></path></svg>

+ 1 - 0
entry/src/main/resources/base/media/camera.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="1767168365572" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="6181" xmlns:xlink="http://www.w3.org/1999/xlink" width="32" height="32"><path d="M860.414581 207.449017 509.333781 207.449017c0-52.808332-43.003528-95.81186-95.81186-95.81186l-63.817235 0c-52.808332 0-95.81186 43.003528-95.81186 95.81186L158.424996 207.449017c-52.808332 0-95.81186 43.003528-95.81186 95.81186l0 510.53788c0 52.808332 43.003528 95.81186 95.81186 95.81186l701.989585 0c52.808332 0 95.81186-43.003528 95.81186-95.81186L956.22644 303.260877C956.054426 250.452545 913.050899 207.449017 860.414581 207.449017zM509.333781 749.981522c-105.616664 0-191.451705-85.835041-191.451705-191.451705s85.835041-191.451705 191.451705-191.451705 191.451705 85.835041 191.451705 191.451705S614.950445 749.981522 509.333781 749.981522zM812.422644 430.895347c-26.490173 0-47.819923-21.501764-47.819923-47.819923s21.501764-47.819923 47.819923-47.819923c26.490173 0 47.819923 21.501764 47.819923 47.819923S838.912817 430.895347 812.422644 430.895347z" fill="#575B66" p-id="6182"></path></svg>

+ 1 - 0
entry/src/main/resources/base/media/logout.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="1767167319997" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="4988" xmlns:xlink="http://www.w3.org/1999/xlink" width="32" height="32"><path d="M573.2 646.5H309.8c-12.6 0-20.8-5.8-22.9-16.1-0.4-2.1-0.4-4.2-0.4-6.4V397.2c0-14.3 7.8-22 22.3-22H573.1v-6.9-201.8c0-9.3 4.4-16.6 11.9-19.5 8.6-3.3 16.2-1.8 22.7 5.1 3.7 3.9 7.8 7.5 11.6 11.4 48.2 48.1 96.3 96.2 144.5 144.2 61.9 61.7 123.7 123.4 185.6 185.2 10.3 10.3 10.4 21.1 0.2 31.2-88.5 88.4-177 176.8-265.6 265.1-25.2 25.1-50.5 50.1-75.7 75.2-6.5 6.5-13.7 9.3-22.5 6-8.6-3.3-12.6-10-12.6-20.7V646.5z m-159-497.3v76.4H212.9c-41 0-71.3 30.3-71.3 71.4 0 142.3 0.3 284.6-0.2 426.9-0.1 37.7 28.5 64.8 55 69.7 5.9 1.1 11.9 1.6 17.9 1.6 64.2 0.1 128.4 0.1 192.6 0.1h7.2v76c-0.9 0.2-2 0.6-3 0.6-68.2 0-136.5 0.7-204.7-0.3-66.7-1-125.7-51.6-138.5-117.1-1.8-9.2-2.7-18.8-2.7-28.2-0.2-143.8-0.5-287.7 0.1-431.5 0.3-60.1 30.1-103.2 82.2-131.2 18.4-9.9 38.7-14.4 59.6-14.4 67.7-0.2 135.3-0.1 203-0.1 1.1 0 2.3 0.1 4.1 0.1z m0 0" p-id="4989"></path></svg>