15 Commits 986dacf170 ... 3baa90e99e

Autor SHA1 Mensagem Data
  YuJing 3baa90e99e fix: 2 meses atrás
  YuJing 8982bfc38e fix: 2 meses atrás
  YuJing 7322ea3cfb fix: 2 meses atrás
  YuJing 0956ad927d fix: 2 meses atrás
  YuJing ec2ba51c29 fix: 2 meses atrás
  YuJing 2fc187cccc fix: 修改 app 的 icon 和 开屏图标 2 meses atrás
  YuJing 02c16d0e2c feat: 2 meses atrás
  YuJing 64643cd472 feat: 2 meses atrás
  YuJing 4961cb6e5b feat: 2 meses atrás
  YuJing 78bf802f48 feat: 2 meses atrás
  YuJing 670255b7a1 feat: 2 meses atrás
  YuJing 82917a025c feat: 2 meses atrás
  YuJing 307986ed11 feat: 2 meses atrás
  YuJing 81f5429628 feat: 初始化项目 2 meses atrás
  YuJing ed67ac5317 Changes 2 meses atrás
78 arquivos alterados com 3435 adições e 231 exclusões
  1. 1 1
      AppScope/app.json5
  2. BIN
      AppScope/resources/base/media/app_icon.png
  3. BIN
      AppScope/resources/base/media/background.png
  4. BIN
      AppScope/resources/base/media/foreground.png
  5. 3 3
      build-profile.json5
  6. 2 1
      commons/basic/src/main/ets/apis/YTRequest.ets
  7. 29 13
      commons/basic/src/main/ets/apis/YTUserRequest.ets
  8. 7 3
      commons/basic/src/main/ets/components/generalComp/AgreePrivacy.ets
  9. 3 1
      commons/basic/src/main/ets/components/generalComp/YTButton.ets
  10. 2 1
      commons/basic/src/main/ets/components/generalComp/YTHeader.ets
  11. 5 0
      commons/basic/src/main/ets/components/generalComp/YtDoubleConfirm.ets
  12. 60 1
      commons/basic/src/main/ets/constants/index.ets
  13. 1 0
      commons/basic/src/main/ets/utils/YTRequest.ets
  14. 2 4
      features/feature/Index.ets
  15. 50 0
      features/feature/src/main/ets/apis/ApiUrl.ets
  16. 113 0
      features/feature/src/main/ets/apis/DiaryApi.ets
  17. 70 0
      features/feature/src/main/ets/components/DiaryDatePicker.ets
  18. 179 0
      features/feature/src/main/ets/components/DiaryTimePicker.ets
  19. 34 0
      features/feature/src/main/ets/components/DiaryTitleItem.ets
  20. 49 0
      features/feature/src/main/ets/components/DoubleConfirm.ets
  21. 48 0
      features/feature/src/main/ets/components/LoginComponent.ets
  22. 119 0
      features/feature/src/main/ets/models/BasicDataSource.ets
  23. 8 0
      features/feature/src/main/ets/models/DateInfo.ets
  24. 35 0
      features/feature/src/main/ets/models/index.ets
  25. 23 0
      features/feature/src/main/ets/pages/DiaryDetailPage.ets
  26. 239 0
      features/feature/src/main/ets/pages/DiarySearchPage.ets
  27. 522 0
      features/feature/src/main/ets/pages/IncreaseDiaryPage.ets
  28. 105 0
      features/feature/src/main/ets/utils/DateUtils.ets
  29. 291 0
      features/feature/src/main/ets/view/DiaryView.ets
  30. 0 6
      features/feature/src/main/ets/view/MainView.ets
  31. 495 0
      features/feature/src/main/ets/view/RecodView.ets
  32. 0 6
      features/feature/src/main/ets/view/SecondView.ets
  33. 0 6
      features/feature/src/main/ets/view/ThirdView.ets
  34. 147 0
      features/feature/src/main/ets/viewModels/DiaryViewModel.ets
  35. 239 0
      features/feature/src/main/ets/viewModels/RecodeViewModel.ets
  36. 1 0
      features/feature/src/main/resources/base/media/Diary_DateOpen.svg
  37. BIN
      features/feature/src/main/resources/base/media/Diary_Entry.png
  38. BIN
      features/feature/src/main/resources/base/media/Diary_cancel.png
  39. 4 0
      features/feature/src/main/resources/base/media/Diary_close.svg
  40. BIN
      features/feature/src/main/resources/base/media/RecodeTitle.png
  41. BIN
      features/feature/src/main/resources/base/media/RecodeView_Bg.png
  42. 4 0
      features/feature/src/main/resources/base/media/Search.svg
  43. 12 0
      features/feature/src/main/resources/base/media/add.svg
  44. BIN
      features/feature/src/main/resources/base/media/add_Img.png
  45. 1 0
      features/feature/src/main/resources/base/media/back.svg
  46. 10 0
      features/feature/src/main/resources/base/media/calendar.svg
  47. BIN
      features/feature/src/main/resources/base/media/close.png
  48. 10 0
      features/feature/src/main/resources/base/media/del.svg
  49. 12 0
      features/feature/src/main/resources/base/media/photoAlbum.svg
  50. 10 1
      features/feature/src/main/resources/base/profile/router_map.json
  51. 5 2
      features/user/src/main/ets/components/LoginInput.ets
  52. 2 3
      features/user/src/main/ets/components/Terms.ets
  53. 159 0
      features/user/src/main/ets/pages/ChangePassword.ets
  54. 45 39
      features/user/src/main/ets/pages/LoginPage.ets
  55. 1 2
      features/user/src/main/ets/pages/Privacy.ets
  56. 61 38
      features/user/src/main/ets/pages/SettingPage.ets
  57. 7 1
      features/user/src/main/ets/pages/SuggestionPage.ets
  58. 1 1
      features/user/src/main/ets/pages/UserAgreement.ets
  59. 19 6
      features/user/src/main/ets/views/LoginView.ets
  60. 145 69
      features/user/src/main/ets/views/Mine.ets
  61. 13 2
      features/user/src/main/ets/views/RegisterOrResetPassView.ets
  62. BIN
      features/user/src/main/resources/base/media/Mine_Bg.png
  63. 1 0
      features/user/src/main/resources/base/media/diary_back.svg
  64. BIN
      features/user/src/main/resources/base/media/loginPage_Bg.png
  65. BIN
      features/user/src/main/resources/base/media/loginPage_Bg_left.png
  66. BIN
      features/user/src/main/resources/base/media/loginPage_Bg_right.png
  67. 7 0
      features/user/src/main/resources/base/profile/router_map.json
  68. 10 1
      products/entry/src/main/ets/entryability/EntryAbility.ets
  69. 13 19
      products/entry/src/main/ets/pages/Index.ets
  70. 1 1
      products/entry/src/main/resources/base/element/string.json
  71. BIN
      products/entry/src/main/resources/base/media/Diary_Icon_0.png
  72. BIN
      products/entry/src/main/resources/base/media/Diary_Icon_1.png
  73. BIN
      products/entry/src/main/resources/base/media/My_Icon_0.png
  74. BIN
      products/entry/src/main/resources/base/media/My_Icon_1.png
  75. BIN
      products/entry/src/main/resources/base/media/Recode_Icon_0.png
  76. BIN
      products/entry/src/main/resources/base/media/Recode_Icon_1.png
  77. BIN
      products/entry/src/main/resources/base/media/startIcon.png
  78. BIN
      sign/朝暮日记调试证书Debug.p7b

+ 1 - 1
AppScope/app.json5

@@ -1,6 +1,6 @@
 {
   "app": {
-    "bundleName": "com.ytpm.ltlab",
+    "bundleName": "com.ytpm.zmrj",
     "vendor": "example",
     "versionCode": 1000000,
     "versionName": "1.0.0",

BIN
AppScope/resources/base/media/app_icon.png


BIN
AppScope/resources/base/media/background.png


BIN
AppScope/resources/base/media/foreground.png


+ 3 - 3
build-profile.json5

@@ -5,11 +5,11 @@
         "name": "default",
         "material": {
           "storeFile": "sign/basic.p12",
-          "storePassword": "000000181F0EECD983295AB4504A961E19D1B5914CB198FA414395A09865788F96EFF93C84981A55",
+          "storePassword": "00000018037629724E3117C3F352DE651A3DA377F66B3425918FC935209E426802F107E5600A05AD",
           "keyAlias": "yt112233",
-          "keyPassword": "0000001871572C6DAC842AAE8EF9A99F0F746307476E0F0ACF919CC12B0F81467CF5B0CCDBF97E2D",
+          "keyPassword": "000000189B8E05080F3748E674C733C8454FB661510188FD202AA49D0D43F39F8212FF3BA5AB3890",
           "signAlg": "SHA256withECDSA",
-          "profile": "sign/聊天恋爱宝调试证书.p7b",
+          "profile": "sign/朝暮日记调试证书Debug.p7b",
           "certpath": "sign/调试证书.cer"
         }
       }

+ 2 - 1
commons/basic/src/main/ets/apis/YTRequest.ets

@@ -13,7 +13,8 @@ import { yTRouter } from '../utils/YTRouter';
 
 // export const baseURL: string = 'https://hm-test.ytpm.net/prod-api'
 
-export const baseURL: string = 'http://192.168.1.160:9900'
+// export const baseURL: string = 'http://192.168.1.160:48099/'
+export const baseURL: string = 'https://hm.ytpm.net/prod-diary/'
 
 export const instance = axios.create({
   baseURL,

+ 29 - 13
commons/basic/src/main/ets/apis/YTUserRequest.ets

@@ -1,11 +1,11 @@
 import { IBestToast } from '@ibestservices/ibest-ui'
-import { AppStorageKeyCollect } from '../constants'
+import { AppStorageKeyCollect, YTUserUrl } from '../constants'
 import { ReqString, ResultCallBack } from '../models'
 import { LoginCollect } from '../models/LoginCollect'
 import { UserInfo, userInfo } from '../models/UserInfo'
 import { yTRouter } from '../utils/YTRouter'
 import { YTRequest } from './YTRequest'
-import { YTLog } from '../../../../Index'
+import { YTLog, yTToast } from '../../../../Index'
 import { AxiosProgressEvent, FormData } from '@ohos/axios'
 import { YTDate } from '../utils/FormatDate'
 import { HuaweiAuthPlugin } from '../utils/HuaWeiAuthPlugin'
@@ -15,7 +15,7 @@ export class YTUserRequest extends YTRequest {
   //获取验证码
   static getLoginCaptcha(phonenumber: string, result: ResultCallBack<LoginCollect>) {
     YTUserRequest.post<LoginCollect, LoginCollect>(
-      `/warehouseApUser/sendSmsCode`,
+      YTUserUrl.SEND_SMS_CODE,
       new LoginCollect('login')
         .setPhonenumber(phonenumber)
     )
@@ -30,11 +30,13 @@ export class YTUserRequest extends YTRequest {
   //验证码登录
   static phonenumberLogin(param: LoginCollect, result?: ResultCallBack<UserInfo>) {
     if (param.getUuid() !== undefined) {
-      YTUserRequest.post<ReqString, LoginCollect>(`/warehouseApUser/phoneLogin`, param)
+      YTUserRequest.post<ReqString, LoginCollect>(YTUserUrl.PHONE_LOGIN, param)
         .then(res => {
           userInfo.setToken(res[AppStorageKeyCollect.TOKEN])
           YTUserRequest.refreshUserInfo((res) => {
-            IBestToast.show({ message: '登录成功' })
+            setTimeout(() => {
+              IBestToast.show({ message: '登录成功' })
+            }, 500)
             yTRouter.routerBack()
             result?.(res)
           })
@@ -47,7 +49,7 @@ export class YTUserRequest extends YTRequest {
   //注册
   static register(param: LoginCollect) {
     if (param.getUuid() !== undefined) {
-      YTUserRequest.post<ReqString, LoginCollect>(`/warehouseApUser/phoneSave`, param)
+      YTUserRequest.post<ReqString, LoginCollect>(YTUserUrl.PHONE_SAVE, param)
         .then(res => {
           userInfo.setToken(res[AppStorageKeyCollect.TOKEN])
           YTUserRequest.refreshUserInfo(() => {
@@ -62,7 +64,7 @@ export class YTUserRequest extends YTRequest {
 
   //密码登录
   static passwordLogin(param: LoginCollect, result?: ResultCallBack<UserInfo>) {
-    YTUserRequest.post<ReqString, LoginCollect>(`/warehouseApUser/passwordLogin`, param)
+    YTUserRequest.post<ReqString, LoginCollect>(YTUserUrl.PASSWORD_LOGIN, param)
       .then(res => {
         userInfo.setToken(res[AppStorageKeyCollect.TOKEN])
         YTUserRequest.refreshUserInfo((res) => {
@@ -75,7 +77,7 @@ export class YTUserRequest extends YTRequest {
 
   //重置密码
   static resetPassword(param: LoginCollect, result?: ResultCallBack<undefined>) {
-    YTUserRequest.post<ReqString, LoginCollect>(`/warehouseApUser/resetPwd`, param)
+    YTUserRequest.post<ReqString, LoginCollect>(YTUserUrl.RESET_PWD, param)
       .then(() => {
         result?.()
       })
@@ -88,7 +90,7 @@ export class YTUserRequest extends YTRequest {
       HuaweiAuthPlugin.requestAuth()
         .then(code => {
           instance.setCode(code!)
-          YTUserRequest.post<ReqString, LoginCollect>(`/warehouseApUser/hmLogin`,
+          YTUserRequest.post<ReqString, LoginCollect>(YTUserUrl.HM_LOGIN,
             instance)
             .then(data => {
               const token = data['token']
@@ -119,7 +121,7 @@ export class YTUserRequest extends YTRequest {
 
   //刷新用户信息
   static refreshUserInfo(result?: ResultCallBack<UserInfo>) {
-    YTUserRequest.post<UserInfo, null>(`/warehouseApUser/info`)
+    YTUserRequest.post<UserInfo, null>(YTUserUrl.USER_INFO)
       .then(res => {
         userInfo.setUserInfoAndLogin(res)
         YTLog.info(userInfo)
@@ -163,7 +165,7 @@ export class YTUserRequest extends YTRequest {
     })
       .then(res => {
         const url = res['url']
-        YTUserRequest.post<null, ReqString>(`/warehouseApUser/modifyMemberIcon`,
+        YTUserRequest.post<null, ReqString>(YTUserUrl.MODIFY_MEMBER_ICON,
           { 'memberIcon': url })
           .then(() => {
             success()
@@ -180,7 +182,7 @@ export class YTUserRequest extends YTRequest {
 
   // 修改用户昵称
   static changeNickname(name: string, success: () => void) {
-    YTUserRequest.post<null, ReqString>(`/warehouseApUser/modifyMemberName`,
+    YTUserRequest.post<null, ReqString>(YTUserUrl.MODIFY_MEMBER_NAME,
       { 'memberName': name })
       .then(() => {
         YTUserRequest.refreshUserInfo(() => {
@@ -191,7 +193,7 @@ export class YTUserRequest extends YTRequest {
 
   //问题反馈
   static questionBack(des: string, createBy: string) {
-    YTUserRequest.post<null, ReqString>(`/warehouseBack/saveQuestion`, {
+    YTUserRequest.post<null, ReqString>(YTUserUrl.SAVE_QUESTION, {
       'backQuestion': des,
       'createBy': createBy,
       'createTime': new YTDate().formatDate(),
@@ -204,4 +206,18 @@ export class YTUserRequest extends YTRequest {
         YTLog.error(e)
       })
   }
+
+  // 用户注销账号
+  static logout() {
+    YTUserRequest.post<null, null>(YTUserUrl.LOGIN_OUT)
+      .then(() => {
+        IBestToast.show("注销成功")
+        userInfo.logout()
+        yTToast.hide()
+        yTRouter.routerBack()
+      })
+      .catch((e: Error) => {
+        YTLog.error(e)
+      })
+  }
 }

+ 7 - 3
commons/basic/src/main/ets/components/generalComp/AgreePrivacy.ets

@@ -39,9 +39,13 @@ export function agreePrivacy(item: BasicType<undefined>) {
           item.loginType!.isAgreePrivacy = true
 
           item.loginType?.executeLogin()
-
-
-        }
+        },
+        btlinear: {
+          colors: [ ['#B9FD2A', 0.5], ['#F5FD6D', 1] ],
+          angle: 135
+        },
+        btFontColor: '#212245',
+        btFontSize: 14,
       })
       YTButton({
         btContent: '不同意',

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

@@ -10,6 +10,7 @@ export struct YTButton {
   btBorder?: BorderOptions
   btState: boolean = true
   btBorderRadius: Length | BorderRadiuses | LocalizedBorderRadiuses = this.btHeight / 2
+  btlinear?: LinearGradientOptions
 
   click = () => {
 
@@ -18,7 +19,7 @@ export struct YTButton {
   build() {
     Button(this.btContent)
       .buttonStyle(ButtonStyleMode.NORMAL)
-      .fontSize($r(`app.float.page_text_font_size_${this.btFontSize}`))
+      .fontSize(this.btFontSize)
       .fontColor(this.btFontColor)
       .backgroundColor(this.bgc)
       .height(this.btHeight)
@@ -28,5 +29,6 @@ export struct YTButton {
       .border(this.btBorder)
       .enabled(this.btState)
       .borderRadius(this.btBorderRadius)
+      .linearGradient(this.btlinear)
   }
 }

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

@@ -10,6 +10,7 @@ export struct YTHeader {
   backArrow: boolean = true
   title: string = ''
   bgc: ResourceColor = Color.White
+  fontc: ResourceColor = Color.Black
   click = () => {
     yTRouter.routerBack()
   }
@@ -43,7 +44,7 @@ export struct YTHeader {
           Text(this.title)
             .fontSize(18)
             .fontWeight(700)
-            .fontColor(Color.Black)
+            .fontColor(this.fontc)
         }
       }
       .width('100%')

+ 5 - 0
commons/basic/src/main/ets/components/generalComp/YtDoubleConfirm.ets

@@ -20,6 +20,11 @@ export function yTDoubleConfirm(item: BasicType<undefined>) {
           btWidth: 108,
           btHeight: 37,
           btFontSize: 12,
+          btlinear: {
+            colors: [ ['#B9FD2A', 0.01], ['#F5FD6D', 1] ],
+            angle: 110
+          },
+          btFontColor: Color.Black,
           click: item.click
         }
       )

+ 60 - 1
commons/basic/src/main/ets/constants/index.ets

@@ -37,5 +37,64 @@ export enum AppStorageKeyCollect {
    * @type Record<string, string>
    * @description 验证码登录手机号与验证码
    */
-  CAPTCHA_LOGIN = 'captchaLogin'
+  CAPTCHA_LOGIN = 'captchaLogin',
+
+  /**
+   * @type number
+   * @description 屏幕宽度
+   */
+  SCREEN_WIDTH = 'screenWidth',
+
+  /**
+   * @type number
+   * @description 屏幕高度
+   */
+  SCREEN_HEIGHT = 'screenHeight',
+}
+
+export enum YTUserUrl {
+  /**
+   * @description 获取验证码
+   */
+  SEND_SMS_CODE = `/diaryApUser/sendSmsCode`,
+  /**
+   * @description 验证码登录
+   */
+  PHONE_LOGIN = `/diaryApUser/phoneLogin`,
+  /**
+   * @description 注册
+   */
+  PHONE_SAVE = `/diaryApUser/phoneSave`,
+  /**
+   * @description 密码登录
+   */
+  PASSWORD_LOGIN = `/diaryApUser/passwordLogin`,
+  /**
+   * @description 重置密码
+   */
+  RESET_PWD = `/diaryApUser/resetPwd`,
+  /**
+   * @description 华为登录
+   */
+  HM_LOGIN = `/diaryApUser/hmLogin`,
+  /**
+   * @description 获取用户信息
+   */
+  USER_INFO = `/diaryApUser/info`,
+  /**
+   * @description 修改用户头像
+   */
+  MODIFY_MEMBER_ICON = `/diaryApUser/modifyMemberIcon`,
+  /**
+   * @description 修改用户昵称
+   */
+  MODIFY_MEMBER_NAME = `/diaryApUser/modifyMemberName`,
+  /**
+   * @description 保存问题反馈
+   */
+  SAVE_QUESTION = `/diaryApUser/saveQuestion`,
+  /**
+   * @description 注销账号
+   */
+  LOGIN_OUT = '/api/diaryApUser/member/logout'
 }

+ 1 - 0
commons/basic/src/main/ets/utils/YTRequest.ets

@@ -12,6 +12,7 @@ import { AppStorageKeyCollect } from '../constants';
 import { ReqString } from '../models';
 import { userInfo, UserInfo } from '../models/UserInfo';
 import { HuaweiAuthPlugin } from './HuaWeiAuthPlugin';
+import { YTToast } from './YTToast';
 
 
 export const baseURL: string = 'https://hm-test.ytpm.net/prod-api'

+ 2 - 4
features/feature/Index.ets

@@ -1,8 +1,6 @@
-export { MainView } from './src/main/ets/view/MainView';
+export { RecodView as MainView } from './src/main/ets/view/RecodView';
 
-export { SecondView } from './src/main/ets/view/SecondView';
-
-export { ThirdView } from './src/main/ets/view/ThirdView';
+export { DiaryView as SecondView } from './src/main/ets/view/DiaryView';
 
 export { add } from './src/main/ets/utils/Calc';
 

+ 50 - 0
features/feature/src/main/ets/apis/ApiUrl.ets

@@ -0,0 +1,50 @@
+export class ApiUrl{
+  /**
+   * 删除日记
+   */
+  public static DELETE_DIARY_LOG = '/diaryLog/deleteDiaryLog'
+  /**
+   * 新增日记
+   */
+  public static LOG_SAVE = '/diaryLog/logSave'
+  /**
+   * 查询日记详情
+   */
+  public static QUERY_DIARY_LOG_BY_ID = '/diaryLog/queryDiaryLogById'
+  /**
+   * 查询日记列表
+   */
+  public static QUERY_DIARY_LOG_LIST = '/diaryLog/queryDiaryLogList'
+  /**
+   * 日记搜索
+   */
+  public static DIARY_LOG_SEARCH = '/diaryLog/search'
+  /**
+   * 修改日记
+   */
+  public static UPDATE_DIARY_LOG = '/diaryLog/updateDiaryLog'
+  /**
+   * 删除生活小记录
+   */
+  public static DELETE_NOTE = '/diaryNote/deleteNote'
+  /**
+   * 添加生活小记录
+   */
+  public static NOTE_SAVE = '/diaryNote/noteSave'
+  /**
+   * 查询生活小记录
+   */
+  public static QUERY_BY_NOTE_LIST = '/diaryNote/queryByNoteList'
+  /**
+   * 查询生活小记录对象
+   */
+  public static QUERY_NOTE_BY_ID = '/diaryNote/queryNoteById'
+  /**
+   * 编辑生活小记录
+   */
+  public static UPDATE_NOTE = '/diaryNote/updateNote'
+  /**
+   * 修改生活小记录时间
+   */
+  public static UPDATE_NOTE_TIME = '/diaryNote/updateNoteTime'
+}

+ 113 - 0
features/feature/src/main/ets/apis/DiaryApi.ets

@@ -0,0 +1,113 @@
+import { YTRequest } from "basic";
+import { DiaryData } from "../models";
+import { ApiUrl } from "./ApiUrl";
+
+export class DiaryApi {
+  /**
+   * 删除日记
+   * @param id 日记id
+   * @returns
+   */
+  static deleteDiaryLog(id: number): Promise<boolean> {
+    return YTRequest.delete<boolean>(ApiUrl.DELETE_DIARY_LOG + '?id=' + id)
+  }
+
+  /**
+   * 新增日记
+   * @param params 日记数据结构
+   * @returns
+   */
+  static saveDiaryLog(params: DiaryData): Promise<boolean> {
+    return YTRequest.post<boolean, DiaryData>(ApiUrl.LOG_SAVE, params)
+  }
+
+  /**
+   * 返回对应 id 的日记详情
+   * @param id 日记id
+   * @returns
+   */
+  static queryDiaryLogById(id: number): Promise<DiaryData> {
+    return YTRequest.get<DiaryData>(ApiUrl.QUERY_DIARY_LOG_BY_ID + '?id=' + id)
+  }
+
+  /**
+   * 查询日记列表
+   * @param nowTime 当前时间
+   * @returns 日记列表
+   */
+  static queryDiaryLogList(nowTime: string): Promise<DiaryData[]> {
+    return YTRequest.post<DiaryData[], number>(ApiUrl.QUERY_DIARY_LOG_LIST + '?nowTime=' + nowTime)
+  }
+
+  /**
+   * 日记搜索
+   * @param keyword 标题关键字
+   * @returns 日记列表
+   */
+  static diaryLogSearch(keyword: string): Promise<DiaryData[]> {
+    return YTRequest.get<DiaryData[]>(ApiUrl.DIARY_LOG_SEARCH + '?keyword=' + keyword)
+  }
+
+  /**
+   * 修改日记
+   * @param params 日记数据结构
+   * @returns
+   */
+  static updateDiaryLog(params: DiaryData): Promise<boolean> {
+    return YTRequest.post<boolean, DiaryData>(ApiUrl.UPDATE_DIARY_LOG, params)
+  }
+
+  /**
+   * 删除生活小记录
+   * @param id 生活小记录id
+   * @returns
+   */
+  static deleteNote(id: number): Promise<boolean> {
+    return YTRequest.delete<boolean>(ApiUrl.DELETE_NOTE + '?id=' + id)
+  }
+
+  /**
+   * 添加生活小记录
+   * @param params 生活小记录数据结构
+   * @returns
+   */
+  static saveNote(params: DiaryData): Promise<boolean> {
+    return YTRequest.post<boolean, DiaryData>(ApiUrl.NOTE_SAVE, params)
+  }
+
+  /**
+   * 查询生活小记录
+   * @param nowTime 当前选中的时间
+   * @returns 生活小记录列表
+   */
+  static queryNoteList(nowTime: string): Promise<DiaryData[]> {
+    return YTRequest.get<DiaryData[]>(ApiUrl.QUERY_BY_NOTE_LIST + '?nowTime=' + nowTime)
+  }
+
+  /**
+   * 查询生活小记录对象
+   * @param id 生活小记录id
+   * @returns
+   */
+  static queryNoteById(id: number): Promise<DiaryData> {
+    return YTRequest.get<DiaryData>(ApiUrl.QUERY_NOTE_BY_ID + '?id=' + id)
+  }
+
+  /**
+   * 编辑生活小记录
+   * @param params 生活小记录数据结构
+   * @returns
+   */
+  static updateNote(params: DiaryData): Promise<boolean> {
+    return YTRequest.post<boolean, DiaryData>(ApiUrl.UPDATE_NOTE, params)
+  }
+
+  /**
+   * 修改生活小记录时间
+   * @param params 生活小记录数据结构
+   * @returns
+   */
+  static updateNoteTime(params: DiaryData): Promise<boolean> {
+    return YTRequest.post<boolean, DiaryData>(ApiUrl.UPDATE_NOTE_TIME, params)
+  }
+}

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

@@ -0,0 +1,70 @@
+import { font } from "@kit.ArkUI";
+
+// 日期选择器
+@Component
+export struct DiaryDatePicker {
+  @State selectedDate: Date = new Date();
+
+  private linearInfo: LinearGradientOptions = {
+    colors: [ ['#B9FD2A', 0.01], ['#F5FD6D', 1] ],
+    angle: 150
+  }
+
+  selectDateBack: (date: Date) => void = (date: Date) => {
+    console.log("选择的日期" + date.toLocaleString())
+  }
+
+  build() {
+    Column({space: 10}){
+      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)
+    .backgroundColor(Color.White)
+    .shadow({
+      radius: 10,
+      type: ShadowType.COLOR,
+      color: Color.Black
+    })
+  }
+}

+ 179 - 0
features/feature/src/main/ets/components/DiaryTimePicker.ets

@@ -0,0 +1,179 @@
+import { DateUtils } from "../utils/DateUtils"
+
+@Component
+export struct DiaryTimePicker {
+  @State selectedHour: number = 0
+  @State selectedMinute: number = 0
+  private hourController: SwiperController = new SwiperController()
+  private minuteController: SwiperController = new SwiperController()
+
+  iwidth = 160
+  timeStr: String = DateUtils.formatDateToCustomString(new Date(), true).split(' ')[1]
+
+  // 回调函数
+  onConfirm?: (time: string) => void = (time: string) => {
+    console.log('onConfirm' + time)
+  }
+
+  onCancel?: () => void
+
+  private linearInfo: LinearGradientOptions = {
+    colors: [ ['#B9FD2A', 0.01], ['#F5FD6D', 1] ],
+    angle: 150
+  }
+
+  aboutToAppear(): void {
+    if (this.timeStr) {
+      // 解析时间字符串 'hh:mm'
+      const timeParts = this.timeStr.split(':');
+      if (timeParts.length >= 2) {
+        let hour = parseInt(timeParts[0], 10) - 1;
+        let minute = parseInt(timeParts[1], 10) - 1;
+
+        if (hour < 0) hour = 23
+        if (minute < 0) minute = 59
+
+        // 验证时间有效性
+        if (!isNaN(hour) && !isNaN(minute) && hour >= 0 && hour < 24 && minute >= 0 && minute < 60) {
+          this.selectedHour = hour;
+          this.selectedMinute = minute;
+
+          setTimeout(() => {
+            this.hourController.changeIndex(hour);
+            this.minuteController.changeIndex(minute);
+          }, 0)
+        }
+      }
+    }
+  }
+
+  build() {
+    Column() {
+
+      Row(){
+        Row(){
+          Image($r('app.media.Diary_cancel'))
+            .width(24)
+            .aspectRatio(1)
+        }
+        .borderRadius(36)
+        .backgroundColor('#F5F5F7')
+        .padding({left: 10, right:10})
+        .alignItems(VerticalAlign.Center)
+        .justifyContent(FlexAlign.Center)
+        .onClick(() => {
+          this.onCancel?.()
+        })
+
+        Row(){
+          Image($r('app.media.Diary_Entry'))
+            .width(24)
+            .aspectRatio(1)
+        }
+        .alignItems(VerticalAlign.Center)
+        .justifyContent(FlexAlign.Center)
+        .padding({left: 10, right:10})
+        .borderRadius(36)
+        .linearGradient(this.linearInfo)
+        .onClick(() => {
+          const formattedHour = ((this.selectedHour+1)%24).toString().padStart(2, '0');
+          const formattedMinute = ((this.selectedMinute+1)%60).toString().padStart(2, '0');
+          const formattedTime = `${formattedHour}:${formattedMinute}`;
+          this.onConfirm?.(formattedTime);
+        })
+      }
+      .width("100%")
+      .justifyContent(FlexAlign.SpaceBetween)
+      .padding({ left: 15, right: 15, top: 17})
+
+      Stack({alignContent: Alignment.Center}){
+        Row()
+          .height(50)
+          .width("100%")
+          .linearGradient(this.linearInfo)
+
+        // 时间选择区域
+        Row() {
+          // 小时选择器
+          Column() {
+            Swiper(this.hourController) {
+              ForEach(new Array(24).fill(0), (item: number, index: number) => {
+                Text(`${index.toString().padStart(2, '0')}`)
+                  .fontWeight(FontWeight.Bold)
+                  .fontSize(index === (this.selectedHour+1)%24 ? 16 : 14)
+                  .width('100%')
+                  .height(30)
+                  .fontColor(index === (this.selectedHour+1)%24 ? '#212245' : '#757575')
+                  .textAlign(TextAlign.Center)
+                  .alignSelf(ItemAlign.Center)
+                  .borderRadius(8)
+              })
+            }
+            .borderColor(Color.Transparent)
+            .loop(true)
+            .displayCount(3)
+            .curve(Curve.Linear)
+            .indicator(false)
+            .vertical(true)
+            .nextMargin(1)
+            .prevMargin(1)
+            .onChange((index: number) => {
+              this.selectedHour = index
+            })
+            .align(Alignment.Center)  // 关键:确保选中项居中
+          }
+          .borderColor(Color.Transparent)
+          .layoutWeight(1)
+          .height(150)
+
+          // 分隔符
+          Text(':')
+            .fontSize(24)
+            .fontWeight(FontWeight.Bold)
+            .fontColor('#333333')
+            .alignSelf(ItemAlign.Center)
+
+          // 分钟选择器
+          Column() {
+            Swiper(this.minuteController) {
+              ForEach(new Array(60).fill(0), (item: number, index: number) => {
+                Text(`${index.toString().padStart(2, '0')}`)
+                  .fontSize(index === (this.selectedMinute+1)%60 ? 16 : 14)
+                  .fontWeight(FontWeight.Bold)
+                  .fontColor(index === (this.selectedMinute+1)%60 ? '#212245' : '#757575')
+                  .width('100%')
+                  .height(30)
+                  .textAlign(TextAlign.Center)
+                  .alignSelf(ItemAlign.Center)
+                  .borderRadius(8)
+              })
+            }
+            .loop(true)
+            .displayCount(3)
+            .curve(Curve.Linear)
+            .indicator(false)
+            .vertical(true)
+            .nextMargin(1)
+            .prevMargin(1)
+            .onChange((index: number) => {
+              this.selectedMinute = index
+            })
+            .align(Alignment.Center)  // 关键:确保选中项居中
+          }
+          .layoutWeight(1)
+          .height(150)
+        }
+        .width('100%')
+        .padding({ left: 12, right: 12 })
+      }
+    }
+    .width(this.iwidth)
+    .backgroundColor(Color.White)
+    .borderRadius(20)
+    .shadow({
+      radius: 10,
+      type: ShadowType.COLOR,
+      color: Color.Black
+    })
+  }
+}

+ 34 - 0
features/feature/src/main/ets/components/DiaryTitleItem.ets

@@ -0,0 +1,34 @@
+@Component
+export struct DiaryTitleItem {
+  title: string = ''
+  onClickBack: () => void = () => {}
+  onActionBack: (event: GestureEvent) => void = () => {}
+
+  build() {
+    Column() {
+      Text(this.title)
+        .fontSize(16)
+        .fontWeight(600)
+        .maxLines(1)
+        .textOverflow ({overflow: TextOverflow.Ellipsis})
+    }
+    .height(60)
+    .width("100%")
+    .borderRadius(12)
+    .backgroundColor('#F1F1F1')
+    .alignItems(HorizontalAlign.Start)
+    .justifyContent(FlexAlign.Center)
+    .padding({
+      left: 16,
+      right: 16,
+      top: 17,
+      bottom: 17
+    })
+    .margin({ top: 5, bottom: 5 })
+    .onClick(this.onClickBack)
+    .gesture(
+      LongPressGesture()
+        .onAction(this.onActionBack)
+    )
+  }
+}

+ 49 - 0
features/feature/src/main/ets/components/DoubleConfirm.ets

@@ -0,0 +1,49 @@
+import { BasicType, yTToast } from "basic"
+
+@Builder
+export function DoubleConfirm(item: BasicType<undefined>) {
+  Column() {
+    if(item.text)
+    Text(item.text)
+      .fontSize(16)
+      .fontColor(Color.Black)
+      .margin({ bottom: 18 })
+    if(item.message)
+    Text(item.message)
+      .fontColor($r('sys.color.mask_secondary'))
+      .lineHeight(18)
+      .fontSize(13)
+      .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(() => {
+          yTToast.hide()
+        })
+
+      Text('确定')
+        .fontSize(16)
+        .fontWeight(400)
+        .borderRadius(36)
+        .fontColor(Color.Black)
+        .padding({ left: 36, top: 9, right: 36, bottom: 9})
+        .linearGradient({
+          colors: [ ['#B9FD2A', 0.01], ['#F5FD6D', 1] ],
+          angle: 110
+        })
+        .onClick(item.click)
+    }
+    .justifyContent(FlexAlign.SpaceBetween)
+    .width('100%')
+  }
+  // .height(160)
+  .width(280)
+  .padding({ top: 28, left: 32, right: 32, bottom: 20 })
+  .backgroundColor(Color.White)
+  .borderRadius(8)
+}

+ 48 - 0
features/feature/src/main/ets/components/LoginComponent.ets

@@ -0,0 +1,48 @@
+import { yTRouter } from "basic"
+
+@Component
+export struct LoginComponent {
+  private linearInfo: LinearGradientOptions = {
+    colors: [ ['#B9FD2A', 0.01], ['#F5FD6D', 1] ],
+    angle: 110
+  }
+
+  build() {
+    Column(){
+      Row(){
+        Row(){
+          Text("登录使用全部功能")
+            .fontSize(16)
+            .fontColor('#FFFFFF')
+
+          Row(){
+            Text("马上登录")
+              .fontSize(12)
+              .fontColor('#212245')
+              .onClick(() => {
+                yTRouter.router2LoginPage()
+              })
+          }
+          .borderRadius(24)
+          .linearGradient(this.linearInfo)
+          .padding({
+            top: 10, left: 15, bottom: 10, right: 15
+          })
+        }
+        .width("100%")
+        .borderRadius(16)
+        .backgroundColor('#000000')
+        .alignItems(VerticalAlign.Center)
+        .justifyContent(FlexAlign.SpaceBetween)
+        .padding({ left: 17, right: 11, top: 12, bottom: 12 })
+      }
+      .width("100%")
+      .padding({left: 18, right: 18, bottom: 20 })
+    }
+    .width("100%")
+    .height("100%")
+    .backgroundColor('rgba(255, 255, 255, 0.5)')
+    .justifyContent(FlexAlign.End)
+    .alignItems(HorizontalAlign.Center)
+  }
+}

+ 119 - 0
features/feature/src/main/ets/models/BasicDataSource.ets

@@ -0,0 +1,119 @@
+// 《记录》页面中日历使用的懒加载数据源
+export class BasicDataSource<T> implements IDataSource {
+  private listeners: DataChangeListener[] = [];
+  private dataArray: T[] = [];
+
+
+  // =============================================================
+  // ===================  框架侧调用  ==============================
+  // ===============  接口内部需实现的方法  ==========================
+  // =============================================================
+
+  // 该方法为框架侧调用,为LazyForEach组件向其数据源处添加listener监听
+  registerDataChangeListener(listener: DataChangeListener): void {
+    if (this.listeners.indexOf(listener) < 0) {
+      console.info('add listener');
+      this.listeners.push(listener);
+    }
+  }
+
+  // 该方法为框架侧调用,为对应的LazyForEach组件在数据源处去除listener监听
+  unregisterDataChangeListener(listener: DataChangeListener): void {
+    const pos = this.listeners.indexOf(listener);
+    if (pos >= 0) {
+      console.info('remove listener');
+      this.listeners.splice(pos, 1);
+    }
+  }
+
+  // =============================================================
+  // ===================  程序调用  ===============================
+  // =========== 整合 DataChangeListener 内部的方法 ================
+  // =============================================================
+
+  // 通知LazyForEach组件需要重载所有子组件
+  notifyDataReload(): void {
+    this.listeners.forEach(listener => {
+      listener.onDataReloaded();
+    })
+  }
+
+  // 通知LazyForEach组件需要在index对应索引处添加子组件
+  notifyDataAdd(index: number): void {
+    this.listeners.forEach(listener => {
+      listener.onDataAdd(index);
+    })
+  }
+
+  // 通知LazyForEach组件在index对应索引处数据有变化,需要重建该子组件
+  notifyDataChange(index: number): void {
+    this.listeners.forEach(listener => {
+      listener.onDataChange(index);
+    })
+  }
+
+  // 通知LazyForEach组件需要在index对应索引处删除该子组件
+  notifyDataDelete(index: number): void {
+    this.listeners.forEach(listener => {
+      listener.onDataDelete(index);
+    })
+  }
+
+  // 通知LazyForEach组件将from索引和to索引处的子组件进行交换
+  notifyDataMove(from: number, to: number): void {
+    this.listeners.forEach(listener => {
+      listener.onDataMove(from, to);
+    })
+  }
+
+
+  // =============================================================
+  // ======================  修改数据源  ===========================
+  // ======================== 外部调用 =============================
+  // =============================================================
+  public totalCount(): number {
+    return this.dataArray.length;
+  }
+
+  public getData(index: number): T {
+    return this.dataArray[index];
+  }
+
+  // 在指定的索引处添加一个元素
+  public addData(index: number, data: T): void {
+    this.dataArray.splice(index, 0, data);
+    this.notifyDataAdd(index);
+  }
+
+  // 往监听列表内部添加元素
+  public pushData(data: T): void {
+    this.dataArray.push(data);
+    this.notifyDataAdd(this.dataArray.length - 1);
+  }
+
+  // 往监听列表内部添加元素
+  public unshiftData(data: T): void {
+    this.dataArray.unshift(data);
+    this.notifyDataAdd(0);
+  }
+
+  // 所有数据进行重新赋值
+  public init(data: T[]) {
+    this.dataArray = data
+    this.notifyDataReload()
+  }
+
+  // 传入一个数组, 初始化监听列表 - 在数组尾部追加数据
+  public reloadDataPush(datas: T[]) {
+    datas.forEach(i => {
+      this.pushData(i)
+    })
+  }
+
+  // 传入一个数组, 初始化监听列表
+  public reloadDataUnshift(datas: T[]) {
+    datas.forEach(i => {
+      this.unshiftData(i)
+    })
+  }
+}

+ 8 - 0
features/feature/src/main/ets/models/DateInfo.ets

@@ -0,0 +1,8 @@
+// 日期信息接口定义
+export interface DateInfo {
+  year: number;   // 年份
+  month: number;  // 月份(1-12)
+  day: number;    // 日期(1-31)
+  week: string;   // 星期(中文)
+  id: Date ;    // 唯一标识
+}

+ 35 - 0
features/feature/src/main/ets/models/index.ets

@@ -0,0 +1,35 @@
+/**
+ * 日记详细数据模型
+ */
+export interface DiaryData{
+  // 富文本正文
+  content?: string
+  // 日记日期
+  diaryDate?: string
+  // 日记id
+  id?: number
+  // 图片地址集合
+  imageUrls?: string[]
+  // 日记标题
+  title?: string
+  // 用户id
+  userId?: number
+  // 时间
+  noteTime?: string
+}
+
+export enum PageStatus{
+  DIARY,
+  RECODE
+}
+
+// 常量
+export enum Constant{
+  // 历史搜索记录 key 值
+  HistoricalSearchRecords = 'HISTORICAL_SEARCH_RECORDS'
+}
+
+// 变量
+export class Variable{
+  static pageReadOnly: boolean = false;
+}

+ 23 - 0
features/feature/src/main/ets/pages/DiaryDetailPage.ets

@@ -0,0 +1,23 @@
+import { YTAvoid } from 'basic'
+
+@Component
+struct DiaryDetailPage{
+  @StorageProp(YTAvoid.SAFE_TOP_KEY) safeTop: number = 0
+
+  build(){
+    NavDestination(){
+      Column(){
+        Text("日记详情")
+      }
+    }
+
+  }
+}
+
+@Builder
+function DiaryDetailBuilder() {
+  NavDestination() {
+    DiaryDetailPage()
+  }
+  .hideTitleBar(true)
+}

+ 239 - 0
features/feature/src/main/ets/pages/DiarySearchPage.ets

@@ -0,0 +1,239 @@
+import { IBestToast, YTAvoid, yTRouter } from 'basic'
+import { LengthMetrics } from '@kit.ArkUI'
+import { Constant, DiaryData } from '../models'
+import { DiaryViewModel } from '../viewModels/DiaryViewModel'
+import { DiaryTitleItem } from '../components/DiaryTitleItem'
+
+// 存储历史搜索记录
+PersistentStorage.persistProp<string[]>(Constant.HistoricalSearchRecords, [])
+
+@Component
+struct DiarySearchPage{
+  @StorageProp(YTAvoid.SAFE_TOP_KEY) safeTop: number = 0
+  @State delModel: boolean = false
+  @StorageLink(Constant.HistoricalSearchRecords) historicalSearchRecords: string[] = []
+  @State keyWord: string = ''
+  @State searchList: DiaryData[] = []
+
+  private linearInfo: LinearGradientOptions = {
+    colors: [ ['#B9FD2A', 0.01], ['#F5FD6D', 1] ],
+    angle: 150
+  }
+
+  async onSearch(){
+    if(!this.keyWord) {
+      IBestToast.show('请输入搜索内容')
+      return
+    }
+
+    const targetIndex: number = this.historicalSearchRecords.indexOf(this.keyWord)
+    if(targetIndex !== -1){
+      this.historicalSearchRecords.splice(targetIndex, 1)
+    }
+    this.historicalSearchRecords.unshift(this.keyWord)
+
+    this.searchList = await DiaryViewModel.diaryLogSearch(this.keyWord)
+    if(this.searchList.length === 0) {
+      IBestToast.show('没有搜索结果')
+    }
+  }
+
+  onDelSearch(index: number){
+    this.historicalSearchRecords.splice(index, 1)
+  }
+
+  /**
+   * 跳转日记详情
+   * @param id 日记 id (可选),没有 id 表示新增日记
+   */
+  routerDiaryPage(id?: number) {
+    const pageReadOnly = id ? true : false
+    yTRouter.pushPathByName("IncreaseDiaryPage", {
+      'pageReadOnly': pageReadOnly,
+      'id': id
+    } as Record<string, boolean | number>);
+  }
+
+  aboutToAppear(): void {
+  }
+
+  build(){
+    NavDestination(){
+      Column(){
+        // Title
+        Row(){
+          Image($r("app.media.back"))
+            .width(20)
+            .aspectRatio(1)
+            .onClick(() => {
+              yTRouter.pop()
+            })
+        }
+        .width('100%')
+        .alignItems(VerticalAlign.Top)
+        .justifyContent(FlexAlign.Start)
+        .padding({top: 10, bottom: 10})
+
+        // 搜索框
+        Row({space: 15}){
+          Image($r("app.media.Search"))
+            .width(18)
+            .aspectRatio(1)
+
+          TextInput({ placeholder: "输入日记标题", text: $$this.keyWord })
+            .padding(0)
+            .fontSize(16)
+            .layoutWeight(1)
+            .borderRadius(0)
+            .placeholderColor('#ff777272')
+            .placeholderFont({ size: 16 })
+            .backgroundColor(Color.Transparent)
+            .caretColor('app.color.main_ac_color_dark')
+            .onSubmit(()=>{ this.onSearch() })
+
+
+          if(this.keyWord.length > 0) {
+            Image($r('app.media.Diary_close'))
+              .width(25)
+              // .padding(5)
+              .aspectRatio(1)
+              .borderRadius(15)
+              .onClick(() => {
+                this.keyWord = ''
+                this.searchList = []
+              })
+          }
+
+          Text("确认")
+            .borderRadius(32)
+            .linearGradient(this.linearInfo)
+            .padding({ left: 17, top: 5.5, right: 17, bottom: 5.5 })
+            .onClick(() => { this.onSearch() })
+
+        }
+        .width("100%")
+        .alignItems(VerticalAlign.Center)
+        .border({ width: { bottom: 1 } })
+        .padding({ bottom: 21, top: 13 })
+
+        // 历史记录
+        Column({space: 15}){
+          if(this.searchList.length !== 0) {
+            Column(){
+              List(){
+                ForEach(this.searchList, (item: DiaryData, i: number) => {
+                  ListItem() {
+                    DiaryTitleItem({
+                      title: item.title,
+                      onClickBack: () => {
+                        this.routerDiaryPage(item.id)
+                      }
+                    })
+                  }
+                }, (item: DiaryData) => item.id?.toString())
+              }
+              .width("100%")
+              .height("100%")
+              .scrollBar(BarState.Off)
+            }
+            .width("100%")
+            .layoutWeight(1)
+            .padding({bottom: 20})
+
+          } else if(this.historicalSearchRecords.length > 0){
+            this.searchTitleBar()
+
+            Flex({wrap: FlexWrap.Wrap, space: { main: new LengthMetrics(8), cross: new LengthMetrics(8)}}){
+              ForEach(this.historicalSearchRecords, (item: string, index: number) => {
+                this.keyWordItem(item, index)
+              })
+            }
+          } else {
+            // 搜索历史
+            this.searchTitleBar()
+
+            Column({ space: 5 }){
+              Image($r('app.media.Search'))
+                .width(80)
+                .aspectRatio(1)
+
+              Text("暂无搜索历史")
+            }
+            .width("100%")
+            .padding({ top: 100 })
+            .alignItems(HorizontalAlign.Center)
+          }
+        }
+        .width("100%")
+        .layoutWeight(1)
+        .padding({ top: 35 })
+      }
+      .padding({ top: this.safeTop, left: 24, right: 24 })
+    }
+  }
+
+  // 搜索记录关键字
+  @Builder
+  keyWordItem(keyWord: string, index: number){
+    Row({space: 8}){
+      Text(keyWord)
+        .fontSize(16)
+
+      if(this.delModel){
+        Image($r('app.media.close'))
+          .width(16)
+          .aspectRatio(1)
+          .padding(2)
+      }
+    }
+    .borderRadius(8)
+    .backgroundColor("#F7F7F7")
+    .padding({top: 8, bottom: 8, left: 25, right: this.delModel ? 5 : 25})
+    .onClick(() => {
+      if(this.delModel) {
+        this.onDelSearch(index)
+        return;
+      }
+      this.keyWord = keyWord
+      this.onSearch()
+    })
+  }
+
+  // 搜索记录标题栏
+  @Builder
+  searchTitleBar(){
+    // 搜索历史
+    Row(){
+      Text("搜索历史")
+        .fontSize(16)
+        .fontColor(Color.Black)
+
+      Row(){
+        if(this.delModel) {
+          Text("取消")
+            .fontSize(14)
+            .fontColor('#ff625a5a')
+        } else {
+          Image($r('app.media.del'))
+            .width(20)
+            .height(30)
+        }
+      }
+      .onClick(() => {
+        this.delModel = !this.delModel
+      })
+    }
+    .height(30)
+    .width("100%")
+    .justifyContent(FlexAlign.SpaceBetween)
+
+  }
+}
+
+@Builder
+function DiarySearchBuilder() {
+  NavDestination() {
+    DiarySearchPage()
+  }
+  .hideTitleBar(true)
+}

+ 522 - 0
features/feature/src/main/ets/pages/IncreaseDiaryPage.ets

@@ -0,0 +1,522 @@
+import { IBestToast, YTAvoid, yTRouter, yTToast } from 'basic'
+import { photoAccessHelper } from '@kit.MediaLibraryKit';
+import { DiaryDatePicker } from '../components/DiaryDatePicker';
+import { DiaryData, PageStatus, Variable } from '../models';
+import { DiaryViewModel } from '../viewModels/DiaryViewModel';
+import { DateUtils } from '../utils/DateUtils';
+import { DiaryTimePicker } from '../components/DiaryTimePicker';
+import { RecodeViewModel } from '../viewModels/RecodeViewModel';
+import { DoubleConfirm } from '../components/DoubleConfirm';
+import { Context } from '@ohos.abilityAccessCtrl';
+import { common } from '@kit.AbilityKit';
+import image from '@ohos.multimedia.image';
+
+/**
+ * 新增/编辑 日记
+ */
+@Component
+struct IncreaseDiaryPage {
+  @StorageProp(YTAvoid.SAFE_TOP_KEY) safeTop: number = 0
+  // 页面编辑中的状态 - 默认为可编辑
+  @State pageReadOnly: boolean = false
+  // 时间选择器 开启控制
+  @State showTimePicker: boolean = false
+  // 日期选择器 开启控制
+  @State showDatePicker: boolean = false
+  // 日记详细数据
+  @State diaryData: DiaryData = {};
+  // 页面状态, 默认为日记
+  @State pageStatus: PageStatus = PageStatus.DIARY
+
+  private linearInfo: LinearGradientOptions = {
+    colors: [ ['#B9FD2A', 0.01], ['#F5FD6D', 1] ],
+    angle: 150
+  }
+  private conText: Context = this.getUIContext().getHostContext() as Context
+
+
+
+  /**
+   * 选择图片
+   */
+  async photoSelect(){
+    let PhotoSelectOptions = new photoAccessHelper.PhotoSelectOptions();
+    PhotoSelectOptions.MIMEType = photoAccessHelper.PhotoViewMIMETypes.IMAGE_TYPE;
+    PhotoSelectOptions.maxSelectNumber = 1;
+    let photoPicker = new photoAccessHelper.PhotoViewPicker();
+
+    let photoSelectResult: photoAccessHelper.PhotoSelectResult = await photoPicker.select(PhotoSelectOptions);
+    let photoList = photoSelectResult.photoUris;
+    if (photoList.length > 0) {
+      if(!this.diaryData.imageUrls) this.diaryData.imageUrls = [];
+      this.diaryData.imageUrls = [...this.diaryData.imageUrls, ...photoList];
+    }
+  }
+
+  /**
+   * 点击 完成 按钮
+   */
+  async onComplete() {
+    if(this.pageReadOnly) {
+      this.pageReadOnly = false;
+      Variable.pageReadOnly = false
+      return;
+    }
+
+    if(!this.diaryData.title || !this.diaryData.content) {
+      IBestToast.show({ message: '请填写标题和内容' })
+      return;
+    }
+
+    // 浅拷贝
+    let diaryData = JSON.parse(JSON.stringify(this.diaryData)) as DiaryData
+    // 统一时间格式
+
+    // 图片上传逻辑
+    if (diaryData.imageUrls && diaryData.imageUrls.length != 0) {
+      console.log("图片上传中" + JSON.stringify(diaryData.imageUrls))
+
+      // 使用map创建Promise数组,然后用Promise.all等待所有上传完成
+      const uploadPromises = diaryData.imageUrls?.map(async (url: string) => {
+        if(url?.split(':')?.[0] === 'file') {
+          console.log("开始上传图片 " + url)
+          let _url = await DiaryViewModel.uploadImage(this.conText, url)
+          return _url
+        }
+        return url
+      })
+
+      // 等待所有上传完成
+      const imageUrl = await Promise.all(uploadPromises)
+      console.log("图片上传结果" + JSON.stringify(imageUrl))
+
+      // 将处理后的URL赋值回diaryData
+      diaryData.imageUrls = imageUrl
+    }
+
+
+    // 判断是否是新增日记 - 有 id 时为 修改日记
+    if(!this.diaryData.id) {
+      diaryData.diaryDate += ':00'
+      this.onSubmit(diaryData)
+    } else {
+      this.onUpdate(diaryData)
+    }
+  }
+
+  // 新建 日记、小记录
+  async onSubmit(data: DiaryData) {
+    let ans: boolean = false
+    console.log("保存")
+
+    if(this.pageStatus === PageStatus.DIARY) {
+      ans = await DiaryViewModel.saveDiaryLog(data)
+      console.log("日记-保存结果" + JSON.stringify(ans))
+    } else {
+      data.noteTime = data.diaryDate
+      ans = await RecodeViewModel.saveNote(data)
+      console.log("小记录-保存结果" + JSON.stringify(ans))
+    }
+
+    if(ans) {
+      IBestToast.show({ message: '保存成功' })
+      yTRouter.routerBack()
+    } else {
+      IBestToast.show({ message: '保存失败' })
+    }
+  }
+
+  // 修改日记、小记录
+  async onUpdate(data: DiaryData) {
+    let ans: boolean = false
+    console.log("修改")
+    if(this.pageStatus === PageStatus.DIARY) {
+      let time = DateUtils.formatDateToCustomString(new Date()).split(' ')[1]
+      data.diaryDate = data.diaryDate?.split(' ')[0] + ' ' +time
+      ans = await DiaryViewModel.updateDiaryLog(data)
+      console.log("日记-修改结果" + ans)
+    } else {
+      data.noteTime = data.diaryDate + ':00'
+      ans = await RecodeViewModel.updateNote(data)
+      console.log("小记录-修改结果" + JSON.stringify(ans))
+    }
+
+    if(ans) {
+      IBestToast.show({ message: '保存成功' })
+      yTRouter.routerBack()
+    } else {
+      IBestToast.show({ message: '保存失败' })
+    }
+  }
+
+  /**
+   * 清空相册
+   */
+  clearPhoto() {
+    this.diaryData.imageUrls = []
+  }
+
+  /**
+   * 删除图片
+   * @param index
+   */
+  delPhotoItem(index: number){
+    let temp = [...this.diaryData.imageUrls!]
+    temp?.splice(index, 1)
+    this.diaryData.imageUrls = temp
+    console.log("点击了删除" + JSON.stringify(this.diaryData.imageUrls))
+  }
+
+  /**
+   * 重写返回逻辑 - 拦截返回手势
+   * @returns
+   */
+  onRouterBack(): boolean {
+    if(!Variable.pageReadOnly) {
+      yTToast.openToast(wrapBuilder(DoubleConfirm), {
+        text: "是否确认退出编辑",
+        click: async () => {
+          yTToast.hide()
+          yTRouter.routerBack()
+        }
+      })
+    } else {
+      yTRouter.routerBack()
+    }
+    return true;
+  }
+
+  // 路由参数解析
+  async getRouterParams(){
+    // 获取路由参数
+    const params = yTRouter.getParamByName("IncreaseDiaryPage").pop() as Record<string, boolean | number>;
+
+    // 获取参数
+    this.pageStatus = (params?.PageStatus ?? PageStatus.DIARY) as PageStatus
+
+    // 获取参数
+    let id = (params?.id ?? -1) as number;
+    if (id != -1) {
+      this.pageReadOnly = true
+      Variable.pageReadOnly = true
+      if(this.pageStatus == PageStatus.DIARY) {
+        this.diaryData = await DiaryViewModel.queryDiaryLogById(id)
+      } else {
+        this.diaryData = await RecodeViewModel.queryNoteById(id)
+        this.diaryData.diaryDate = this.diaryData.noteTime
+      }
+      try{
+        let time = this.diaryData.diaryDate?.split(' ')?.[1]
+        let time1 = time?.split(':')
+        time1?.pop()
+        this.diaryData.diaryDate = this.diaryData.diaryDate?.split(' ')?.[0] + ' ' + time1?.join(':')
+      } catch (e){
+        console.log("时间解析错误")
+      }
+    }
+  }
+
+  async aboutToAppear(): Promise<void> {
+    this.diaryData.diaryDate = DateUtils.formatDateToCustomString(new Date(), true, false)
+    this.getRouterParams()
+
+    // TODO 在没有数据的时候 时间选择器的回显为 undefined
+  }
+
+  build() {
+    NavDestination() {
+      Column({ space: 5 }) {
+        // 标题区
+        Stack({alignContent: Alignment.Center}) {
+          Row(){
+            Image($r("app.media.close"))
+              .width(20)
+              .aspectRatio(1)
+              .onClick(this.onRouterBack)
+
+            Text(this.pageReadOnly ? "编辑" : "完成")
+              .fontSize(14)
+              .fontWeight(500)
+              .borderRadius(16)
+              .backgroundColor(Color.White)
+              .padding({top: 5.5, left: 14, right: 14, bottom: 5.5})
+              .onClick(() => {
+                this.onComplete()
+              })
+          }
+          .width("100%")
+          .justifyContent(FlexAlign.SpaceBetween)
+
+          Text("创作")
+            .fontSize(20)
+            .fontWeight(700)
+        }
+        .width("100%")
+        .padding({ top: this.safeTop + 5, left: 20, right: 20, bottom: 22 })
+
+        // 内容区
+        Column({space: 5}) {
+          Stack({alignContent: Alignment.Bottom}){
+            // 主要内容
+            Column(){
+              // 日期选择
+              Row(){
+                Row({space: 8}){
+                  Text(this.diaryData.diaryDate?.split(' ')[0])
+                    .fontSize(16)
+                    .fontWeight(600)
+
+                  Image($r('app.media.Diary_DateOpen'))
+                    .width(14)
+                    .height(8)
+                }
+                .onClick(() => {
+                  this.showDatePicker = true
+                })
+
+                // 时间选择
+                Row({space: 8}){
+                  if(this.pageStatus == PageStatus.RECODE) {
+                    Text(this.diaryData.diaryDate?.split(' ')[1])
+                      .fontSize(16)
+                      .fontWeight(600)
+
+                    Image($r('app.media.Diary_DateOpen'))
+                      .width(14)
+                      .height(8)
+                  }
+                }
+                .onClick(() => {
+                  this.showTimePicker = true
+                })
+              }
+              .width("100%")
+              .justifyContent(FlexAlign.SpaceBetween)
+              .padding({top: 16, bottom: 16}) // , left: 20, right: 20
+
+              // 标题栏
+              Row() {
+                TextInput({ text: $$this.diaryData.title, placeholder: "输入标题会更受欢迎!" })
+                  .padding(0)
+                  .fontSize(16)
+                  .fontWeight(500)
+                  .maxLength(20)
+                  .height('100%')
+                  .layoutWeight(1)
+                  .borderRadius(0)
+                  .placeholderColor("#BFBFBF")
+                  .backgroundColor(Color.Transparent)
+                  .caretColor('app.color.main_ac_color_dark')
+                  .placeholderFont({ size: 16, weight: FontWeight.Bold })
+
+                Row(){
+                  if(this.diaryData.title && !this.pageReadOnly){
+                    Image($r('app.media.Diary_close'))
+                      .width(24)
+                      .height(24)
+                      .borderRadius(12)
+                      .onClick(() => {
+                        this.diaryData.title = ''
+                      })
+                  }
+                }
+                .width(24)
+                .margin({right: 15})
+
+                Text(`${20 - (this.diaryData.title ? this.diaryData.title.length : 0) }`)
+                  .fontColor("#BFBFBF")
+              }
+              .height(50)
+              .border({
+                width: {
+                  bottom: 0.1
+                },
+                color: 20 - (this.diaryData.title ? this.diaryData.title.length : 0) === 0 ? Color.Red : "#BFBFBF"
+              })
+
+              // 内容栏
+              List(){
+                ListItem(){
+                  TextArea({ text: $$this.diaryData.content, placeholder: "记录此刻" })
+                    .padding(0)
+                    .fontSize(14)
+                    .width("100%")
+                    .height("100%")
+                    .borderRadius(0)
+                    .fontWeight(400)
+                    .placeholderColor("#BFBFBF")
+                    .placeholderFont({ size: 16 })
+                    .backgroundColor(Color.Transparent)
+                    .caretColor('app.color.main_ac_color_dark')
+                }
+              }
+              .padding({top: 12})
+              .layoutWeight(1)
+              .width("100%")
+
+              Column({space: 32}){
+                // 图片显示器
+                Scroll(){
+                  Row({space: 5}){
+                    ForEach(this.diaryData.imageUrls, (item: string, index: number) => {
+                      Stack({alignContent: Alignment.TopEnd}){
+                        Image(item)
+                          .width(100)
+                          .height(108)
+                        if(!this.pageReadOnly) {
+                          Image($r('app.media.Diary_close'))
+                            .width(24)
+                            .aspectRatio(1)
+                            .offset({
+                              x: -2, y: -2
+                            })
+                            .onClick(() => {
+                              this.delPhotoItem(index)
+                            })
+                        }
+                      }
+                    })
+                  }
+                }
+                .height(108)
+                .scrollable(ScrollDirection.Horizontal)
+                .align(Alignment.TopStart)
+
+                // 图片选择器
+                Row(){
+                  // 清空
+                  Row(){
+                    if(!this.pageReadOnly){
+                      Text('清空')
+                        .fontSize(18)
+                        .fontWeight(400)
+                        .fontColor('#979797')
+                    }
+                  }
+                  .borderRadius(20)
+                  .backgroundColor('#F0F0F0')
+                  .alignItems(VerticalAlign.Center)
+                  .justifyContent(FlexAlign.Center)
+                  .padding({ top: 6, right: 18, bottom: 6, left: 18})
+                  .onClick(() => {
+                    // this.clearPhoto()
+                    this.diaryData.content = ''
+                  })
+
+                  // 相册
+                  Row({space: 5}){
+                    Image($r('app.media.photoAlbum'))
+                      .width(20)
+                      .aspectRatio(1)
+
+                    Text("相册")
+                      .fontSize(18)
+                      .fontWeight(500)
+                  }
+                  .borderRadius(18)
+                  .linearGradient(this.linearInfo)
+                  .padding({ top: 12, right: 16, bottom: 12, left: 16})
+                  .onClick(()=>{
+                    this.photoSelect()
+                  })
+                }
+                .width("100%")
+                .alignItems(VerticalAlign.Center)
+                .justifyContent(FlexAlign.SpaceBetween)
+              }
+              .padding({bottom: 64})
+            }
+            .width("100%")
+            .height("100%")
+
+            // 当页面不可编辑时添加覆盖层
+            if(this.pageReadOnly) {
+              Row()
+                .width('100%')
+                .height('100%')
+                .backgroundColor(Color.Transparent) // 透明覆盖层
+                .onTouch((event: TouchEvent) => {
+                  event.stopPropagation() // 阻止触摸事件
+                })
+            }
+
+            // 开启时间选择器
+            if(this.showTimePicker){
+              Column(){
+                DiaryTimePicker({
+                  timeStr: (this.diaryData.diaryDate ?? DateUtils.formatDateToCustomString(new Date(), true)).split(' ')[1],
+                  onConfirm: (time: string) => {
+                    this.showTimePicker = false
+                    console.log("选择的时间 " + time)
+                    this.diaryData.diaryDate = this.diaryData.diaryDate?.split(' ')[0] + ' ' + time
+                  }
+                })
+              }
+              .width("100%")
+              .height("100%")
+              .padding({ top: 53 })
+              .alignItems(HorizontalAlign.End)
+              .justifyContent(FlexAlign.Start)
+              .onClick(() => {
+                this.showTimePicker = false
+              })
+            }
+
+            // 开启日期选择器
+            if(this.showDatePicker) {
+              Column(){
+                DiaryDatePicker({
+                  selectedDate: new Date(this.diaryData.diaryDate ?? new Date().toISOString()),
+                  selectDateBack: (date: Date) => {
+                    this.showDatePicker = false
+                    let result = DateUtils.formatDateToCustomString(date, false)
+                    console.log("选择的日期" + result)
+                    try {
+                      let temp = this.diaryData.diaryDate?.split(' ')[1]
+                      this.diaryData.diaryDate = result + ' ' + temp
+                    } catch (e) {
+
+                    }
+                  }
+                })
+                  .width("80%")
+              }
+              .width("100%")
+              .height("100%")
+              .padding({ top: 53 })
+              .alignItems(HorizontalAlign.Start)
+              .justifyContent(FlexAlign.Start)
+              .onClick(() => {
+                this.showDatePicker = false
+              })
+            }
+          }
+          .width("100%")
+          .height("100%")
+        }
+        .width("100%")
+        .layoutWeight(1)
+        .backgroundColor(Color.White)
+        .alignItems(HorizontalAlign.Start)
+        .justifyContent(FlexAlign.Start)
+        .padding({ left: 20, right: 20 })
+        .borderRadius({
+          topLeft: 28, topRight: 28
+        })
+      }
+      .width("100%")
+      .height("100%")
+      .linearGradient(this.linearInfo)
+    }
+    .hideTitleBar(true)
+    .onBackPressed(() => {
+      console.log("返回"+this.pageReadOnly)
+      return this.onRouterBack.bind(this)
+    })
+  }
+}
+
+@Builder
+function IncreaseDiaryBuilder() {
+  IncreaseDiaryPage()
+}

+ 105 - 0
features/feature/src/main/ets/utils/DateUtils.ets

@@ -0,0 +1,105 @@
+import { DateInfo } from "../models/DateInfo";
+
+// 星期中文映射表
+const WEEK_MAP = ['日', '一', '二', '三', '四', '五', '六'];
+
+/**
+ * 创建一个日期信息对象
+ * @param date 日期对象
+ * @returns DateInfo 对象
+ */
+function createDateInfo(date: Date): DateInfo {
+  const year = date.getFullYear();
+  const month = date.getMonth() + 1;
+  const day = date.getDate();
+  const week = WEEK_MAP[date.getDay()];
+
+  return {
+    year: year,
+    month: month,
+    day: day,
+    week: week,
+    id: new Date(date)
+  };
+}
+
+
+export class DateUtils {
+  static formatDateToCustomString(date: Date, needTime: boolean = true, needSecond: boolean = true): string {
+    // 转换为 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 hours = date.getHours().toString().padStart(2, '0');
+    const minutes = date.getMinutes().toString().padStart(2, '0');
+    const seconds = date.getSeconds().toString().padStart(2, '0');
+
+    const result = `${year}-${month}-${day}` + (needTime ? ` ${hours}:${minutes}` + (needSecond ? `:${seconds}` : '') : '');
+    return result;
+  }
+
+  /**
+   * 生成从指定日期开始向前的连续日期数组
+   * @param startDate 起始日期(默认当前日期)
+   * @param count 生成的日期数量(默认7天)
+   * @returns 日期对象数组
+   */
+  static generateForwardDateArray(
+    startDate: Date = new Date(),
+    count: number = 7
+  ): DateInfo[] {
+    const dateArray: DateInfo[] = [];
+
+    // 复制起始日期,避免修改原对象
+    const currentDate = new Date(startDate);
+
+    for (let i = 0; i < count; i++) {
+      // 添加日期信息到数组
+      dateArray.push(createDateInfo(currentDate));
+
+      // 日期减1天(向前)
+      currentDate.setDate(currentDate.getDate() - 1);
+    }
+
+    return dateArray;
+  }
+
+  /**
+   * 生成从指定日期开始向后的连续日期数组,可以包含今天但不能超过今天
+   * @param startDate 起始日期(默认当前日期)
+   * @param count 生成的日期数量(默认7天)
+   * @returns 日期对象数组,包含今天但不包含超过今天的日期
+   */
+  static generateBackwardDateArray(
+    startDate: Date = new Date(),
+    count: number = 7
+  ): DateInfo[] {
+    const dateArray: DateInfo[] = [];
+
+    // 复制起始日期,避免修改原对象
+    const currentDate = new Date(startDate);
+
+    // 获取今天的日期
+    // 获取今天的日期并设置时间为23:59:59:999,便于比较
+    const today = new Date();
+    today.setHours(0, 0, 0, 0);
+    today.setDate(today.getDate() + 1);
+    today.setTime(today.getTime() - 1); // 设置为今天的最后一毫秒
+
+    for (let i = 0; i < count; i++) {
+      // 检查当前日期是否超过今天
+      if (currentDate > today) {
+        break;
+      }
+
+      // 添加日期信息到数组
+      dateArray.push(createDateInfo(currentDate));
+
+      // 日期加1天(向后)
+      currentDate.setDate(currentDate.getDate() + 1);
+    }
+
+    return dateArray;
+  }
+}
+

+ 291 - 0
features/feature/src/main/ets/view/DiaryView.ets

@@ -0,0 +1,291 @@
+import { IBestToast, userInfo, UserInfo, YTAvoid, yTRouter, yTToast } from "basic"
+import { DiaryTitleItem } from "../components/DiaryTitleItem"
+import { DoubleConfirm } from "../components/DoubleConfirm"
+import { LoginComponent } from "../components/LoginComponent"
+import { DiaryData, PageStatus } from "../models"
+import { DateUtils } from "../utils/DateUtils"
+import { DiaryViewModel } from "../viewModels/DiaryViewModel"
+
+/**
+ * 日记页面
+ */
+@Component
+export struct DiaryView {
+  @StorageProp(YTAvoid.SAFE_TOP_KEY) safeTop: number = 0
+  @State Vm: DiaryViewModel = new DiaryViewModel()
+  @State ShowLoginDialog: boolean = false
+  @StorageProp(UserInfo.KEY) @Watch('loginStateChanged')  userInfo: UserInfo = userInfo
+
+  private linearInfo: LinearGradientOptions = {
+    colors: [ ['#B9FD2A', 0.01], ['#F5FD6D', 1] ],
+    angle: 110
+  }
+
+  /**
+   * 登录状态发生变化
+   */
+  loginStateChanged(){
+    console.log('登录状态发生变化 登录状态为 ' + this.userInfo.checkLogin())
+    const loginState = this.userInfo.checkLogin()
+    if(loginState){
+      this.ShowLoginDialog = false
+      this.reloadDiaryData()
+    } else {
+      this.Vm.diaryDataList = []
+      this.Vm.dateList = []
+    }
+  }
+
+  /**
+   * 跳转日记详情
+   * @param id 日记 id (可选),没有 id 表示新增日记
+   */
+  routerDiaryPage(id?: number) {
+    yTRouter.pushPathByName("IncreaseDiaryPage", {
+      'id': id,
+      'PageStatus': PageStatus.DIARY
+    } as Record<string, string | number>);
+  }
+
+  /**
+   * 删除日记
+   * @param index
+   */
+  decreaseDiary(index: number){
+    yTToast.openToast(wrapBuilder(DoubleConfirm), {
+      text: "确定删除该篇日记吗?",
+      click: async () => {
+        yTToast.hide()
+        let ans = await this.Vm.deleteDiaryLog(index)
+        if(ans){
+          IBestToast.show({ message: '删除了日记' })
+          this.reloadDiaryData()
+        }
+      }
+    })
+  }
+
+  /**
+   * 搜索日记
+   */
+  routerSearchPage(){
+    yTRouter.pushPathByName("DiarySearchPage", null)
+  }
+
+  /**
+   * 打开日期选择器
+   */
+  openDatePicker(){
+    CalendarPickerDialog.show({
+      selected: new Date(),
+      start: new Date('1970-01-10'),
+      end: new Date(DateUtils.formatDateToCustomString(new Date(), false)),
+      onAccept: (value) => {
+        this.toDiaryHead(value)
+      }
+    })
+  }
+
+  /**
+   * 跳转到指定的日期的日记索引 ( 如果找不到指定的日期, 跳转到最近的比目标值大的索引 )
+   * @param date 选择的 日期
+   */
+  toDiaryHead(date: Date) {
+    console.info("calendar onAccept:" + JSON.stringify(date));
+    let ans = DateUtils.formatDateToCustomString(date, false);
+    let target = 0;
+    for (let i = 0; i < this.Vm.dateList.length; i++) {
+      let current = this.Vm.dateList[i]
+      if(current >= ans) {
+        target = i;
+      }
+    }
+    console.log("target " + target)
+    this.Vm.scroller.scrollToIndex(target, true,  ScrollAlign.START)
+  }
+
+
+  /**
+   * 重新加载日记数据
+   */
+  reloadDiaryData() {
+    if(this.userInfo.checkLogin()){
+      this.Vm.queryDiaryLogList(DateUtils.formatDateToCustomString(new Date(), false))
+    } else {
+      this.ShowLoginDialog = true
+    }
+  }
+
+  aboutToAppear(): void {
+    this.reloadDiaryData()
+  }
+
+  build() {
+    Stack(){
+      Column() {
+        // title
+        Row() {
+          Image($r("app.media.calendar"))
+            .width(30)
+            .aspectRatio(1)
+            .onClick(() => {
+              this.openDatePicker()
+            })
+
+          Text("日记本")
+            .fontSize(20)
+
+          Image($r("app.media.Search"))
+            .width(30)
+            .aspectRatio(1)
+            .onClick(this.routerSearchPage)
+        }
+        .width("100%")
+        .justifyContent(FlexAlign.SpaceBetween)
+        .padding({ top: this.safeTop + 22, left: 16, right: 16, bottom: 33 })
+
+        // swiper
+        Stack({ alignContent: Alignment.BottomEnd }) {
+          // 日记列表
+          List({ space: 16, scroller: this.Vm.scroller }) {
+            // 空数据页面
+            if(this.Vm.diaryDataList.length === 0) {
+              ListItem(){
+                Column({space: 12}){
+                  Row({space: 8}){
+                    Text("+")
+                    Text("去添加")
+                  }
+                  .borderRadius(8)
+                  .linearGradient(this.linearInfo)
+                  .alignItems(VerticalAlign.Center)
+                  .justifyContent(FlexAlign.Center)
+                  .border({width: 1, color: Color.Black})
+                  .padding({ left: 16, top: 12, right: 16, bottom: 12})
+                  .onClick(() => {
+                    this.routerDiaryPage()
+                  })
+
+                  Text("暂无记录~")
+                    .fontSize(14)
+                    .fontWeight(400)
+                }
+                .width("100%")
+                .height("100%")
+                .alignItems(HorizontalAlign.Center)
+                .padding({ top: '40%'})
+                // .justifyContent(FlexAlign.Center)
+              }
+              .layoutWeight(1)
+              .width("100%")
+            }
+
+            ForEach(this.Vm.dateList, (groupTitle: string, index: number) => {
+              ListItemGroup({
+                header: this.DiaryHead(groupTitle),
+              }) {
+                ForEach(this.Vm.diaryDataList.filter((item) => item.diaryDate == groupTitle), (item: DiaryData, i: number) => {
+                  ListItem() {
+                    DiaryTitleItem({
+                      title: item.title,
+                      onClickBack: () => {
+                        this.routerDiaryPage(item.id)
+                      },
+                      onActionBack: (event: GestureEvent) => {
+                        console.log("触发删除")
+                        this.decreaseDiary(item.id ?? -1)
+                      }
+                    })
+                  }
+                  .swipeAction({
+                    end: this.DiaryDel(item.id),
+                    edgeEffect: SwipeEdgeEffect.None
+                  })
+                }, (item: DiaryData) => item.id?.toString() + item.title!)
+              }
+            }, (groupTitle: string, index: number) => groupTitle)
+          }
+          .width("100%")
+          .height("100%")
+          .scrollBar(BarState.Off)
+          .sticky(StickyStyle.Header)
+
+          // 增加日记按钮
+          Row() {
+            Image($r("app.media.add_Img"))
+              .width(40)
+              .aspectRatio(1)
+          }
+          .onClick(() => {
+            this.routerDiaryPage()
+          })
+          .width(40)
+          .aspectRatio(1)
+          .borderRadius(20)
+          .margin({ bottom: 16 })
+          .alignItems(VerticalAlign.Center)
+          .justifyContent(FlexAlign.Center)
+          .linearGradient(this.linearInfo)
+        }
+        .width("100%")
+        .layoutWeight(1)
+        .backgroundColor(Color.White)
+        .padding({ left: 16, right: 16, top: 13 })
+        .borderRadius({
+          topLeft: 28, topRight: 28
+        })
+      }
+      .width("100%")
+      .height("100%")
+      .linearGradient(this.linearInfo)
+      .onVisibleAreaChange([0, 1], (isExpanding: boolean, currentRatio: number) => {
+        if(isExpanding) {
+          console.log("组件出来了")
+          this.reloadDiaryData()
+        } else {
+          console.log("组件退了")
+        }
+      })
+
+      if(this.ShowLoginDialog){
+        LoginComponent()
+      }
+    }
+    .width("100%")
+    .height("100%")
+  }
+
+  // 日记时间组 - 头部组件
+  @Builder
+  DiaryHead(time: string) {
+    Row(){
+      Text(time)
+    }
+    .width("100%")
+    .backgroundColor(Color.White)
+  }
+
+  // 日记条目删除组件
+  @Builder
+  DiaryDel(index: number) {
+    Row() {
+      Row(){
+        Text("删除")
+          .fontSize(16)
+          .fontColor(Color.White)
+      }
+      .width(60)
+      .height("100%")
+      .backgroundColor(Color.Red)
+      .alignItems(VerticalAlign.Center)
+      .justifyContent(FlexAlign.Center)
+      .borderRadius({
+        topLeft: 20, bottomLeft: 20
+      })
+      .onClick(() => {
+        this.decreaseDiary(index)
+      })
+    }
+    .padding({left: 10})
+  }
+}

+ 0 - 6
features/feature/src/main/ets/view/MainView.ets

@@ -1,6 +0,0 @@
-@Component
-export struct MainView {
-  build() {
-    Text('1')
-  }
-}

+ 495 - 0
features/feature/src/main/ets/view/RecodView.ets

@@ -0,0 +1,495 @@
+import { AppStorageKeyCollect, IBestToast, userInfo, UserInfo, YTAvoid, yTRouter } from 'basic'
+import { DateInfo } from '../models/DateInfo'
+import { RecodeViewModel } from '../viewModels/RecodeViewModel'
+import { DiaryDatePicker } from '../components/DiaryDatePicker'
+import { DiaryTimePicker } from '../components/DiaryTimePicker'
+import { DateUtils } from '../utils/DateUtils'
+import { DiaryData, PageStatus } from '../models'
+import { CollaborationCameraStateDialog } from '@hms.collaboration.camera'
+import { LoginComponent } from '../components/LoginComponent'
+
+/**
+ * 记录页面
+ */
+@Component
+export struct RecodView {
+  @StorageProp(YTAvoid.SAFE_BOTTOM_KEY) bottom: number = 0
+  @StorageProp(YTAvoid.SAFE_TOP_KEY) safeTop: number = 0
+  @State Vm: RecodeViewModel = new RecodeViewModel()
+  @State heightList: number[] = []
+  // 去登录界面
+  @State ShowLoginDialog: boolean = false
+  @StorageProp(UserInfo.KEY) @Watch('loginStateChanged')  userInfo: UserInfo = userInfo
+
+  private linearInfo: LinearGradientOptions = {
+    colors: [ ['#B9FD2A', 0.01], ['#F5FD6D', 1] ],
+    angle: 110
+  }
+
+  selectDateChange = (index: number) => {
+    this.Vm.selectedDate = index
+    this.Vm.changeDataByIndex()
+    console.log('改变了选择的日期')
+  }
+
+
+  /**
+   * 登录状态发生变化
+   */
+  loginStateChanged(){
+    console.log('登录状态发生变化 登录状态为 ' + this.userInfo.checkLogin())
+    const loginState = this.userInfo.checkLogin()
+    if(loginState){
+      this.ShowLoginDialog = false
+      this.loadDataList(DateUtils.formatDateToCustomString(new Date(), false))
+    } else {
+      this.Vm.recodeList = []
+    }
+  }
+
+  // 加载小记录数据列表
+  async loadDataList(targetDate: string) {
+    if(this.userInfo.checkLogin()) {
+      this.Vm.queryNoteList(targetDate)
+    } else {
+      this.ShowLoginDialog = true
+    }
+  }
+
+  /**
+   * 更新小记录时间
+   * @param index
+   * @param time
+   */
+  async updateNoteTime(index: number, time: string) {
+    let currentNote: DiaryData = this.Vm.recodeList[index]
+    currentNote.noteTime = currentNote.noteTime?.split(' ')[0] + ' ' + time + ':00'
+    let ans = await this.Vm.updateNoteTime(currentNote)
+    if(ans) {
+      this.Vm.changeDataByIndex()
+      IBestToast.show('更改成功')
+    } else {
+      IBestToast.show('更改失败')
+    }
+  }
+
+  /**
+   * 跳转至添加小记录页面
+   * @param id
+   */
+  routerAddNote(id?: number) {
+    yTRouter.pushPathByName("IncreaseDiaryPage", {
+      'id': id,
+      'PageStatus': PageStatus.RECODE
+    } as Record<string, boolean | number | string>);
+  }
+
+  aboutToAppear(): void {
+    this.Vm.selectedDateChange = this.selectDateChange
+    this.loadDataList(DateUtils.formatDateToCustomString(new Date(), false))
+  }
+
+  build() {
+    Stack(){
+      Column(){
+        Row(){
+          Image($r("app.media.RecodeTitle"))
+            .width(140)
+            .height(44)
+
+          Image($r("app.media.calendar"))
+            .width(30)
+            .aspectRatio(1)
+            .onClick(() => {
+              animateToImmediately({
+                duration: 200
+              }, () => {
+                if(this.Vm.showDatePicker) {
+                  this.Vm.showDatePicker = false
+                } else {
+                  this.Vm.showDatePicker = true
+                  this.Vm.showTimePicker = -1
+                }
+              })
+            })
+        }
+        .width("100%")
+        .height(76)
+        .justifyContent(FlexAlign.SpaceBetween)
+        .alignItems(VerticalAlign.Center)
+        .padding({ left: 17, right: 17, bottom: 17, top: 17})
+        .onClick(() => {
+          this.Vm.showTimePicker = -1
+          this.Vm.showDatePicker = false
+        })
+
+        // 时间选择器 - 使用区域变换实现
+        if(this.Vm.showTimePicker != -1) {
+          DiaryTimePicker({
+            timeStr: this.Vm.getTime(this.Vm.showTimePicker),
+            onConfirm: (time: string) => {
+              this.updateNoteTime(this.Vm.showTimePicker, time)
+              this.Vm.showTimePicker = -1
+            },
+            onCancel: () => {
+              this.Vm.showTimePicker = -1
+            }
+          })
+            .position({
+              // x: 5,
+              // y: 35
+              x: this.Vm.getPostion('x'),
+              y: this.Vm.getPostion('y')
+            })
+            .zIndex(100)
+        }
+
+        // 主体内容
+        Stack({alignContent: Alignment.TopEnd}){
+          Column(){
+            // 日期选择
+            Swiper(this.Vm.swiperController){
+              LazyForEach(this.Vm.weekLoop, (item: DateInfo, index: number) => {
+                Column({space: 2}) {
+                  Column({space: 15}){
+                    Text(item.week)
+                    // ${item.month}-
+                    Text(`${item.day}`)
+                  }
+                  .width("100%")
+                  .padding({ top: 5, bottom: 5 })
+                  .borderRadius(10)
+                  .linearGradient(this.Vm.selectedDate === index ? this.linearInfo : null)
+
+                  // TODO 表示某天有数据 - 暂无接口,待定
+                  if(false) {
+                    Row()
+                      .width(6)
+                      .height(6)
+                      .borderRadius(3)
+                      .backgroundColor('#BAFE2B')
+                  }
+                }
+                .width(50)
+                .height(80)
+                .padding({
+                  left: 7,
+                  right: 7,
+                  top: 9,
+                })
+                .onClick(() => {
+                  this.selectDateChange(index)
+                })
+              }, (item: DateInfo, index: number) => { return item.id.toString() })
+            }
+            .loop(false)
+            .displayCount(7)
+            .indicator(false)
+            .direction(Direction.Rtl)
+            .onChange((index: number) => {
+              this.Vm.swiperOnChange(index)
+            })
+
+            // 记录内容主体
+            Stack({alignContent: Alignment.BottomEnd}){
+              List({space: 10}) {
+                ListItem()
+                  .height(20)
+                  .onClick(() => {
+                    this.Vm.showTimePicker = -1
+                    this.Vm.showDatePicker = false
+                  })
+
+                ForEach(this.Vm.recodeList, (item: DiaryData, index: number) => {
+                  ListItem(){
+                    Row({space: 20}){
+                      // 时间 和 分隔线
+                      Column({space: 5}){
+                        Row(){
+                          Text(this.Vm.getTime(index))
+                            .fontSize(14)
+                            .padding({
+                              top: 5,
+                              left: 8,
+                              right: 8,
+                              bottom: 5
+                            })
+                            .fontWeight(400)
+                            .borderRadius(8)
+                            .fontColor(Color.Black)
+                            .linearGradient(this.linearInfo)
+                        }
+                        .width(54)
+                        .height(30)
+                        .alignItems(VerticalAlign.Center)
+                        .justifyContent(FlexAlign.Center)
+                        .onClick(() => {
+                          if(this.Vm.showTimePicker === index) {
+                            this.Vm.showTimePicker = -1
+                          } else {
+                            this.Vm.showTimePicker = index
+                            this.Vm.showDatePicker = false
+                          }
+                        })
+
+                        // 分隔线
+                        Column(){
+                          Row() {
+                            Row()
+                              .width(7)
+                              .aspectRatio(1)
+                              .borderRadius(4)
+                              .backgroundColor(Color.White)
+                          }
+                          .width(10)
+                          .aspectRatio(1)
+                          .borderRadius(5)
+                          .backgroundColor('#B9FD2A')
+                          .alignItems(VerticalAlign.Center)
+                          .justifyContent(FlexAlign.Center)
+
+                          Row()
+                            .width(3)
+                            .backgroundColor('#E9E9EC')
+                            .layoutWeight(1)
+
+                          Row() {
+                            Row()
+                              .width(7)
+                              .aspectRatio(1)
+                              .borderRadius(4)
+                              .backgroundColor(Color.White)
+                          }
+                          .width(10)
+                          .aspectRatio(1)
+                          .borderRadius(5)
+                          .backgroundColor('#B9FD2A')
+                          .alignItems(VerticalAlign.Center)
+                          .justifyContent(FlexAlign.Center)
+                        }
+                        .width(30)
+                        .height(this.heightList[index] + 15)
+                      }
+                      // .layoutWeight(1)
+
+                      // 标题 和 内容
+                      Column({space: 5}){
+                        // 标题
+                        Row(){
+                          Text(item.title)
+                            .fontSize(14)
+                            .fontWeight(600)
+                            .padding({
+                              top: 5,
+                              left: 8,
+                              right: 8,
+                              bottom: 5
+                            })
+                            .maxLines(1)
+                            .textOverflow ({overflow: TextOverflow.Ellipsis})
+                        }
+                        .height(30)
+                        .alignItems(VerticalAlign.Center)
+                        .justifyContent(FlexAlign.Center)
+
+                        // 内容
+                        Column({space: 8}){
+                          Text(item.content)
+                            .fontSize(12)
+                            .fontColor('#212245')
+                            .opacity(0.5)
+                            .maxLines(2)
+                            .textOverflow ({overflow: TextOverflow.Ellipsis})
+
+                          // 图片显示
+                          Scroll(){
+                            Row({space: 5}){
+                              ForEach(item.imageUrls, (url: string, index: number) => {
+                                Image(url)
+                                  .width(100)
+                                  .height(150)
+                                  .borderRadius(12)
+                              })
+                            }
+                          }
+                          .scrollable(ScrollDirection.Horizontal)
+                          .scrollBar(BarState.Off)
+
+                        }
+                        .alignItems(HorizontalAlign.Start)
+                        .justifyContent(FlexAlign.Start)
+                        .onAreaChange((_o: Area, _n: Area) => {
+                          this.heightList[index] = _n.height as number
+                        })
+
+                        Blank().height(15)
+                      }
+                      .layoutWeight(1)
+                      .alignItems(HorizontalAlign.Start)
+                      .justifyContent(FlexAlign.Start)
+                      .onClick(() => {
+                        this.routerAddNote(item.id!)
+                        this.Vm.showDatePicker = false
+                        this.Vm.showTimePicker = -1
+                      })
+                      .gesture(
+                        LongPressGesture()
+                          .onAction(() => {
+                            console.log("长按了哦")
+                            this.Vm.onDelRecode(item.id!)
+                          })
+                      )
+                    }
+                    .onClick(() => {
+                      this.Vm.showTimePicker = -1
+                      this.Vm.showDatePicker = false
+                    })
+                    .onAreaChange((_o: Area, _n: Area) => {
+                      console.log('位置信息' + JSON.stringify(_n.globalPosition))
+                      let postion = this.Vm.postionList
+                      postion[index] = _n.globalPosition
+                      this.Vm.postionList = postion
+                    })
+                  }
+                })
+
+                // 空数据页面
+                if(this.Vm.recodeList.length === 0) {
+                  ListItem(){
+                    Column({space: 12}){
+                      Row({space: 8}){
+                        Text("+")
+                        Text("去添加")
+                      }
+                      .borderRadius(8)
+                      .linearGradient(this.linearInfo)
+                      .alignItems(VerticalAlign.Center)
+                      .justifyContent(FlexAlign.Center)
+                      .border({width: 1, color: Color.Black})
+                      .padding({ left: 16, top: 12, right: 16, bottom: 12})
+                      .onClick(() => {
+                        this.routerAddNote()
+                      })
+
+                      Text("暂无记录~")
+                        .fontSize(14)
+                        .fontWeight(400)
+                    }
+                    .width("100%")
+                    .height("100%")
+                    .alignItems(HorizontalAlign.Center)
+                    .padding({ top: '30%'})
+                    // .justifyContent(FlexAlign.Center)
+                  }
+                  .layoutWeight(1)
+                  .width("100%")
+                }
+              }
+              .width("100%")
+              .height("100%")
+              .scrollBar(BarState.Off)
+              .padding({top: 10})
+              .onScrollIndex(() => {
+                this.Vm.showTimePicker = -1
+              })
+
+              // 增加日记按钮
+              Row() {
+                Image($r("app.media.add_Img"))
+                  .width("100%")
+                  .aspectRatio(1)
+              }
+              .onClick(() => {
+                this.routerAddNote()
+              })
+              .width(40)
+              .aspectRatio(1)
+              .borderRadius(20)
+              .margin({ bottom: 16 })
+              .alignItems(VerticalAlign.Center)
+              .justifyContent(FlexAlign.Center)
+              .linearGradient(this.linearInfo)
+            }
+            .width("100%")
+            .layoutWeight(1)
+            .padding({
+              bottom: 20, left: 24, right: 24
+            })
+
+            // 记录内容主体
+            // Stack({ alignContent: Alignment.BottomEnd }){
+            //
+            //   // 增加日记按钮
+            //   Row() {
+            //     Image($r("app.media.add"))
+            //       .width(20)
+            //       .aspectRatio(1)
+            //   }
+            //   .onClick(() => {
+            //     this.routerAddNote()
+            //   })
+            //   .width(40)
+            //   .aspectRatio(1)
+            //   .borderRadius(20)
+            //   .padding(8)
+            //   // .border({ width: 1 })
+            //   .margin({ bottom: 16 })
+            //   // .backgroundColor(Color.White)
+            //   .alignItems(VerticalAlign.Center)
+            //   .justifyContent(FlexAlign.Center)
+            //   .linearGradient(this.linearInfo)
+            // }
+            // .width("100%")
+            // .layoutWeight(1)
+
+
+          }
+
+          // 日期选择器
+          if(this.Vm.showDatePicker) {
+            DiaryDatePicker({
+              selectedDate: this.Vm.weekLoop.getData(this.Vm.swiperCurrentIndex).id,
+              selectDateBack: (date: Date) => {
+                this.Vm.showDatePicker = false
+                this.Vm.jumpToDate(date)
+              }
+            })
+              .width(267)
+          }
+        }
+        .width("100%")
+        .layoutWeight(1)
+        .backgroundColor(Color.White)
+        .borderRadius({
+          topLeft: 20,
+          topRight: 20
+        })
+      }
+      .width("100%")
+      .height("100%")
+      .padding({ top: this.safeTop})
+      .linearGradient({
+        colors: [ ['#B9FD2A', 0.01], ['#F5FD6D', 1] ],
+        angle: 150
+      })
+      .onVisibleAreaChange([0, 1], (isExpanding: boolean, currentRatio: number) => {
+        if(isExpanding) {
+          console.log("组件出来了")
+
+          this.loadDataList(this.Vm.getSelectedDate())
+        } else {
+          console.log("组件退了")
+        }
+      })
+
+      if(this.ShowLoginDialog){
+        LoginComponent()
+      }
+    }
+    .width("100%")
+    .height("100%")
+
+
+  }
+}
+

+ 0 - 6
features/feature/src/main/ets/view/SecondView.ets

@@ -1,6 +0,0 @@
-@Component
-export struct SecondView {
-  build() {
-    Text('2')
-  }
-}

+ 0 - 6
features/feature/src/main/ets/view/ThirdView.ets

@@ -1,6 +0,0 @@
-@Component
-export struct ThirdView {
-  build() {
-    Text('3')
-  }
-}

+ 147 - 0
features/feature/src/main/ets/viewModels/DiaryViewModel.ets

@@ -0,0 +1,147 @@
+import { YTLog, YTUserRequest } from "basic"
+import { DiaryApi } from "../apis/DiaryApi"
+import { DiaryData } from "../models"
+import { util } from "@kit.ArkTS"
+import { fileIo as fs } from "@kit.CoreFileKit"
+import { image } from "@kit.ImageKit"
+import { faceDetector } from "@kit.CoreVisionKit"
+
+
+export class DiaryViewModel{
+  // 日记列表
+  diaryDataList: DiaryData[] = []
+  // 时间列表
+  dateList: string[] = []
+  // 列表控制器
+  scroller: ListScroller = new ListScroller()
+
+  /**
+   * 删除日记
+   * @param id 日记 id
+   */
+  async deleteDiaryLog(id: number) {
+    const result = await DiaryApi.deleteDiaryLog(id)
+    YTLog.info(`删除日记结果 ${result}`)
+    return result
+  }
+
+  /**
+   * 查询日记列表
+   * @param nowTime 当前选中时间
+   * @returns 日记列表
+   */
+  async queryDiaryLogList(nowTime: string){
+    const result: DiaryData[] = await DiaryApi.queryDiaryLogList(nowTime)
+    YTLog.info(`查询日记列表结果 ${JSON.stringify(result)}`)
+    this.diaryDataList = result
+
+    let dateList: string[] = [result[0].diaryDate!]
+    result.forEach(item => {
+      if(dateList.indexOf(item.diaryDate!) === -1){
+        dateList.push(item.diaryDate!)
+      }
+    })
+    this.dateList = dateList
+    console.log('title_List ' + JSON.stringify(this.dateList))
+  }
+
+  /**
+   * 日记搜索
+   * @param keyWord 日记标题关键字
+   * @returns
+   */
+  static async diaryLogSearch(keyWord: string): Promise<DiaryData[]> {
+    let encode = encodeURIComponent(keyWord)
+    const result: DiaryData[] = await DiaryApi.diaryLogSearch(encode)
+    YTLog.info(`查询日记搜索结果 ${JSON.stringify(result)}`)
+    return result
+  }
+
+  /**
+   * 修改日记
+   * @param params 日记数据结构
+   * @returns
+   */
+  static async updateDiaryLog(params: DiaryData) {
+    let ans = params.diaryDate?.split(' ')[1]
+    if(!ans) {
+      params.diaryDate += ' 00:00:01'
+    }
+    const result = await DiaryApi.updateDiaryLog(params)
+    YTLog.info(`修改日记结果 ${result}`)
+    return result
+  }
+
+  /**
+   * 查询日记详情
+   * @param id
+   * @returns
+   */
+  static async queryDiaryLogById(id: number) {
+    const result: DiaryData = await DiaryApi.queryDiaryLogById(id)
+    YTLog.info(`查询日记结果 ${JSON.stringify(result)}`)
+    return result
+  }
+
+  /**
+   * 新增日记
+   * @param params 日记数据结构
+   * @returns
+   */
+  static async saveDiaryLog(params: DiaryData) {
+    const result = await DiaryApi.saveDiaryLog(params)
+    YTLog.info(`新增日记结果 ${result}`)
+    return result
+  }
+
+  // 上传图片
+  static async uploadImage(conText: Context, filePath: string) {
+    const promise = new Promise<string>(async (resolve, reject) => {
+      let uri = DiaryViewModel.copyToSync(conText, filePath) as string
+      uri = await DiaryViewModel.manualCompression(uri, conText)
+      console.log("uri " + uri)
+      YTUserRequest.uploadFile(conText, uri, (url) => {
+        resolve(url)
+      })
+    })
+    const url = await promise
+    return url
+  }
+
+  // 图片处理
+  static copyToSync(conText: Context, uri: string) {
+    // 切割图片路径
+    let temp: string[] = uri.split("/")
+
+    // 使用时间戳拼接文件名 ( 仅仅是为了获取文件后缀名 )
+    let fileName: string = Date.now() + "." + temp[temp.length-1].split(".")[1]
+
+    // 根据上下文对象获取 cache 文件的路径,将其于 filename 进行拼接
+    let filePath: string = conText.cacheDir + "/" + fileName
+
+    // 获取图片路径的文件指针,模式设置为只读
+    const file = fs.openSync(uri, fs.OpenMode.READ_ONLY)
+
+    // 将文件拷贝至 cache 的路径
+    fs.copyFileSync(file.fd, filePath)
+
+    // 需要拿到复制到 Cache 中的文件名
+    return filePath;
+  }
+
+  /**
+   * 手动压缩图片
+   */
+  static async manualCompression(filePath: string, context: Context) {
+    const imageSourceApi: image.ImageSource = image.createImageSource(filePath);
+    let packOpts: image.PackingOption = { format: "image/jpeg", quality: 20 };
+    const imagePackerApi = image.createImagePacker()
+    const buffer = await imagePackerApi.packing(imageSourceApi, packOpts)
+    const imagePath = context.cacheDir + '/' + util.generateRandomUUID() + '.jpeg'
+    const file = fs.openSync(imagePath, fs.OpenMode.CREATE | fs.OpenMode.READ_WRITE)
+    fs.writeSync(file.fd, buffer)
+    fs.closeSync(file)
+    fs.unlinkSync(filePath)
+    return imagePath
+  }
+}

+ 239 - 0
features/feature/src/main/ets/viewModels/RecodeViewModel.ets

@@ -0,0 +1,239 @@
+import { AppStorageKeyCollect, IBestToast, yTToast } from 'basic';
+import { DiaryApi } from '../apis/DiaryApi';
+import { DoubleConfirm } from '../components/DoubleConfirm';
+import { DiaryData } from '../models';
+import { BasicDataSource } from '../models/BasicDataSource';
+import { DateInfo } from '../models/DateInfo';
+import { DateUtils } from '../utils/DateUtils';
+
+export class RecodeViewModel{
+  // 懒加载数据源
+  weekLoop: BasicDataSource<DateInfo> = new BasicDataSource()
+  // swiper 控制器
+  swiperController: SwiperController = new SwiperController();
+  // 是否显示时间选择器
+  showDatePicker: boolean = false
+  // 是否显示时间选择器
+  showTimePicker: number = -1
+  // swiper 容器中当前选中的 index
+  swiperCurrentIndex: number = 0
+  // 日历中被选中的日期
+  selectedDate: number = 0
+  // 当天小记录的数据
+  recodeList: DiaryData[] = []
+  // 记录时间组件的位置信息
+  postionList: Position[] = []
+
+  // 外部传入, 用于修改日历中选中的日期 ( 直接在本类中修改 UI 无法进行刷新WWW )
+  selectedDateChange: (index: number) => void = (index: number) => {}
+
+  /**
+   * 构造函数 - 初始化 weekLoop 数据源
+   */
+  constructor() {
+    // 初始化列表数据
+    const dateList: DateInfo[] = DateUtils.generateForwardDateArray(new Date, 30);
+    console.log("初始化数据" + JSON.stringify(dateList))
+    this.weekLoop.init(dateList);
+  }
+
+  /**
+   * 加载更多数据 - 向左
+   * @param days 需要加载天数
+   */
+  loadForwardMoreData(days: number): void {
+    // 取得列表最后一条数据的 id
+    const dateInfo: Date = this.weekLoop.getData(this.weekLoop.totalCount() - 1).id;
+    // 向后加载 10 天的数据
+    const dateArray: DateInfo[] = DateUtils.generateForwardDateArray(dateInfo, days)
+    dateArray.splice(0, 1)
+    console.log("向左加载的数据" +  JSON.stringify(dateArray))
+
+    // 重新挂载到数据源中
+    this.weekLoop.reloadDataPush(dateArray)
+  }
+
+  /**
+   * 加载更多数据 - 向右
+   * @param days 加载的天数
+   * @param start 起始的日期, 未传则使用当前时间
+   * @returns 加载的天数
+   */
+  loadBackwardMoreData(days: number, start?: Date): number {
+    // 向后加载 10 天的数据
+    const dateArray: DateInfo[] = DateUtils.generateBackwardDateArray(start ?? new Date(), days)
+    console.log("向右加载的数据" + JSON.stringify(dateArray))
+    dateArray.splice(0, 1)
+
+    const count = dateArray.length
+    // 重新挂载到数据源中
+    this.weekLoop.reloadDataUnshift(dateArray)
+
+    return count;
+  }
+
+  /**
+   * swiper 改变时触发
+   * @param currentIndex 当前 swiper 选中的 index
+   * @param days 加载的天数
+   */
+  swiperOnChange(currentIndex: number, days: number = 10){
+    console.log('Swiper currentIndex', currentIndex)
+    this.swiperCurrentIndex = currentIndex
+    if (currentIndex >= this.weekLoop.totalCount() - 10) {
+      // 向左加载
+      console.log('Swiper loadMoreData')
+      this.loadForwardMoreData(days)
+    } else if (currentIndex <= 10) {
+      // 向右加载
+      let count = this.loadBackwardMoreData(days, this.weekLoop.getData(0).id)
+      this.swiperController.changeIndex(this.swiperCurrentIndex + count)
+      this.selectedDateChange(this.selectedDate + count)
+    }
+  }
+
+  /**
+   * 通过日期选择器跳转至指定日期时触发
+   * @param date 跳转到的指定日期
+   */
+  jumpToDate(date: Date) {
+    const backList: DateInfo[] = DateUtils.generateBackwardDateArray(date, 20).reverse()
+    const forwardList: DateInfo[] = DateUtils.generateForwardDateArray(date, 20)
+    console.log("向右加载的数据" + JSON.stringify(backList))
+    console.log("向左加载的数据" + JSON.stringify(forwardList))
+
+    backList.pop()
+    // 小 小 大 大
+    const dateList: DateInfo[] = [...backList, ...forwardList]
+    console.log("重新加载" + JSON.stringify(dateList))
+    this.weekLoop.init(dateList);
+
+    const targetIndex = dateList.findIndex(item => item.id.getTime() === date.getTime())
+    this.swiperController.changeIndex(targetIndex)
+    this.selectedDateChange(targetIndex)
+  }
+
+  // 获取日历中被选中的日期
+  getSelectedDate(): string {
+    const ans = this.weekLoop.getData(this.selectedDate).id
+    const date = DateUtils.formatDateToCustomString(ans, false)
+    console.log("日历中被选中的日期" + date)
+    return date
+  }
+
+  /**
+   * 根据当前日历中选择的日期刷新数据
+   */
+  changeDataByIndex(){
+    const date = this.getSelectedDate()
+    this.queryNoteList(date)
+    console.log("当天小记录" + JSON.stringify(this.recodeList))
+  }
+
+  /**
+   * 时间选择器用 - 动态更改时间选择器的位置
+   * @param type 需要的坐标类型(x/y)
+   * @returns 坐标值
+   */
+  getPostion(type: 'x'|'y'): Length{
+    // 获取屏幕高度
+    const screenHeight = AppStorage.get<number>(AppStorageKeyCollect.SCREEN_HEIGHT)
+
+    if(type == 'x') {
+      return this.postionList[this.showTimePicker].x!
+    } else {
+      const y = this.postionList[this.showTimePicker].y! as number
+      // 屏幕剩余高度过小
+      if(screenHeight && y > screenHeight - 300) {
+        return y - 240
+      }
+      return y
+    }
+  }
+
+  getTime(index: number){
+    let time = this.recodeList[index].noteTime?.split(' ')[1]
+    let time1 = time?.split(':')
+    time1?.pop()
+    return time1?.join(':')
+  }
+
+  /**
+   * 在首页通过长按记录执行的删除的逻辑
+   * @param id
+   */
+  onDelRecode(id: number){
+      yTToast.openToast(wrapBuilder(DoubleConfirm), {
+        text: "确定删除该这条记录吗?",
+        click: async () => {
+          yTToast.hide()
+          let ans = await this.deleteNote(id)
+          if(ans){
+            IBestToast.show({ message: '删除了记录' })
+            this.changeDataByIndex()
+          }
+        }
+      })
+
+  }
+
+  // 请求函数
+
+  // 删除生活小记录
+  async deleteNote(id: number){
+    const ans = await DiaryApi.deleteNote(id)
+    return ans;
+  }
+
+  // 查询生活小记录
+  async queryNoteList(nowTime: string){
+    const result: DiaryData[] = await DiaryApi.queryNoteList(nowTime)
+
+    result.forEach(item => {
+      item.diaryDate = item.noteTime
+    })
+
+    result.sort((a, b) => {
+      return new Date(a.noteTime!).getTime() - new Date(b.noteTime!).getTime()
+    })
+
+    this.recodeList = result
+
+    console.log('查询生活小记录' + JSON.stringify(result))
+
+    // this.dateList[0] = result[0].noteTime?.split(' ')[0] ?? ' '
+    // for (let index = 0; index < result.length; index++) {
+    //   if(result[index].diaryDate != this.dateList[this.dateList.length-1]){
+    //     this.dateList.push(result[index].noteTime?.split(' ')[0] ?? ' ')
+    //   }
+    // }
+    //
+    // console.log('时间列表' + JSON.stringify(this.dateList))
+    // let dateStr = this.getSelectedDate()
+    // this.todayNote = this.totalNote.filter(item => item.noteTime?.split(' ')[0] == dateStr)
+  }
+
+  // 修改生活小记录时间
+  async updateNoteTime(params: DiaryData){
+    const ans = await DiaryApi.updateNoteTime(params)
+    return ans;
+  }
+
+  // 查询生活小记录对象
+  static async queryNoteById(id: number){
+    const ans: DiaryData = await DiaryApi.queryNoteById(id)
+    return ans;
+  }
+
+  // 编辑生活小记录
+  static async updateNote(params: DiaryData){
+    const ans = await DiaryApi.updateNote(params)
+    return ans;
+  }
+
+  // 添加生活小记录
+  static async saveNote(params: DiaryData){
+    const ans = await DiaryApi.saveNote(params)
+    return ans;
+  }
+}

+ 1 - 0
features/feature/src/main/resources/base/media/Diary_DateOpen.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="1755755766785" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="5050" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M112.593358 228.860385c41.35999 0 767.301594 0 795.827277 0 37.003775 0 64.532759 27.609825 42.885739 54.892191-17.330714 21.871123-367.19501 458.883245-397.113413 496.180709-19.661805 24.495904-66.530252 24.081465-86.208431 0-21.951965-26.850531-373.59579-465.531666-398.023132-497.297137C52.043307 259.377422 71.837118 228.860385 112.593358 228.860385z" p-id="5051"></path></svg>

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


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


+ 4 - 0
features/feature/src/main/resources/base/media/Diary_close.svg

@@ -0,0 +1,4 @@
+<svg fill="none" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="design-iconfont">
+  <path fill="#EBEBEB" d="M12 2A10 10 0 1 0 12 22A10 10 0 1 0 12 2Z"/>
+  <path d="M14.8 9L12 11.8966M12 11.8966L15 15M12 11.8966L9.2 9M12 11.8966L9 15" stroke="#BDBDBD" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
+</svg>

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


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


+ 4 - 0
features/feature/src/main/resources/base/media/Search.svg

@@ -0,0 +1,4 @@
+<svg fill="none" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 86 86" class="design-iconfont">
+  <rect x="14.3585" y="12.5641" width="57.2833" height="57.2833" rx="28.6417" stroke="#898989" stroke-width="10.8"/>
+  <path d="M63.2891 64.5L73.7541 75.2777" stroke="#898989" stroke-width="10.8" stroke-linecap="round" stroke-linejoin="round"/>
+</svg>

+ 12 - 0
features/feature/src/main/resources/base/media/add.svg

@@ -0,0 +1,12 @@
+<svg fill="none" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48" class="design-iconfont">
+  <rect width="48" height="48" rx="24" fill="url(#4hppupeu9__paint0_linear_4970_74986)"/>
+  <rect x="16" y="22" width="15" height="3" rx="1.5" fill="#222345"/>
+  <rect x="22" y="32" width="16" height="3" rx="1.5" transform="rotate(-90 22 32)" fill="#222345"/>
+  <path d="M40.2467 28.0552C40.1477 28.872 40.0982 29.2804 40.0945 29.31C39.3902 34.8671 35.9063 38.2787 30.3355 38.8663C30.3059 38.8694 29.8756 38.9124 29.0151 38.9985V38.9985C28.9752 39.0025 28.9553 39.0045 28.9354 39.0064C25.6532 39.332 22.3468 39.332 19.0646 39.0064C19.0447 39.0045 19.0169 39.0017 18.9612 38.9961V38.9961C18.7263 38.9726 18.6089 38.9609 18.5186 38.9505C13.0115 38.3154 8.65621 33.9908 7.98228 28.4883C7.97124 28.3982 7.95994 28.2927 7.93735 28.0819V28.0819C7.92689 27.9843 7.92166 27.9355 7.91673 27.8883C7.6467 25.3037 7.65731 22.6975 7.94837 20.1152C7.95369 20.0681 7.95914 20.0208 7.97004 19.9263L8.04387 19.2865C8.1587 18.2913 8.21612 17.7937 8.36129 17.1746C9.15298 13.7988 12.3169 10.3369 15.608 9.24538C16.2115 9.04523 16.4945 8.98648 17.0603 8.86897C19.4162 8.37972 21.916 8 24 8C25.145 8 26.4154 8.11461 27.7185 8.29902C32.772 9.0142 35.2988 9.37179 37.7283 12.0588C40.1578 14.7458 40.2614 17.3335 40.4687 22.509C40.4889 23.0145 40.5 23.5134 40.5 24C40.5 25.4782 40.3978 26.8092 40.2467 28.0552Z" stroke="#222345" stroke-width="2"/>
+  <defs>
+    <linearGradient id="4hppupeu9__paint0_linear_4970_74986" x1="0" y1="0" x2="53.5679" y2="40.6656" gradientUnits="userSpaceOnUse">
+      <stop stop-color="#B9FD2A"/>
+      <stop offset="1" stop-color="#F5FD6D"/>
+    </linearGradient>
+  </defs>
+</svg>

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


+ 1 - 0
features/feature/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="1755071625373" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="6319" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M395.21518 513.604544l323.135538-312.373427c19.052938-18.416442 19.052938-48.273447 0-66.660212-19.053961-18.416442-49.910737-18.416442-68.964698 0L291.75176 480.290811c-19.052938 18.416442-19.052938 48.273447 0 66.660212l357.633237 345.688183c9.525957 9.207709 22.01234 13.796214 34.497699 13.796214 12.485359 0 24.971741-4.588505 34.466999-13.82896 19.052938-18.416442 19.052938-48.242747 0-66.660212L395.21518 513.604544z" fill="#272636" p-id="6320"></path></svg>

+ 10 - 0
features/feature/src/main/resources/base/media/calendar.svg

@@ -0,0 +1,10 @@
+<svg fill="none" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="design-iconfont">
+  <g clip-path="url(#59jtqozsx__clip0_4976_75684)">
+    <path d="M8 5V3M16 5V3M9 16H15M6 20H18C19.6569 20 21 18.6569 21 17V7C21 5.34315 19.6569 4 18 4H6C4.34315 4 3 5.34315 3 7V17C3 18.6569 4.34315 20 6 20Z" stroke="#212245" stroke-width="2" stroke-linecap="round"/>
+  </g>
+  <defs>
+    <clipPath id="59jtqozsx__clip0_4976_75684">
+      <path fill="#fff" d="M0 0H24V24H0z"/>
+    </clipPath>
+  </defs>
+</svg>

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


+ 10 - 0
features/feature/src/main/resources/base/media/del.svg

@@ -0,0 +1,10 @@
+<svg fill="none" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="design-iconfont">
+  <g clip-path="url(#necc0pqe1__clip0_4980_81502)">
+    <path d="M6.59961 8.4H7.79961M7.79961 8.4H17.3996M7.79961 8.4V16.8C7.79961 17.1183 7.92604 17.4235 8.15108 17.6485C8.37612 17.8736 8.68135 18 8.99961 18H14.9996C15.3179 18 15.6231 17.8736 15.8481 17.6485C16.0732 17.4235 16.1996 17.1183 16.1996 16.8V8.4M9.59961 8.4V7.2C9.59961 6.88174 9.72604 6.57652 9.95108 6.35147C10.1761 6.12643 10.4813 6 10.7996 6H13.1996C13.5179 6 13.8231 6.12643 14.0481 6.35147C14.2732 6.57652 14.3996 6.88174 14.3996 7.2V8.4M10.7996 11.4V15M13.1996 11.4V15" stroke="#000" stroke-opacity=".5" stroke-width="1.2" stroke-linecap="round" stroke-linejoin="round"/>
+  </g>
+  <defs>
+    <clipPath id="necc0pqe1__clip0_4980_81502">
+      <path fill="#fff" d="M0 0H24V24H0z"/>
+    </clipPath>
+  </defs>
+</svg>

+ 12 - 0
features/feature/src/main/resources/base/media/photoAlbum.svg

@@ -0,0 +1,12 @@
+<svg fill="none" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="design-iconfont">
+  <g clip-path="url(#qnjwvfk81__clip0_4996_75116)">
+    <path d="M1.20364 8.58219C1.54832 5.17362 4.27706 2.54264 7.68904 2.23347C9.16308 2.0999 10.7001 2 12 2C13.2999 2 14.8369 2.0999 16.311 2.23347C19.7229 2.54264 22.4517 5.17362 22.7964 8.58219C22.9158 9.76383 23 10.9639 23 12C23 13.0361 22.9158 14.2362 22.7964 15.4178C22.4517 18.8264 19.7229 21.4574 16.311 21.7665C14.8369 21.9001 13.2999 22 12 22C10.7001 22 9.16308 21.9001 7.68904 21.7665C4.27707 21.4574 1.54832 18.8264 1.20364 15.4178C1.08416 14.2362 1 13.0361 1 12C1 10.9639 1.08416 9.76383 1.20364 8.58219Z" stroke="#212245" stroke-width="2"/>
+    <path d="M5 17L7.91343 14.0234L11 17.5L15 13L19 17" stroke="#212245" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
+    <path fill="#212245" d="M16 5A2 2 0 1 0 16 9A2 2 0 1 0 16 5Z"/>
+  </g>
+  <defs>
+    <clipPath id="qnjwvfk81__clip0_4996_75116">
+      <path fill="#fff" d="M0 0H24V24H0z"/>
+    </clipPath>
+  </defs>
+</svg>

+ 10 - 1
features/feature/src/main/resources/base/profile/router_map.json

@@ -1,5 +1,14 @@
 {
   "routerMap": [
-
+    {
+        "name": "IncreaseDiaryPage",
+        "pageSourceFile": "src/main/ets/pages/IncreaseDiaryPage.ets",
+        "buildFunction": "IncreaseDiaryBuilder"
+    },
+    {
+      "name": "DiarySearchPage",
+      "pageSourceFile": "src/main/ets/pages/DiarySearchPage.ets",
+      "buildFunction": "DiarySearchBuilder"
+    }
   ]
 }

+ 5 - 2
features/user/src/main/ets/components/LoginInput.ets

@@ -46,9 +46,12 @@ export struct LoginInput {
         Text(this.time == 61 ? '获取验证码' : this.time + '后重新发送')
           .height(30)
           .fontSize(12)
-          .fontColor(Color.White)
+          .fontColor('#212245')
           .borderRadius(16)
-          .backgroundColor($r('[basic].color.main_ac_color_dark'))
+          .linearGradient({
+            colors: [ ['#B9FD2A', 0.5], ['#F5FD6D', 1] ],
+            angle: 135
+          })
           .onClick(() => {
             this.loginCollect.requestSmsCode((res) => {
               if (res.smsCode) {

+ 2 - 3
features/user/src/main/ets/components/Terms.ets

@@ -4,7 +4,7 @@ import { yTRouter } from 'basic'
 @Extend(Span)
 function spanEx(click: () => void) {
   // .decoration({ type: TextDecorationType.Underline, color: $r('[basic].color.main_ac_color_dark') })
-  .fontColor($r('[basic].color.main_ac_color_dark'))
+  .fontColor($r('[basic].color.main_blank'))
   .onClick(click)
 }
 
@@ -33,10 +33,9 @@ export struct Terms {
           //   })
           //
           // Span('以及')
-          Span('《小易决定用户协议》')
+          Span('《朝暮日记用户协议》')
             .spanEx(() => {
               yTRouter.router2userAgreement()
-
             })
           Span('和')
           Span('《隐私政策》')

+ 159 - 0
features/user/src/main/ets/pages/ChangePassword.ets

@@ -0,0 +1,159 @@
+import { YTAvoid, YTButton, YTHeader, yTRouter } from 'basic'
+import { LoginCollect } from 'basic/src/main/ets/models/LoginCollect'
+import { LoginInput } from '../components/LoginInput'
+import { CodeInputType } from '../models'
+
+
+@Component
+struct ChangePassWord{
+  @State private loginCollect: LoginCollect = new LoginCollect('reset')
+  @StorageProp(YTAvoid.SAFE_TOP_KEY) safeTop: number = 0
+
+  private inputPhoneNumberType: CodeInputType = {
+    txt: '+86',
+    placeHolder: '手机号'
+  }
+  private inputCaptchaType: CodeInputType = {
+  txt: '验证码',
+  placeHolder: '验证码'
+}
+  private inputPasswordType: CodeInputType = {
+    txt: '密码',
+    placeHolder: '设置密码'
+  }
+  private inputConfirmPasswordType: CodeInputType = {
+    txt: '密码',
+    placeHolder: '确认密码'
+  }
+  private linearInfo: LinearGradientOptions = {
+    colors: [ ['#B9FD2A', 0.01], ['#F5FD6D', 1] ],
+    angle: 110
+  }
+  build() {
+    NavDestination(){
+      Column(){
+        YTHeader({ title: '用户设置', bgc: 'rgba(0, 0, 0, 0)', leftComp: this.backIcon})
+
+        Column(){
+          // 手机号
+          LoginInput({
+            item: this.inputPhoneNumberType,
+            inputData: this.loginCollect.phonenumber,
+            isPassword: false,
+            needCode: false,
+            // changeStyle: true,
+            // fontSize: 16,
+            // fontColor: Color.White,
+            inputChange: (value: string) => {
+              this.loginCollect.phonenumber = value
+            }
+          })
+
+          // 验证码
+          LoginInput({
+            item: this.inputCaptchaType,
+            inputData: this.loginCollect.smsCode,
+            needCode: true,
+            loginCollect: this.loginCollect,
+            // changeStyle: true,
+            // fontSize: 16,
+            // fontColor: Color.White,
+            // codeSize: 12,
+            inputChange: (value) => {
+              this.loginCollect.smsCode = value
+            }
+          })
+
+          // 设置密码
+          LoginInput({
+            item: this.inputPasswordType,
+            inputData: this.loginCollect.password,
+            needCode: false,
+            isPassword: true,
+            marginBottom: 0,
+            // changeStyle: true,
+            // fontColor: Color.White,
+            // fontSize: 16,
+            inputChange: (value) => {
+              this.loginCollect.password = value
+            }
+          })
+
+          // 确认密码
+          LoginInput({
+            item: this.inputConfirmPasswordType,
+            inputData: this.loginCollect.confirmPassword,
+            isPassword: true,
+            needCode: false,
+            // fontColor: Color.White,
+            // changeStyle: true,
+            // fontSize: 16,
+            inputChange: (value) => {
+              this.loginCollect.confirmPassword = value
+            }
+          })
+
+          // 空白占位
+          Blank()
+            .layoutWeight(1)
+
+          YTButton({
+            btContent: '完成',
+            btFontColor: Color.Black,
+            btFontSize: 20,
+            btlinear: this.linearInfo,
+            btBorder: {width: 0},
+            btPadding: {
+              left: 26,
+              right: 26,
+              top: 9,
+              bottom: 9
+            },
+            click: () => {
+              this.loginCollect.executeLogin("common")
+              // if (!this.value) {
+              //   IBestToast.show({
+              //     type: "warning",
+              //     message: "昵称不能为空"
+              //   })
+              //   return
+              // }
+              // YTUserRequest.changeNickname(this.value, () => {
+              //   IBestToast.show({ message: '名称修改成功' })
+              //   this.showReviseName = false
+              // })
+            }
+
+          }).margin({ bottom: 142 })
+        }
+        .padding({ left: 14, right: 14})
+        .width("100%")
+        .layoutWeight(1)
+      }
+      // .padding({ top: this.safeTop })
+    }
+
+  }
+
+  @Builder
+  backIcon(){
+    Image($r('app.media.diary_back'))
+      .width(12)
+      .height(20)
+      .margin({ left: 16 })
+      // .fillColor('#FFECD5AF')
+      .onClick(() => {
+        yTRouter.pop()
+      })
+
+  }
+}
+
+
+@Builder
+function ChangePassWordBuilder() {
+  NavDestination() {
+    ChangePassWord()
+  }
+  .hideTitleBar(true)
+}

+ 45 - 39
features/user/src/main/ets/pages/LoginPage.ets

@@ -3,9 +3,6 @@ import { LoginCollect } from 'basic/src/main/ets/models/LoginCollect'
 import { RegisterOrResetPassComp } from '../views/RegisterOrResetPassView'
 import { LoginView } from '../views/LoginView'
 
-// import { OtherLoginMethods } from '../views/OtherLoginMethods'
-
-
 @Builder
 function LoginBuilder() {
   NavDestination() {
@@ -20,6 +17,10 @@ struct LoginPage {
   @StorageProp(YTAvoid.SAFE_BOTTOM_KEY) private safeBottom: number = 0
   @State private tabBarIndex: number = 0
   private tabController: TabsController = new TabsController()
+  private linearInfo1: LinearGradientOptions = {
+    colors: [ ['#F7FCF3', 0.1], ['#DEFE9E', 1] ],
+    angle: 90
+  }
 
   aboutToAppear(): void {
 
@@ -34,7 +35,7 @@ struct LoginPage {
             .fontWeight(400)
             .alignSelf(ItemAlign.End)
             .textAlign(TextAlign.Center)
-            .fontColor($r('[basic].color.main_ac_color_light'))
+            .fontColor('#3E5100')
             .onClick(() => {
               yTRouter.routerBack()
             })
@@ -43,24 +44,30 @@ struct LoginPage {
             .borderRadius(12)
             .backgroundColor('#4DFFFFFF')
             .margin({ bottom: 24, right: 28, top: 20 })
-          Text('你好,\n欢迎来到盒小仓')
+          Text('HELLLO,\n欢迎来到朝暮日记')
             .lineHeight(40)
             .fontSize(28)
             .fontWeight(600)
-            .fontColor($r('[basic].color.main_ac_color_dark'))
+            .fontColor('#0E2E1A')
         }
         .padding({ left: 16, })
         .height(193)
         .width('100%')
         .alignItems(HorizontalAlign.Start)
+      }
+      .padding({ top: this.safeTop })
+      .backgroundImage($r('app.media.loginPage_Bg'))
+      .backgroundImageSize(ImageSize.Cover)
 
+      Column(){
         Row() {
           Text('注册')
             .fontSize(16)
             .fontWeight(600)
             .layoutWeight(1)
-            .fontColor(this.tabBarIndex == 0 || this.tabBarIndex == 2 ? '#FF141111' : '#80141111')
-            .backgroundColor(this.tabBarIndex == 0 || this.tabBarIndex == 2 ? Color.White : Color.Transparent)
+            .fontColor(this.tabBarIndex == 0 ? '#FF141111' : '#80141111')
+            .backgroundColor(this.tabBarIndex == 0 || this.tabBarIndex == 2 ? 'rgba(255,255,255,0.5)' : Color.Transparent)
+            // .linearGradient(this.tabBarIndex == 0 ? this.linearInfo1 : this.linearInfo2)
             .textAlign(TextAlign.Center)
             .height(48)
             .borderRadius({ topLeft: 12, topRight: 12, bottomRight: this.tabBarIndex == 1 ? 12 : 0 })
@@ -68,19 +75,21 @@ struct LoginPage {
               this.tabBarIndex = 0
               this.tabController.changeIndex(0)
             })
+
           Text('登录')
             .fontSize(16)
             .fontWeight(600)
             .borderRadius({
               topLeft: 12,
               topRight: 12,
-              bottomLeft: this.tabBarIndex == 0 || this.tabBarIndex == 2 ? 12 : 0
+              bottomLeft: this.tabBarIndex == 0 ? 12 : 0
             })
-            .backgroundColor(this.tabBarIndex == 1 ? Color.White : Color.Transparent)
+            .backgroundColor(this.tabBarIndex == 1 ? 'rgba(255,255,255,0.5)' : Color.Transparent)
             .layoutWeight(1)
             .height(48)
             .textAlign(TextAlign.Center)
-            .fontColor(this.tabBarIndex == 1 ? '#FF141111' : '#80141111')
+            .fontColor(this.tabBarIndex == 1 || this.tabBarIndex == 2 ? '#FF141111' : '#80141111')
+            // .linearGradient(this.tabBarIndex == 1 || this.tabBarIndex == 2 ? this.linearInfo1 : this.linearInfo2)
             .onClick(() => {
               this.tabBarIndex = 1
               this.tabController.changeIndex(1)
@@ -90,39 +99,37 @@ struct LoginPage {
         .alignItems(VerticalAlign.Center)
         .justifyContent(FlexAlign.SpaceBetween)
         .width('100%')
+        .linearGradient(this.linearInfo1)
 
-      }
-      .padding({ top: this.safeTop })
-      .linearGradient({ angle: 135, colors: [['#CAE2F9', -0.1571], ['#D4D1F4', 0.4709], ['#EDF5FD', 1.1235]] })
-      .margin({ bottom: 20 })
+        Tabs({ controller: this.tabController }) {
+          TabContent() {
+            RegisterOrResetPassComp({ loginCollect: new LoginCollect("register") })
 
+          }
+          .padding({ left: 20, right: 20 })
 
-      Tabs({ controller: this.tabController }) {
-        TabContent() {
-          RegisterOrResetPassComp({ loginCollect: new LoginCollect("register") })
-
-        }
-        .padding({ left: 20, right: 20 })
-
-        TabContent() {
-          LoginView({
-            forgetPassClick: () => {
-              this.tabBarIndex = 2
-              this.tabController.changeIndex(2)
-            }
-          })
-        }
-        .padding({ left: 20, right: 20 })
+          TabContent() {
+            LoginView({
+              forgetPassClick: () => {
+                this.tabBarIndex = 2
+                this.tabController.changeIndex(2)
+              }
+            })
+          }
+          .padding({ left: 20, right: 20 })
 
-        TabContent() {
-          RegisterOrResetPassComp({ loginCollect: new LoginCollect("reset") })
+          TabContent() {
+            RegisterOrResetPassComp({ loginCollect: new LoginCollect("reset") })
+          }
+          .padding({ left: 20, right: 20 })
         }
-        .padding({ left: 20, right: 20 })
+        .scrollable(false)
+        .layoutWeight(1)
+        .barHeight(0)
+        .padding({top: 20})
       }
-      .scrollable(false)
-      .layoutWeight(1)
-      .barHeight(0)
-
+      // .backgroundImage(this.tabBarIndex == 0 ? $r('app.media.loginPage_Bg_left') : $r('app.media.loginPage_Bg_right'))
+      // .backgroundImageSize(ImageSize.Contain)
     }
 
     .padding({
@@ -132,4 +139,3 @@ struct LoginPage {
     .height('100%')
   }
 }
-

+ 1 - 2
features/user/src/main/ets/pages/Privacy.ets

@@ -17,11 +17,10 @@ export struct Privacy {
   private webviewController: WebviewController = new webview.WebviewController()
 
   build() {
-
     Column() {
       YTHeader({ title: "隐私政策" })
       Web({
-        src: "https://hm-static.ytpm.net/friend/doc/%E9%9A%90%E7%A7%81%E6%94%BF%E7%AD%96.html",
+        src: "https://hm-test.ytpm.net/diaryPrivatePolicy",
         controller: this.webviewController,
         renderMode: RenderMode.ASYNC_RENDER // 设置渲染模式
       }).padding(20)

+ 61 - 38
features/user/src/main/ets/pages/SettingPage.ets

@@ -15,6 +15,7 @@ import {
   YTUserRequest
 } from 'basic'
 
+
 @Builder
 function settingBuilder() {
   NavDestination() {
@@ -30,19 +31,28 @@ struct SettingPage {
   @State showReviseName: boolean = false
   @State showHeaderImgRevise: boolean = false
   @State value: string = ''
+
   reviseBuilderArr: Array<BasicType<undefined>> = [
     {
       text: '头像修改',
-      src: '',
+      src: 'head',
       click: () => {
         this.showHeaderImgRevise = true
       }
     },
     {
       text: '昵称修改',
+      src: 'name',
       click: () => {
         this.showReviseName = true
       }
+    },
+    {
+      text: '密码设置',
+      click: () => {
+        yTRouter.pushPathByName("ChangePassWord", null)
+
+      }
     }
   ]
   options: BasicType<undefined>[] = [
@@ -74,6 +84,11 @@ struct SettingPage {
       }
     },
   ]
+  private linearInfo: LinearGradientOptions = {
+    colors: [ ['#B9FD2A', 0.01], ['#F5FD6D', 1] ],
+    angle: 110
+  }
+
 
   build() {
     Column() {
@@ -89,35 +104,36 @@ struct SettingPage {
                 .backgroundColor('#0A000000')
             }
             .padding({ left: 12, right: 8 })
-            .bindSheet($$this.showHeaderImgRevise, this.changeBuilder, {
-              height: 204,
-              backgroundColor: Color.White,
-              showClose: false
-            })
           }
         })
-        YTButton({
-          btContent: '退出登录', click: () => {
-            this.userInfo.logout()
-            yTRouter.routerBack()
-            IBestToast.show({ message: '退出登录成功' })
-          }
-        })
-          .margin({ top: 426, bottom: 12 })
         YTButton({
           btContent: '注销用户',
-          btFontColor: Color.Red,
+          btFontColor: '#ff989494',
           bgc: Color.White,
           click: () => {
             yTToast.doubleConfirm({
-              text: '警告⚠', message: '确定要注销吗?\n注销后数据可能丢失无法恢复!', click: () => {
+              text: '警告⚠', message: '确定要注销吗?\n注销后数据可能丢失无法恢复!',
+              click: () => {
                 userInfo.logout()
                 yTToast.hide()
                 yTRouter.routerBack()
-              }
+                YTUserRequest.logout()
+              },
             })
           }
         })
+          .margin({ top: 426, bottom: 12 })
+        YTButton({
+          btContent: '退出登录', click: () => {
+            this.userInfo.logout()
+            yTRouter.routerBack()
+            IBestToast.show({ message: '退出登录成功' })
+          },
+          btlinear: this.linearInfo,
+          btFontColor: Color.Black,
+          btFontSize: 16
+        })
+
       }
       .bindSheet($$this.showReviseName, this.reviseNameBuilder, {
         height: 275,
@@ -130,7 +146,11 @@ struct SettingPage {
       })
     }
     .padding({ bottom: this.safeBottom })
-
+    .bindSheet($$this.showHeaderImgRevise, this.changeBuilder, {
+      height: 204,
+      backgroundColor: Color.White,
+      showClose: false
+    })
   }
 
   @Builder
@@ -140,12 +160,12 @@ struct SettingPage {
         .fontSize($r('[basic].float.page_text_font_size_12'))
         .fontColor('#80000000')
       Row() {
-        if (typeof item.src == 'string') {
-          Image(this.userInfo.getHeadImg() ? this.userInfo.getHeadImg() : $r('app.media.default_img'))
+        if (item.src === 'head') {
+          Image(this.userInfo.getHeadImg() ? this.userInfo.getHeadImg() : $r('app.media.app_icon'))
             .height(24)
             .width(24)
             .borderRadius(12)
-        } else {
+        } else if (item.src === 'name') {
           Text(this.userInfo.getName() ?? this.userInfo.getPhoneNumber() ?? this.userInfo.getId()?.toString())
             .fontSize($r('[basic].float.page_text_font_size_12'))
             .fontColor('#CC000000')
@@ -167,21 +187,22 @@ struct SettingPage {
     Column() {
 
       Text('昵称')
-        .width('100%')
         .height(36)
+        .width('100%')
+        .fontSize(16)
+        .fontColor('#ff989494')
         .textAlign(TextAlign.Start)
-        .fontSize(12)
 
       TextInput({ text: $$this.value, placeholder: '请输入昵称' })
-        .borderRadius(4)
-        .fontSize(12)
-        .placeholderFont({ size: 12 })
-        .placeholderColor('#14000000')
         .height(36)
+        .fontSize(12)
         .width('100%')
-        .backgroundColor(Color.White)
-        .border({ width: 1, color: '#14000000' })
-        .margin({ bottom: 25 })
+        .border({ width: { bottom: 1 } })
+        .borderRadius(0)
+        .placeholderColor('#1C1C1C')
+        .placeholderFont({ size: 12 })
+        .backgroundColor(Color.Transparent)
+        .margin({ bottom: 44 })
         .onChange((value) => {
           if (value.length > 7) {
             this.value = value.slice(0, 7)
@@ -189,20 +210,20 @@ struct SettingPage {
           }
         })
 
-      Row({ space: 32 }) {
+      Row({ space: 48 }) {
         YTButton({
           btContent: '取消',
-          btHeight: 25,
-          btWidth: 78,
+          btHeight: 42,
+          btWidth: 104,
           btBorder: { width: 1, color: '#1A000000' },
+          btFontColor: '#353C46',
           btPadding: {
             left: 26,
             right: 26,
             top: 4,
             bottom: 4
           },
-          bgc: Color.White,
-          btFontColor: $r('sys.color.mask_secondary'),
+          bgc: '#F5F5F7',
           click: () => {
             this.showReviseName = false
             this.value = ''
@@ -211,8 +232,10 @@ struct SettingPage {
         })
         YTButton({
           btContent: '完成',
-          btHeight: 25,
-          btWidth: 78,
+          btHeight: 42,
+          btWidth: 104,
+          btlinear: this.linearInfo,
+          btFontColor: '#353C46',
           btPadding: {
             left: 26,
             right: 26,
@@ -239,7 +262,7 @@ struct SettingPage {
       .width('100%')
 
     }
-    .padding({ left: 22, right: 22, top: 8 })
+    .padding({ left: 22, right: 22, top: 24 })
   }
 
   @Builder

+ 7 - 1
features/user/src/main/ets/pages/SuggestionPage.ets

@@ -13,6 +13,10 @@ struct SuggestionPage {
   @StorageProp(YTAvoid.SAFE_BOTTOM_KEY) private safeBottom: number = 0
   @State private description: string = ''
   @State private contact: string = ''
+  private linearInfo: LinearGradientOptions = {
+    colors: [ ['#B9FD2A', 0.01], ['#F5FD6D', 1] ],
+    angle: 110
+  }
 
   build() {
     Column() {
@@ -125,7 +129,9 @@ struct SuggestionPage {
             YTUserRequest.questionBack(this.description, this.contact)
             // //TODO 发请求提交反馈
             // YTLog.info(this.description + this.contact + '反馈提交了')
-          }
+          },
+          btlinear: this.linearInfo,
+          btFontColor: Color.Black,
         })
       }
       .padding({ left: 18, right: 18 })

+ 1 - 1
features/user/src/main/ets/pages/UserAgreement.ets

@@ -17,7 +17,7 @@ struct UserAgreementPage {
     Column() {
       YTHeader({ title: '用户协议' })
       Web({
-        src: "https://hm-static.ytpm.net/friend/doc/%E7%94%A8%E6%88%B7%E5%8D%8F%E8%AE%AE.html",
+        src: "https://hm-test.ytpm.net/diaryUserAgreement",
         controller: this.webviewController,
         renderMode: RenderMode.ASYNC_RENDER // 设置渲染模式
       })

+ 19 - 6
features/user/src/main/ets/views/LoginView.ets

@@ -73,7 +73,8 @@ export struct LoginView {
           inputChange: (value: string) => {
             this.loginCollect.smsCode = value
           },
-          marginBottom: 19
+          marginBottom: 19,
+
         })
       }
 
@@ -86,7 +87,7 @@ export struct LoginView {
       Row() {
         if (!this.isPassword) {
           Text('密码登录')
-            .fontColor($r('[basic].color.main_ac_color_dark'))
+            .fontColor($r('[basic].color.main_blank'))
             .fontSize(12)
             .fontWeight(700)
             .onClick(() => {
@@ -95,7 +96,7 @@ export struct LoginView {
           Blank()
         } else {
           Text('验证码登录')
-            .fontColor($r('[basic].color.main_ac_color_dark'))
+            .fontColor($r('[basic].color.main_blank'))
             .fontWeight(700)
             .fontSize(12)
             .onClick(() => {
@@ -103,7 +104,7 @@ export struct LoginView {
             })
           Blank()
           Text('忘记密码?')
-            .fontColor($r('[basic].color.main_ac_color_dark'))
+            .fontColor($r('[basic].color.main_blank'))
             .fontSize(12)
             .fontWeight(700)
             .onClick(() => {
@@ -119,12 +120,24 @@ export struct LoginView {
         btContent: '登录',
         click: () => {
           this.loginCollect.executeLogin("common")
-        }
+        },
+        btFontColor: Color.Black,
+        btFontSize: 18,
+        btlinear: {
+          colors: [ ['#B9FD2A', 0.5], ['#F5FD6D', 1] ],
+          angle: 135
+        },
+        btPadding: {
+          top: 12,
+          bottom: 12,
+        },
+        btHeight: 48
       })
 
 
+
       Text('未注册的手机号码登陆后将自动注册')
-        .fontColor($r('[basic].color.main_ac_color_dark'))
+        .fontColor($r('[basic].color.main_blank'))
         .fontSize(12)
         .margin({ top: 16, bottom: 56 })
         .alignSelf(ItemAlign.Start)

+ 145 - 69
features/user/src/main/ets/views/Mine.ets

@@ -8,15 +8,28 @@ import {
   YTLog,
   yTRouter
 } from 'basic'
-import { common, Want } from '@kit.AbilityKit'
+import {  Want } from '@kit.AbilityKit'
 import { BusinessError } from '@kit.BasicServicesKit'
 import { BUNDLE_NAME } from 'BuildProfile'
+import { image } from '@kit.ImageKit'
+import { systemShare } from '@kit.ShareKit'
+import { common } from '@kit.AbilityKit'
+import { uniformTypeDescriptor } from '@kit.ArkData';
+
 
 @Component
 export struct Mine {
   @StorageProp(YTAvoid.SAFE_TOP_KEY) safeTop: number = 0
   @StorageProp(UserInfo.KEY) userInfo: UserInfo = userInfo
   setArr: Array<BasicType<undefined>> = [
+    {
+      text: '分享给好友',
+      message: '去分享',
+      click: () => {
+        this.share()
+      },
+      src: $r('app.media.right_arrow')
+    },
     {
       text: '意见反馈',
       click: () => {
@@ -55,97 +68,160 @@ export struct Mine {
     }
   ]
 
+
+  private async share() {
+    try {
+      // 构造ShareData,需配置一条有效数据信息
+      const data = new systemShare.SharedData({
+        // utd: uniformTypeDescriptor.UniformDataType.HYPERLINK,
+        utd: uniformTypeDescriptor.UniformDataType.TEXT,
+        title: '朝暮日记',
+        content: 'http://appgallery.huawei.com/app/detail?id=6917582300519105855',
+        description: "http://appgallery.huawei.com/app/detail?id=6917582300519105855"
+      })
+      const controller = new systemShare.ShareController(data)
+      const context = this.getUIContext().getHostContext()! as common.UIAbilityContext;
+      // 进行分享面板显示
+      controller.show(context, {
+        previewMode: systemShare.SharePreviewMode.DEFAULT,
+        selectionMode: systemShare.SelectionMode.SINGLE,
+        // anchor: { windowOffset: { x: 0, y: 0 }, size: { width: this.breakWidth, height: 500 } }
+      })
+    } catch (error) {
+      IBestToast.show({ message: '当前设备不支持', duration: 500 })
+    }
+  }
+
+  private toSettingPage(){
+      if (this.userInfo.checkLogin()) {
+        yTRouter.router2SettingPage()
+        return
+      }
+      yTRouter.router2LoginPage()
+  }
+
+  private linearInfo: LinearGradientOptions = {
+    colors: [ ['#B9FD2A', 0.01], ['#F5FD6D', 1] ],
+    angle: 110
+  }
   aboutToAppear(): void {
 
   }
 
   build() {
     Column() {
-      Row() {
-        Row() {
-          Image(this.userInfo.getHeadImg() ?? $r('app.media.app_icon'))
-            .aspectRatio(1)
-            .height(40)
-            .borderRadius(20)
-            .margin({ right: 9 })
+      // 空白占位
+      Row()
+      .height(212)
 
-          Column({ space: 7 }) {
+      // 主体
+      Column({space: 20}){
+        // 头像 + 编辑按钮
+        Column(){
+          // 头像
+          Row(){
+            Image(this.userInfo.getHeadImg() ?? $r('app.media.app_icon'))
+              .aspectRatio(1)
+              .height(80)
+              .borderRadius(40)
+          }
+          .border({
+            width: 5,
+            color: Color.White
+          })
+          .borderRadius(40)
+          .position({ y: -40 })
+          .onClick(() => {
+            this.toSettingPage()
+          })
+
+          // 编辑按钮
+          Row(){
+            Text(this.userInfo.checkLogin() ? "编辑" : "去登录")
+              .fontSize(14)
+              .borderRadius(20)
+              .fontWeight(400)
+              .fontColor(Color.Black)
+              .linearGradient(this.linearInfo)
+              .padding({ left: 14, top: 5, right: 14, bottom: 5 })
+          }
+          .width("100%")
+          .alignItems(VerticalAlign.Center)
+          .justifyContent(FlexAlign.End)
+          .padding({top: 32})
+          .onClick(() => {
+            this.toSettingPage()
+          })
+
+          // 昵称 + 编辑按钮
+          Row(){
             Text(this.userInfo.getName() ?? this.userInfo.getPhoneNumber() ?? this.userInfo.getId()?.toString() ??
               '未登录')
-              .fontSize($r('[basic].float.page_text_font_size_16'))
+              .fontSize(18)
               .fontColor('Color.Black')
-            Text() {
-              Span('ID:' + (this.userInfo.getId()?.toString().padStart(8, '0') ?? '00000000'))
-              ImageSpan($r('app.media.copy'))
-                .width(7)
-                .height(8)
-                .margin({ left: 4 })
-                .onClick(() => {
-                  copyText((this.userInfo.getId()?.toString().padStart(8, '0') ?? '00000000'))
-                })
-                .offset({ bottom: 4 })
-            }
-            .fontColor('#80000000')
-            .fontSize($r('[basic].float.page_text_font_size_10'))
+              .onClick(() => {
+                this.toSettingPage()
+              })
           }
-          .alignItems(HorizontalAlign.Start)
+          .width("100%")
+          .alignItems(VerticalAlign.Center)
+          .justifyContent(FlexAlign.Start)
         }
-        .onClick(() => {
-
-          if (this.userInfo.checkLogin()) {
-            yTRouter.router2SettingPage()
-            return
-          }
-          yTRouter.router2LoginPage()
-        })
-      }
-      .width('100%')
-      .margin({ bottom: 30 })
 
-      // ShowBannerAd()
-      Column() {
-        List() {
-          ForEach(this.setArr, (item: BasicType<undefined>, index) => {
-            ListItem() {
-              Row() {
-                Text(item.text)
-                  .fontColor('#80000000')
-                  .fontSize(12)
-                if (!index) {
-                  Row() {
-                    Text(this.userInfo.getAiNum()?.toString() ?? '')
-                      .fontWeight(600)
-                      .fontSize($r('[basic].float.page_text_font_size_14'))
+        // 设置项
+        Column() {
+          List({space: 20}) {
+            ForEach(this.setArr, (item: BasicType<undefined>, index) => {
+              ListItem() {
+                Row() {
+                  Text(item.text)
+                    .fontColor('#1C1C1C')
+                    .fontSize(16)
+                  if (item.message) {
+                    Row() {
+                      Text(item.message ?? '')
+                        .fontWeight(400)
+                        .fontColor('#ff989494')
+                        .fontSize($r('[basic].float.page_text_font_size_14'))
+                      Image($r('app.media.right_arrow'))
+                        .width(24)
+                        .aspectRatio(1)
+                        .opacity(0.7)
+                    }
+                  } else {
                     Image($r('app.media.right_arrow'))
                       .width(24)
                       .aspectRatio(1)
+                      .opacity(0.7)
                   }
-                } else {
-                  Image($r('app.media.right_arrow'))
-                    .width(24)
-                    .aspectRatio(1)
                 }
+                .width('100%')
+                .height(36)
+                .justifyContent(FlexAlign.SpaceBetween)
+                // .padding({ top: 10, bottom: 10 })
+                .onClick(() => {
+                  item.click?.()
+                })
               }
-              .width('100%')
-              .height(36)
-              .justifyContent(FlexAlign.SpaceBetween)
-              .onClick(() => {
-                item.click?.()
-              })
-            }
-          })
+            })
+          }
+          .divider({ strokeWidth: 1, color: '#0A000000', endMargin: 10 })
+          .margin({ top: 30 })
+          .width('100%')
+          .height('100%')
         }
-        .padding({ left: 12, right: 4 })
-        .divider({ strokeWidth: 1, color: '#0A000000', endMargin: 8 })
-        .margin({ top: 30 })
+        .layoutWeight(1)
         .width('100%')
-        .height('100%')
       }
-      .layoutWeight(1)
-      .width('100%')
-
+      .width("100%")
+      .backgroundColor(Color.White)
+      .justifyContent(FlexAlign.Start)
+      .alignItems(HorizontalAlign.Start)
+      .padding({ left: 24, right: 24 })
     }
-    .padding({ top: this.safeTop + 22, left: 16, right: 16 })
     .height('100%')
+    .backgroundImage($r('app.media.Mine_Bg'))
+    .backgroundImageSize(ImageSize.Contain)
+
   }
 }

+ 13 - 2
features/user/src/main/ets/views/RegisterOrResetPassView.ets

@@ -76,12 +76,23 @@ export struct RegisterOrResetPassComp {
         click: () => {
           this.loginCollect.executeLogin("common")
         },
-        btBorderRadius: 32
+        btBorderRadius: 32,
+        btlinear: {
+          colors: [ ['#B9FD2A', 0.5], ['#F5FD6D', 1] ],
+          angle: 135
+        },
+        btPadding: {
+          top: 12,
+          bottom: 12,
+        },
+        btHeight: 48,
+        btFontColor: Color.Black,
+        btFontSize: 18
       })
 
       Text('注册成功后将自动登录')
         .fontSize(10)
-        .fontColor($r('[basic].color.main_ac_color_dark'))
+        .fontColor($r('[basic].color.main_blank'))
         .margin({ top: 16 })
     }
     .width('100%')

BIN
features/user/src/main/resources/base/media/Mine_Bg.png


+ 1 - 0
features/user/src/main/resources/base/media/diary_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="1755071625373" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="6319" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M395.21518 513.604544l323.135538-312.373427c19.052938-18.416442 19.052938-48.273447 0-66.660212-19.053961-18.416442-49.910737-18.416442-68.964698 0L291.75176 480.290811c-19.052938 18.416442-19.052938 48.273447 0 66.660212l357.633237 345.688183c9.525957 9.207709 22.01234 13.796214 34.497699 13.796214 12.485359 0 24.971741-4.588505 34.466999-13.82896 19.052938-18.416442 19.052938-48.242747 0-66.660212L395.21518 513.604544z" fill="#272636" p-id="6320"></path></svg>

BIN
features/user/src/main/resources/base/media/loginPage_Bg.png


BIN
features/user/src/main/resources/base/media/loginPage_Bg_left.png


BIN
features/user/src/main/resources/base/media/loginPage_Bg_right.png


+ 7 - 0
features/user/src/main/resources/base/profile/router_map.json

@@ -49,6 +49,13 @@
       "data": {
         "description": "this is DelPhotoPage"
       }
+    },{
+      "name": "ChangePassWord",
+      "pageSourceFile": "src/main/ets/pages/ChangePassword.ets",
+      "buildFunction": "ChangePassWordBuilder",
+      "data": {
+        "description": "this is DelPhotoPage"
+      }
     }
   ]
 }

+ 10 - 1
products/entry/src/main/ets/entryability/EntryAbility.ets

@@ -3,6 +3,7 @@ import { hilog } from '@kit.PerformanceAnalysisKit';
 import { window } from '@kit.ArkUI';
 import {
   AppStorageKeyCollect,
+  IBestInit,
   jHStartAd,
   permissionController,
   YTAvoid,
@@ -46,7 +47,7 @@ export default class EntryAbility extends UIAbility {
       if (AppStorage.get<string>(AppStorageKeyCollect.TOKEN)) {
         YTUserRequest.refreshUserInfo()
       }
-      // IBestInit(windowStage, this.context)
+      IBestInit(windowStage, this.context)
       bundleManager.getBundleInfoForSelf(bundleManager.BundleFlag.GET_BUNDLE_INFO_WITH_SIGNATURE_INFO)
         .then(res => {
           YTLog.info(`signatureInfo:` + JSON.stringify(res.signatureInfo))
@@ -112,8 +113,16 @@ export default class EntryAbility extends UIAbility {
         name: 'category'
       })
       AppStorage.setOrCreate<preferences.Preferences>('category', preference)
+
+
+      windowClass.on('windowSizeChange', size => {
+        YTBreakPoint.setBreakPoint(size.width)
+        AppStorage.setOrCreate(AppStorageKeyCollect.SCREEN_WIDTH, px2vp(size.width))
+        AppStorage.setOrCreate(AppStorageKeyCollect.SCREEN_HEIGHT, px2vp(size.height))
+      })
     });
 
+
   }
 
   onWindowStageDestroy(): void {

+ 13 - 19
products/entry/src/main/ets/pages/Index.ets

@@ -1,6 +1,6 @@
 import { BasicType, YTAvoid, yTRouter, yTToast } from 'basic';
 import { Mine } from 'user/src/main/ets/views/Mine';
-import { MainView, SecondView, ThirdView } from 'feature';
+import { MainView, SecondView } from 'feature';
 
 @Entry
 @Component
@@ -10,24 +10,19 @@ struct Index {
   //tabs展示内容
   contentList: BasicType<undefined>[] = [
     {
-      text: '日历',
-      src: $r('app.media.app_icon'),
-      acSrc: $r('app.media.app_icon')
+      text: '记录',
+      src: $r('app.media.Recode_Icon_0'),
+      acSrc: $r('app.media.Recode_Icon_1')
     },
     {
-      text: '黄历',
-      src: $r('app.media.app_icon'),
-      acSrc: $r('app.media.app_icon')
-    },
-    {
-      text: '卡片',
-      src: $r('app.media.app_icon'),
-      acSrc: $r('app.media.app_icon')
+      text: '日记',
+      src: $r('app.media.Diary_Icon_0'),
+      acSrc: $r('app.media.Diary_Icon_1')
     },
     {
       text: '我的',
-      src: $r('app.media.app_icon'),
-      acSrc: $r('app.media.app_icon')
+      src: $r('app.media.My_Icon_0'),
+      acSrc: $r('app.media.My_Icon_1')
     }
   ]
   tabsController: TabsController = new TabsController()
@@ -42,7 +37,7 @@ struct Index {
   build() {
     Navigation(yTRouter) {
       Column() {
-        Tabs({ controller: this.tabsController }) {
+        Tabs({ controller: this.tabsController, index: 0 }) {
           ForEach(this.contentList, (_: BasicType<undefined>, index) => {
             TabContent() {
               if (index == 0) {
@@ -51,8 +46,6 @@ struct Index {
               } else if (index == 1) {
                 SecondView()
               } else if (index == 2) {
-                ThirdView()
-              } else {
                 Mine()
               }
             }
@@ -63,6 +56,7 @@ struct Index {
         })
         .barHeight(0)
         .layoutWeight(1)
+        .scrollable(false)
 
         Row() {
           ForEach(this.contentList, (item: BasicType<undefined>, index) => {
@@ -94,8 +88,8 @@ struct Index {
       Text(item.text)
         .fontSize($r('[basic].float.page_text_font_size_10'))
         .lineHeight(16)
-        .fontColor(this.currentIndex == item.index ? $r('[basic].color.main_ac_color_dark') :
-        $r('[basic].color.main_na_color'))
+        .fontColor(this.currentIndex == item.index ? $r('[basic].color.main_blank') :
+        $r('[basic].color.mask_color'))
 
     }
     .margin({ top: 5 })

+ 1 - 1
products/entry/src/main/resources/base/element/string.json

@@ -10,7 +10,7 @@
     },
     {
       "name": "EntryAbility_label",
-      "value": "label"
+      "value": "朝暮日记"
     },
     {
       "name": "reason",

BIN
products/entry/src/main/resources/base/media/Diary_Icon_0.png


BIN
products/entry/src/main/resources/base/media/Diary_Icon_1.png


BIN
products/entry/src/main/resources/base/media/My_Icon_0.png


BIN
products/entry/src/main/resources/base/media/My_Icon_1.png


BIN
products/entry/src/main/resources/base/media/Recode_Icon_0.png


BIN
products/entry/src/main/resources/base/media/Recode_Icon_1.png


BIN
products/entry/src/main/resources/base/media/startIcon.png


BIN
sign/朝暮日记调试证书Debug.p7b