Pārlūkot izejas kodu

新增登录模板 修改了一些存在的问题 新增loginCollect类统一管理登录

wangcy 3 mēneši atpakaļ
vecāks
revīzija
c19f589048
34 mainītis faili ar 1267 papildinājumiem un 345 dzēšanām
  1. 19 11
      commons/basic/Index.ets
  2. 2 2
      commons/basic/src/main/ets/ads/RewardAd.ets
  3. 88 0
      commons/basic/src/main/ets/apis/YTRequest.ets
  4. 207 0
      commons/basic/src/main/ets/apis/YTUserRequest.ets
  5. 3 3
      commons/basic/src/main/ets/components/adComp/ShowBannerAd.ets
  6. 2 2
      commons/basic/src/main/ets/components/adComp/ShowJHRewardAd.ets
  7. 21 20
      commons/basic/src/main/ets/components/generalComp/AgreePrivacy.ets
  8. 2 2
      commons/basic/src/main/ets/components/generalComp/ChatList.ets
  9. 1 1
      commons/basic/src/main/ets/components/generalComp/ReviseImgHeaderBuilder.ets
  10. 0 0
      commons/basic/src/main/ets/components/generalComp/YTButton.ets
  11. 13 12
      commons/basic/src/main/ets/components/generalComp/YTHeader.ets
  12. 0 0
      commons/basic/src/main/ets/components/generalComp/YTSearch.ets
  13. 0 0
      commons/basic/src/main/ets/components/generalComp/YTTiltleBar.ets
  14. 3 3
      commons/basic/src/main/ets/components/generalComp/YtDoubleConfirm.ets
  15. 352 0
      commons/basic/src/main/ets/models/LoginCollect.ets
  16. 3 0
      commons/basic/src/main/ets/models/index.ets
  17. 10 9
      commons/basic/src/main/ets/utils/FormatDate.ets
  18. 6 8
      commons/basic/src/main/ets/utils/YTRequest.ets
  19. 24 22
      commons/basic/src/main/ets/utils/YTRouter.ets
  20. 10 5
      commons/basic/src/main/ets/utils/YTToast.ets
  21. 44 56
      features/user/src/main/ets/components/LoginInput.ets
  22. 10 4
      features/user/src/main/ets/components/OtherLoginMethods.ets
  23. 40 29
      features/user/src/main/ets/components/Terms.ets
  24. 3 3
      features/user/src/main/ets/pages/AboutUS.ets
  25. 11 11
      features/user/src/main/ets/pages/DelPhotoPage.ets
  26. 106 109
      features/user/src/main/ets/pages/LoginPage.ets
  27. 13 15
      features/user/src/main/ets/pages/SettingPage.ets
  28. 5 5
      features/user/src/main/ets/pages/SuggestionPage.ets
  29. 136 0
      features/user/src/main/ets/views/LoginView.ets
  30. 15 6
      features/user/src/main/ets/views/Mine.ets
  31. 103 0
      features/user/src/main/ets/views/RegisterOrResetPassView.ets
  32. BIN
      features/user/src/main/resources/base/media/hua_wei.png
  33. 12 4
      products/entry/src/main/ets/entryability/EntryAbility.ets
  34. 3 3
      products/entry/src/main/ets/pages/Index.ets

+ 19 - 11
commons/basic/Index.ets

@@ -1,8 +1,14 @@
+export { permissionController } from './src/main/ets/utils/PermissionControl'
+
+export { YTUserRequest } from './src/main/ets/apis/YTUserRequest'
+
+export { YTDate } from './src/main/ets/utils/FormatDate'
+
 export { AppStorageKeyCollect } from './src/main/ets/constants'
 
 export * from '@ibestservices/ibest-ui'
 
-export { reviseImgHeaderBuilder } from './src/main/ets/components/ReviseImgHeaderBuilder'
+export { reviseImgHeaderBuilder } from './src/main/ets/components/generalComp/ReviseImgHeaderBuilder'
 
 export { takePicture } from './src/main/ets/utils/TakePicture'
 
@@ -12,37 +18,35 @@ export { Log as YTLog } from '@abner/log'
 
 export { YtDebounce } from "./src/main/ets/utils/DebounceLoad"
 
-export { ShowBannerAd } from "./src/main/ets/components/ShowBannerAd"
+export { ShowBannerAd } from "./src/main/ets/components/adComp/ShowBannerAd"
 
 export { BannerAd } from "./src/main/ets/ads/BannerAd"
 
-export { ShowJHRewardAd } from "./src/main/ets/components/ShowJHRewardAd"
+export { ShowJHRewardAd } from "./src/main/ets/components/adComp/ShowJHRewardAd"
 
 export { jHStartAd } from "./src/main/ets/ads/StartAd"
 
 export { AdStatus } from "./src/main/ets/constants"
 
-export { PermissionControl } from "./src/main/ets/utils/PermissionControl"
 
-export { YTRequest } from "./src/main/ets/utils/YTRequest"
+export { YTRequest } from "./src/main/ets/apis/YTRequest"
+
 
 export { HuaweiAuthPlugin } from "./src/main/ets/utils/HuaWeiAuthPlugin"
 
 export { userInfo, UserInfo } from "./src/main/ets/models/UserInfo"
 
-export { YTToast } from "./src/main/ets/utils/YTToast"
+export { yTToast } from "./src/main/ets/utils/YTToast"
 
-export { YTButton } from "./src/main/ets/components/YTButton"
+export { YTButton } from "./src/main/ets/components/generalComp/YTButton"
 
-export { YTHeader } from "./src/main/ets/components/YTHeader"
+export { YTHeader } from "./src/main/ets/components/generalComp/YTHeader"
 
 export { Upload } from "./src/main/ets/utils/UploadFile"
 
-// export * from "@ibestservices/ibest-ui"
-
 export { YTAvoid } from "./src/main/ets/utils/YTAvoid"
 
-export { YTRouter } from "./src/main/ets/utils/YTRouter"
+export { yTRouter } from "./src/main/ets/utils/YTRouter"
 
 export * from "./src/main/ets/utils/YTBreakPoint"
 
@@ -66,3 +70,7 @@ export * from './src/main/ets/models'
 
 
 
+
+
+
+

+ 2 - 2
commons/basic/src/main/ets/ads/RewardAd.ets

@@ -3,7 +3,7 @@ import { common } from '@kit.AbilityKit';
 import { hilog } from '@kit.PerformanceAnalysisKit';
 import { BusinessError, commonEventManager, emitter } from '@kit.BasicServicesKit';
 import { AdStatus } from '../constants';
-import { YTLog, YTToast } from '../../../../Index';
+import { YTLog, yTToast } from '../../../../Index';
 import { IBestToast } from '@ibestservices/ibest-ui';
 
 const KEY_REWARD_DATA = "reward_ad_data";
@@ -66,7 +66,7 @@ export class RewardAd {
               hilog.info(0x0000, 'testTag', '%{public}s', `onAdOpen`);
               //关闭弹窗
               IBestToast.hide()
-              YTToast.getInstance().hide()
+              yTToast.hide()
               break;
             case AdStatus.AD_CLICKED:
               hilog.info(0x0000, 'testTag', '%{public}s', `onAdClick`);

+ 88 - 0
commons/basic/src/main/ets/apis/YTRequest.ets

@@ -0,0 +1,88 @@
+import axios, {
+  AxiosError,
+  AxiosHeaders,
+  AxiosRequestConfig,
+  AxiosResponse,
+  InternalAxiosRequestConfig
+} from '@ohos/axios';
+import { IBestToast, YTLog } from '../../../../Index';
+import { AppStorageKeyCollect } from '../constants';
+import { userInfo } from '../models/UserInfo';
+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 instance = axios.create({
+  baseURL,
+  timeout: 5000
+})
+
+// 添加请求拦截器
+instance.interceptors.request.use((config: InternalAxiosRequestConfig) => {
+
+  // 对请求数据做点什么
+  if (AppStorage.get<string>(AppStorageKeyCollect.TOKEN)) {
+    config.headers.Authorization = AppStorage.get<string>(AppStorageKeyCollect.TOKEN)
+  }
+  return config;
+}, (error: AxiosError) => {
+  // 对请求错误做些什么
+
+  return Promise.reject(error);
+});
+
+
+// 添加响应拦截器
+instance.interceptors.response.use((response: AxiosResponse) => {
+  // 对响应数据做点什么
+  YTLog.info(response)
+  // 对响应错误做点什么
+  if (response.data.code == 401) {
+    userInfo.logout()
+    yTRouter.router2LoginPage()
+    return Promise.reject('401');
+  }
+  if (response.data.code == 500) {
+    IBestToast.show({ message: response.data.msg, type: "fail" })
+    return Promise.reject(response.data);
+  }
+
+  return response.data.data;
+}, (error: AxiosError) => {
+  YTLog.error(error)
+  setTimeout(() => {
+    IBestToast.hide()
+    setTimeout(() => {
+      IBestToast.show({ message: '请求超时,请检查网络' })
+    }, 100)
+  }, 1000)
+  return Promise.reject(error);
+});
+
+
+export class YTRequest {
+  static get<T>(url: string, params?: Record<string, string | number | boolean>, headers?: Record<string, string>) {
+    return instance.get<null, T, null>(url, { params, headers })
+  }
+
+  static post<T, D>(url: string, data?: D, params?: Record<string, string | number | boolean>, headers?: AxiosHeaders) {
+    return instance.post<null, T, D>(url, data, { params, headers })
+  }
+
+  static delete<T>(url: string, params?: Record<string, string | number | boolean> | object, headers?: AxiosHeaders) {
+    return instance.delete<null, T, null>(url, { params, headers })
+  }
+
+  static put<T, D>(url: string, data?: D, params?: Record<string, string | number | boolean>, headers?: AxiosHeaders) {
+    return instance.put<null, T, D>(url, data, { params, headers })
+  }
+
+  static upPost<T, D>(url: string, data: D, configs?: AxiosRequestConfig<D>) {
+    return instance.post<string, T, D>(url, data, configs)
+  }
+}
+
+

+ 207 - 0
commons/basic/src/main/ets/apis/YTUserRequest.ets

@@ -0,0 +1,207 @@
+import { IBestToast } from '@ibestservices/ibest-ui'
+import { AppStorageKeyCollect } 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 { AxiosProgressEvent, FormData } from '@ohos/axios'
+import { YTDate } from '../utils/FormatDate'
+import { HuaweiAuthPlugin } from '../utils/HuaWeiAuthPlugin'
+
+//用户相关api
+export class YTUserRequest extends YTRequest {
+  //获取验证码
+  static getLoginCaptcha(phonenumber: string, result: ResultCallBack<LoginCollect>) {
+    YTUserRequest.post<LoginCollect, LoginCollect>(
+      `/warehouseApUser/sendSmsCode`,
+      new LoginCollect('login')
+        .setPhonenumber(phonenumber)
+    )
+      .then(res => {
+        result(res)
+      })
+      .catch((err: Error) => {
+        result(undefined, err)
+      })
+  }
+
+  //验证码登录
+  static phonenumberLogin(param: LoginCollect, result?: ResultCallBack<UserInfo>) {
+    if (param.getUuid() !== undefined) {
+      YTUserRequest.post<ReqString, LoginCollect>(`/warehouseApUser/phoneLogin`, param)
+        .then(res => {
+          userInfo.setToken(res[AppStorageKeyCollect.TOKEN])
+          YTUserRequest.refreshUserInfo((res) => {
+            IBestToast.show({ message: '登录成功' })
+            yTRouter.routerBack()
+            result?.(res)
+          })
+        })
+    } else {
+      IBestToast.show({ message: "请求异常,请重新发送验证码", type: "fail" })
+    }
+  }
+
+  //注册
+  static register(param: LoginCollect) {
+    if (param.getUuid() !== undefined) {
+      YTUserRequest.post<ReqString, LoginCollect>(`/warehouseApUser/phoneSave`, param)
+        .then(res => {
+          userInfo.setToken(res[AppStorageKeyCollect.TOKEN])
+          YTUserRequest.refreshUserInfo(() => {
+            IBestToast.show({ message: '注册成功' })
+            yTRouter.routerBack()
+          })
+        })
+    } else {
+      IBestToast.show({ message: "请求异常,请重新发送验证码", type: "fail" })
+    }
+  }
+
+  //密码登录
+  static passwordLogin(param: LoginCollect, result?: ResultCallBack<UserInfo>) {
+    YTUserRequest.post<ReqString, LoginCollect>(`/warehouseApUser/passwordLogin`, param)
+      .then(res => {
+        userInfo.setToken(res[AppStorageKeyCollect.TOKEN])
+        YTUserRequest.refreshUserInfo((res) => {
+          IBestToast.show({ message: '登录成功' })
+          yTRouter.routerBack()
+          result?.(res)
+        })
+      })
+  }
+
+  //重置密码
+  static resetPassword(param: LoginCollect, result?: ResultCallBack<undefined>) {
+    YTUserRequest.post<ReqString, LoginCollect>(`/warehouseApUser/resetPwd`, param)
+      .then(() => {
+        result?.()
+      })
+  }
+
+  //华为登录
+  static harmonyLogin(instance: LoginCollect) {
+    try {
+      IBestToast.showLoading()
+      HuaweiAuthPlugin.requestAuth()
+        .then(code => {
+          instance.setCode(code!)
+          YTUserRequest.post<ReqString, LoginCollect>(`/warehouseApUser/hmLogin`,
+            instance)
+            .then(data => {
+              const token = data['token']
+              userInfo.setToken(token)
+              YTUserRequest.refreshUserInfo((userInfo) => {
+                YTLog.info(userInfo)
+                IBestToast.hide()
+                setTimeout(() => {
+                  IBestToast.show({ message: '登录成功' })
+                }, 100)
+                yTRouter.routerBack()
+              })
+            })
+            .catch((err: Error) => {
+              IBestToast.hide()
+              YTLog.error(err)
+            })
+        })
+        .catch((e: Error) => {
+          YTLog.error(e)
+          IBestToast.hide()
+        })
+    } catch (e) {
+      YTLog.error(e)
+      IBestToast.hide()
+    }
+  }
+
+  //刷新用户信息
+  static refreshUserInfo(result?: ResultCallBack<UserInfo>) {
+    YTUserRequest.post<UserInfo, null>(`/warehouseApUser/info`)
+      .then(res => {
+        userInfo.setUserInfoAndLogin(res)
+        YTLog.info(userInfo)
+        result?.(res)
+      })
+      .catch((err: Error) => {
+        result?.(undefined, err)
+      })
+  }
+
+  //上传文件
+  static uploadFile(context: Context, fullpath: string, success: (url: string) => void) {
+    const formData = new FormData()
+    formData.append('file', fullpath)
+    YTUserRequest.upPost<ReqString, FormData>('/common/upload', formData, {
+      headers: { 'Content-Type': 'multipart/form-data' },
+      context,
+      onUploadProgress: (progressEvent: AxiosProgressEvent): void => {
+        YTLog.info(progressEvent && progressEvent.loaded && progressEvent.total ?
+          Math.ceil(progressEvent.loaded / progressEvent.total * 100) + '%' : '0%', 'uploadFile');
+      }
+    })
+      .then(res => {
+        const url = res['url']
+        success(url)
+      })
+  }
+
+  // 修改用户头像
+  static uploadHeadImg(context: Context, fullpath: string, success: () => void) {
+    const formData = new FormData()
+    formData.append('file', fullpath)
+
+    YTUserRequest.upPost<ReqString, FormData>('/common/upload', formData, {
+      headers: { 'Content-Type': 'multipart/form-data' },
+      context,
+      onUploadProgress: (progressEvent: AxiosProgressEvent): void => {
+        YTLog.info(progressEvent && progressEvent.loaded && progressEvent.total ?
+          Math.ceil(progressEvent.loaded / progressEvent.total * 100) + '%' : '0%', 'uploadFile');
+      }
+    })
+      .then(res => {
+        const url = res['url']
+        YTUserRequest.post<null, ReqString>(`/warehouseApUser/modifyMemberIcon`,
+          { 'memberIcon': url })
+          .then(() => {
+            success()
+          })
+          .catch((e: Error) => {
+            YTLog.error(e)
+            IBestToast.show({ message: '头像上传失败', type: 'fail' })
+          })
+      })
+      .catch((e: Error) => {
+        YTLog.error(e)
+      })
+  }
+
+  // 修改用户昵称
+  static changeNickname(name: string, success: () => void) {
+    YTUserRequest.post<null, ReqString>(`/warehouseApUser/modifyMemberName`,
+      { 'memberName': name })
+      .then(() => {
+        YTUserRequest.refreshUserInfo(() => {
+          success()
+        })
+      })
+  }
+
+  //问题反馈
+  static questionBack(des: string, createBy: string) {
+    YTUserRequest.post<null, ReqString>(`/warehouseBack/saveQuestion`, {
+      'backQuestion': des,
+      'createBy': createBy,
+      'createTime': new YTDate().formatDate(),
+    })
+      .then(() => {
+        IBestToast.show("反馈成功")
+        yTRouter.routerBack()
+      })
+      .catch((e: Error) => {
+        YTLog.error(e)
+      })
+  }
+}

+ 3 - 3
commons/basic/src/main/ets/components/ShowBannerAd.ets → commons/basic/src/main/ets/components/adComp/ShowBannerAd.ets

@@ -1,12 +1,12 @@
 import { advertising, AutoAdComponent } from '@kit.AdsKit';
-import { BannerAd } from '../ads/BannerAd';
+import { BannerAd } from '../../ads/BannerAd';
 import { hilog } from '@kit.PerformanceAnalysisKit';
-import { AdStatus } from '../constants';
+import { AdStatus } from '../../constants';
 
 @Component
 export struct ShowBannerAd {
-  private bannerAd = new BannerAd()
   @State visibilityState: Visibility = Visibility.Hidden;
+  private bannerAd = new BannerAd()
 
   build() {
     Column() {

+ 2 - 2
commons/basic/src/main/ets/components/ShowJHRewardAd.ets → commons/basic/src/main/ets/components/adComp/ShowJHRewardAd.ets

@@ -1,12 +1,12 @@
 import { common } from '@kit.AbilityKit';
-import { RewardAd } from '../ads/RewardAd';
+import { RewardAd } from '../../ads/RewardAd';
 import { emitter } from '@kit.BasicServicesKit';
 
 
 @Component
 export struct ShowJHRewardAd {
-  private context: common.UIAbilityContext = getContext(this) as common.UIAbilityContext;
   @BuilderParam showAdStruct: () => void
+  private context: common.UIAbilityContext = getContext(this) as common.UIAbilityContext;
 
   aboutToAppear(): void {
     emitter.on('showJHAd', () => {

+ 21 - 20
commons/basic/src/main/ets/components/AgreePrivacy.ets → commons/basic/src/main/ets/components/generalComp/AgreePrivacy.ets

@@ -1,11 +1,9 @@
-import { IBestToast } from '../../../../Index';
-import { BasicType, ReqString } from '../models';
-import { YTRequest } from '../utils/YTRequest';
-import { YTToast } from '../utils/YTToast';
+import { BasicType } from '../../models';
+import { YTToast } from '../../utils/YTToast';
 import { YTButton } from './YTButton';
 
 @Builder
-export function AgreePrivacy(item: BasicType<undefined>) {
+export function agreePrivacy(item: BasicType<undefined>) {
   Column() {
     Text('温馨提示')
       .fontSize(14)
@@ -23,21 +21,24 @@ export function AgreePrivacy(item: BasicType<undefined>) {
         btHeight: 37,
         click: () => {
           YTToast.getInstance().hide()
-          const loginData: ReqString = AppStorage.get<ReqString>('captchaLogin')!
-
-          if (item.text == '验证码登录') {
-            if (!loginData.phonenumber || !loginData.captcha) {
-              IBestToast.show({
-                message: "请输入手机号或验证码"
-              })
-              return
-            }
-
-            YTRequest.phonenumberLogin(AppStorage.get<ReqString>('captchaLogin')!)
-          }
-          if (item.text == '华为登录') {
-            YTRequest.huaweiLogin()
-          }
+
+
+          // if (item.text == '验证码登录') {
+          //   if (!loginData.phonenumber || !loginData.captcha) {
+          //     IBestToast.show({
+          //       message: "请输入手机号或验证码"
+          //     })
+          //     return
+          //   }
+          //
+          //   // YTRequest.phonenumberLogin(AppStorage.get<ReqString>('captchaLogin')!)
+          // }
+          // if (item.text == '华为登录') {
+          //   // YTRequest.huaweiLogin()
+          // }
+          item.loginType!.isAgreePrivacy = true
+
+          item.loginType?.executeLogin()
 
 
         }

+ 2 - 2
commons/basic/src/main/ets/components/ChatList.ets → commons/basic/src/main/ets/components/generalComp/ChatList.ets

@@ -1,5 +1,5 @@
-import { BasicType, BreakPointString, MessageType, Role } from '../models'
-import { BreakPointType, YTBreakPoint } from '../utils/YTBreakPoint'
+import { BasicType, BreakPointString, MessageType, Role } from '../../models'
+import { BreakPointType, YTBreakPoint } from '../../utils/YTBreakPoint'
 
 @Component
 export struct ChatList {

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

@@ -1,4 +1,4 @@
-import { BasicType } from '../models'
+import { BasicType } from '../../models'
 
 @Builder
 export function reviseImgHeaderBuilder(items: BasicType<undefined>[]) {

+ 0 - 0
commons/basic/src/main/ets/components/YTButton.ets → commons/basic/src/main/ets/components/generalComp/YTButton.ets


+ 13 - 12
commons/basic/src/main/ets/components/YTHeader.ets → commons/basic/src/main/ets/components/generalComp/YTHeader.ets

@@ -1,17 +1,17 @@
-import { YTAvoid } from '../../../../Index'
-import { YTRouter } from '../utils/YTRouter'
+import { YTAvoid } from '../../utils/YTAvoid'
+import { yTRouter } from '../../utils/YTRouter'
 
 @Component
 export struct YTHeader {
   @BuilderParam leftComp?: () => void
-  @BuilderParam RightComp?: () => void
-  @BuilderParam CenterComp?: () => void
+  @BuilderParam rightComp?: () => void
+  @BuilderParam centerComp?: () => void
   @StorageProp(YTAvoid.SAFE_TOP_KEY) safeTop: number = 0
   backArrow: boolean = true
   title: string = ''
   bgc: ResourceColor = Color.White
   click = () => {
-    YTRouter.routerBack()
+    yTRouter.routerBack()
   }
 
   build() {
@@ -27,19 +27,19 @@ export struct YTHeader {
           this.leftComp()
         }
 
-        if (this.RightComp) {
-          this.RightComp()
+        if (this.rightComp) {
+          this.rightComp()
         }
       }
       .width('100%')
-      .justifyContent(this.RightComp ? FlexAlign.SpaceBetween : FlexAlign.Start)
+      .justifyContent(this.rightComp ? FlexAlign.SpaceBetween : FlexAlign.Start)
+
 
-      if (this.CenterComp || this.title)
       Row() {
-        if (this.CenterComp) {
-          this.CenterComp()
+        if (this.centerComp) {
+          this.centerComp()
         }
-        if (this.title && !this.CenterComp) {
+        if (this.title && !this.centerComp) {
           Text(this.title)
             .fontSize(18)
             .fontWeight(700)
@@ -53,5 +53,6 @@ export struct YTHeader {
     .height(44 + this.safeTop)
     .padding({ top: this.safeTop })
     .backgroundColor(this.bgc)
+
   }
 }

+ 0 - 0
commons/basic/src/main/ets/components/YTSearch.ets → commons/basic/src/main/ets/components/generalComp/YTSearch.ets


+ 0 - 0
commons/basic/src/main/ets/components/YTTiltleBar.ets → commons/basic/src/main/ets/components/generalComp/YTTiltleBar.ets


+ 3 - 3
commons/basic/src/main/ets/components/YtDoubleConfirm.ets → commons/basic/src/main/ets/components/generalComp/YtDoubleConfirm.ets

@@ -1,5 +1,5 @@
-import { YTButton, YTToast } from '../../../../Index';
-import { BasicType } from '../models';
+import { YTButton, yTToast, } from '../../../../../Index';
+import { BasicType } from '../../models';
 
 @Builder
 export function yTDoubleConfirm(item: BasicType<undefined>) {
@@ -33,7 +33,7 @@ export function yTDoubleConfirm(item: BasicType<undefined>) {
           btFontSize: 12,
           bgc: Color.White,
           click: () => {
-            YTToast.getInstance().hide()
+            yTToast.hide()
           }
         }
       )

+ 352 - 0
commons/basic/src/main/ets/models/LoginCollect.ets

@@ -0,0 +1,352 @@
+import { YTLog } from '../../../../Index';
+import { IBestToast } from '@ibestservices/ibest-ui';
+import { YTToast } from '../utils/YTToast';
+import { AppStorageKeyCollect } from '../constants';
+import { YTUserRequest } from '../apis/YTUserRequest';
+
+export class LoginCollect {
+  phonenumber?: string; // 用户输入的手机号
+  password?: string; // 密码(密码登录/注册/重置时使用)
+  smsCode?: string; // 验证码(验证码登录/注册/重置时使用)
+  confirmPassword?: string; // 确认密码(注册/重置时使用)
+  isAgreePrivacy: boolean = false; // 是否同意隐私政策
+  private code?: string //华为登录code
+  private operation: 'register' | 'reset' | 'login'; // 当前操作类型:注册/重置/登录
+  private uuid?: string //验证码登录防伪标识
+  private isRequesting: boolean = false //是否已经发送一个请求了
+  private loginMethod: 'harmony' | 'common' = 'common'
+  private countDown: number = 0
+
+  constructor(registerOrReset: 'register' | 'reset' | 'login') {
+    this.operation = registerOrReset
+    const storageUUID = AppStorage.get<string>(AppStorageKeyCollect.UUID)
+    if (storageUUID) {
+      this.uuid = storageUUID
+    }
+  }
+
+  /**
+   * 执行登录/注册/重置操作,根据当前场景校验必要字段并处理逻辑
+   * @param harmony表示华为登录,common表示其它普通登录
+   */
+  executeLogin(loginMethod: 'harmony' | 'common' = this.loginMethod) {
+    if (loginMethod == undefined) {
+      throw Error("请传入登录方法")
+    }
+    //记录弹出隐私政策时的登录方法
+    this.loginMethod = loginMethod
+    // 基础校验:必须同意隐私政策
+    if (!this.isAgreePrivacy) {
+      YTToast.getInstance().agreePrivacy({ loginType: this })
+      return
+    }
+    //已有请求则拦截多于请求
+    if (this.isRequesting) {
+      return
+    }
+    if (loginMethod == 'harmony') {
+      YTUserRequest.harmonyLogin(this)
+      return
+    }
+
+    // 根据当前操作类型分支处理
+    switch (this.operation) {
+      case 'register':
+        this.handleRegister(); // 处理注册逻辑
+        break
+      case 'reset':
+        this.handleResetPassword(); // 处理重置密码逻辑
+        break
+      case 'login':
+        this.handleLogin(); // 默认处理登录逻辑(密码/验证码登录)
+        break
+    }
+  }
+
+
+  //将所有属性重置为初始态
+  clearAll() {
+    this.code = undefined
+    this.phonenumber = undefined
+    this.password = undefined
+    this.smsCode = undefined
+    this.confirmPassword = undefined
+    this.isAgreePrivacy = false
+    this.uuid = undefined
+    this.isRequesting = false
+  }
+
+
+  //如获取验证码或华为登录后,后端返回的字段使用此方法接收
+  updateUsefulProperty(instance: LoginCollect) {
+    //判断不为空再赋值
+    if (instance.code) {
+      this.code = instance.code
+    }
+    if (instance.phonenumber) {
+      this.phonenumber = instance.phonenumber
+    }
+    if (instance.password) {
+      this.password = instance.password
+    }
+    if (instance.operation) {
+      this.operation = instance.operation
+    }
+    if (instance.smsCode) {
+      this.smsCode = instance.smsCode
+    }
+    if (instance.confirmPassword) {
+      this.confirmPassword = instance.confirmPassword
+    }
+    if (instance.isAgreePrivacy) {
+      this.isAgreePrivacy = instance.isAgreePrivacy
+    }
+    if (instance.uuid) {
+      this.uuid = instance.uuid
+    }
+
+    return this
+
+  }
+
+  //发送验证码
+  requestSmsCode(success: (res: LoginCollect) => void) {
+    if (this.phonenumber?.match(new RegExp('^1(3[0-9]|4[01456879]|5[0-35-9]|6[2567]|7[0-8]|8[0-9]|9[0-35-9])\\d{8}$'))) {
+
+      YTUserRequest.getLoginCaptcha(this.phonenumber, (res, err) => {
+        if (!err && !res) {
+          IBestToast.show({ message: '请勿重复发送验证码' })
+          return
+        } else if (res) {
+          //防止退出登录页导致uuid直接失效
+          AppStorage.setOrCreate<string>(AppStorageKeyCollect.UUID, this.uuid)
+          IBestToast.show({ message: '验证码发送成功' })
+          this.updateUsefulProperty(res)
+          success(this)
+        } else {
+          YTLog.error(err)
+        }
+      })
+
+
+    } else {
+      IBestToast.show({ message: '请输入正确的手机号' })
+    }
+  }
+
+  getCode(): string | undefined {
+    return this.code
+  }
+
+  setCode(code: string) {
+    this.code = code
+    return this
+  }
+
+
+  getPhonenumber(): string | undefined {
+    return this.phonenumber
+  }
+
+  setPhonenumber(phonenumber: string) {
+    this.phonenumber = phonenumber
+    return this
+  }
+
+  getPassword(): string | undefined {
+    return this.password
+  }
+
+  setPassword(password: string) {
+    this.password = password
+    return this
+  }
+
+  getOperation(): 'register' | 'reset' | 'login' {
+    return this.operation
+  }
+
+  setOperation(registerOrReset: 'register' | 'reset' | 'login') {
+    this.operation = registerOrReset
+    return this
+  }
+
+  getSmsCode(): string | undefined {
+    return this.smsCode
+  }
+
+  setSmsCode(smsCode: string) {
+    this.smsCode = smsCode
+    return this
+  }
+
+  getConfirmPassword(): string | undefined {
+    return this.confirmPassword
+  }
+
+  setConfirmPassword(confirmPassword: string) {
+    this.confirmPassword = confirmPassword
+    return this
+  }
+
+  getIsAgreePrivacy(): boolean {
+    return this.isAgreePrivacy
+  }
+
+  setIsAgreePrivacy(isAgreePrivacy: boolean) {
+    this.isAgreePrivacy = isAgreePrivacy
+    return this
+  }
+
+  getUuid(): string | undefined {
+    return this.uuid
+  }
+
+  setUuid(uuid: string) {
+    this.uuid = uuid
+    return this
+  }
+
+  getCountDown() {
+    return this.countDown
+  }
+
+  /**
+   * 处理登录逻辑(支持密码登录或验证码登录)
+   */
+  private handleLogin() {
+    // 核心校验:手机号必填
+    if (!this.phonenumber) {
+
+      IBestToast.show({ message: '登录失败:请输入手机号码', type: "warning" })
+      return
+    }
+
+    // 场景分支:密码登录 或 验证码登录
+    if (this.password) {
+      // 密码登录:校验密码非空
+      if (!this.password.trim()) {
+
+        IBestToast.show({ message: '登录失败:请输入密码', type: "warning" })
+        return
+      }
+      // 调用密码登录接口
+      YTUserRequest.passwordLogin(this)
+      return
+    } else if (this.smsCode) {
+      // 验证码登录:校验验证码非空
+      if (!this.smsCode.trim()) {
+
+        IBestToast.show({ message: '登录失败:请输入验证码', type: "warning" })
+        return
+      }
+      // 验证码登录逻辑
+      YTUserRequest.phonenumberLogin(this)
+      return
+    } else {
+      // 无密码/验证码时提示
+
+      IBestToast.show({ message: '登录失败:请输入密码或验证码', type: "warning" })
+      return
+    }
+  }
+
+  /**
+   * 处理注册逻辑(手机号+验证码+密码+确认密码)
+   */
+  private handleRegister() {
+    // 核心校验:手机号必填
+    if (!this.phonenumber) {
+
+      IBestToast.show({ message: '注册失败:请输入手机号码', type: "warning" })
+      return
+    }
+
+    // 场景分支:注册需要验证码
+    if (!this.smsCode?.trim()) {
+
+      IBestToast.show({ message: '注册失败:请输入验证码', type: "warning" })
+      return
+    }
+
+    // 密码相关校验
+    if (!this.password?.trim()) {
+
+      IBestToast.show({ message: '注册失败:请设置密码', type: "warning" })
+      return
+    }
+    if (!this.confirmPassword?.trim()) {
+
+      IBestToast.show({ message: '注册失败:请确认密码', type: "warning" })
+      return
+    }
+    if (!this.validatePassword(this.password)) {
+      IBestToast.show({ message: '注册失败:密码必须包含字母、数字和特殊符号,并且长度在8到20位之间', type: "warning" })
+      return
+    }
+    if (this.password !== this.confirmPassword) {
+
+      IBestToast.show({ message: '注册失败:两次输入的密码不一致', type: "warning" })
+      return
+    }
+
+    // 实际场景可调用注册接口(示例)
+    YTUserRequest.register(this)
+    return
+  }
+
+  /**
+   * 处理重置密码逻辑(手机号+验证码+新密码+确认密码)
+   */
+  private handleResetPassword() {
+    // 核心校验:手机号必填
+    if (!this.phonenumber) {
+
+      IBestToast.show({ message: '重置密码失败:请输入手机号码', type: "warning" })
+      return
+    }
+
+    // 场景分支:重置需要验证码
+    if (!this.smsCode?.trim()) {
+
+      IBestToast.show({ message: '重置密码失败:请输入验证码', type: "warning" })
+      return
+    }
+
+    // 新密码相关校验
+    if (!this.password?.trim()) {
+
+      IBestToast.show({ message: '重置密码失败:请设置新密码', type: "warning" })
+      return
+    }
+    if (!this.confirmPassword?.trim()) {
+
+      IBestToast.show({ message: '重置密码失败:请确认新密码', type: "warning" })
+      return
+    }
+    if (this.password !== this.confirmPassword) {
+
+      IBestToast.show({ message: '重置密码失败:两次输入的新密码不一致', type: "warning" })
+      return
+    }
+
+    // 实际场景可调用重置密码接口
+    YTUserRequest.resetPassword(this, () => {
+      this.handleLogin()
+    })
+    return
+  }
+
+  // 密码校验函数
+  private validatePassword(password: string): boolean {
+    // 正则表达式说明:
+    // ^ 表示字符串开始
+    // (?=.*[A-Za-z]) 至少包含一个字母(大小写均可)
+    // (?=.*\d)        至少包含一个数字
+    // (?=.*[^A-Za-z0-9]) 至少包含一个非字母数字的特殊符号(如@#$%^&*等)
+    // .{8,20}        长度限制 8-20 位
+    // $ 表示字符串结束
+    const passwordRegex = /^(?=.*[A-Za-z])(?=.*\d)(?=.*[^A-Za-z0-9]).{8,20}$/;
+    return passwordRegex.test(password);
+  }
+}

+ 3 - 0
commons/basic/src/main/ets/models/index.ets

@@ -1,3 +1,5 @@
+import { LoginCollect } from './LoginCollect'
+
 export interface BasicType<T> {
   src?: ResourceStr,
   acSrc?: ResourceStr,
@@ -9,6 +11,7 @@ export interface BasicType<T> {
   generics?: T,
   date?: string,
   index?: number,
+  loginType?: LoginCollect
   finally?: () => void
 }
 

+ 10 - 9
commons/basic/src/main/ets/utils/FormatDate.ets

@@ -1,10 +1,11 @@
-export function formatDate(date: Date): string {
-  const year = date.getFullYear();
-  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');
-
-  return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
+export class YTDate extends Date {
+  formatDate(separator: string = '-', date: Date = this): string {
+    const year = date.getFullYear();
+    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');
+    return `${year + separator + month + separator + day} ${hours}:${minutes}:${seconds}`;
+  }
 }

+ 6 - 8
commons/basic/src/main/ets/utils/YTRequest.ets

@@ -7,13 +7,11 @@ import axios, {
   FormData,
   InternalAxiosRequestConfig
 } from '@ohos/axios';
-import { IBestToast, YTLog } from '../../../../Index';
+import { IBestToast, YTDate, YTLog, yTRouter } from '../../../../Index';
 import { AppStorageKeyCollect } from '../constants';
 import { ReqString } from '../models';
 import { userInfo, UserInfo } from '../models/UserInfo';
-import { formatDate } from './FormatDate';
 import { HuaweiAuthPlugin } from './HuaWeiAuthPlugin';
-import { YTRouter } from './YTRouter';
 
 
 export const baseURL: string = 'https://hm-test.ytpm.net/prod-api'
@@ -45,7 +43,7 @@ instance.interceptors.response.use((response: AxiosResponse) => {
   // 对响应错误做点什么
   if (response.data.code == 401) {
     userInfo.logout()
-    YTRouter.router2LoginPage()
+    yTRouter.router2LoginPage()
     return Promise.reject('401');
   }
 
@@ -103,7 +101,7 @@ export class YTRequest {
           userInfo.setToken(res[AppStorageKeyCollect.TOKEN])
           YTRequest.refreshUserInfo(() => {
             IBestToast.show({ message: '登录成功' })
-            YTRouter.routerBack()
+            yTRouter.routerBack()
           })
         })
     }
@@ -126,7 +124,7 @@ export class YTRequest {
                 setTimeout(() => {
                   IBestToast.show({ message: '登录成功' })
                 }, 100)
-                YTRouter.routerBack()
+                yTRouter.routerBack()
               })
             })
             .catch((err: Error) => {
@@ -219,11 +217,11 @@ export class YTRequest {
     YTRequest.post<null, ReqString>(`/api/${YTRequest.productName}/question/saveQuestion`, {
       'backQuestion': des,
       'createBy': createBy,
-      'createTime': formatDate(new Date()),
+      'createTime': new YTDate().formatDate(),
     })
       .then(() => {
         IBestToast.show("反馈成功")
-        YTRouter.routerBack()
+        yTRouter.routerBack()
       })
       .catch((e: Error) => {
         YTLog.error(e)

+ 24 - 22
commons/basic/src/main/ets/utils/YTRouter.ets

@@ -14,53 +14,55 @@ export class YTRouter extends NavPathStack {
     return YTRouter.instance
   }
 
-  static router2SettingPage() {
-    YTRouter.getInstance().pushPathByName('SettingPage', '')
+  router2SettingPage() {
+    yTRouter.pushPathByName('SettingPage', '')
   }
 
-  static router2SuggestionPage() {
-    YTRouter.getInstance().pushPathByName('SuggestionPage', '')
+  router2SuggestionPage() {
+    yTRouter.pushPathByName('SuggestionPage', '')
   }
 
-  static router2AgreementPage(param: '关于我们' | '隐私政策' | '用户协议') {
-    YTRouter.getInstance().pushPathByName('AgreementPage', param)
+  router2AgreementPage(param: '关于我们' | '隐私政策' | '用户协议') {
+    yTRouter.pushPathByName('AgreementPage', param)
   }
 
   /**
    * 跳转至用户协议
    */
-  static router2userAgreement() {
-    YTRouter.getInstance().pushPathByName('UserAgreementPage', '')
+  router2userAgreement() {
+    yTRouter.pushPathByName('UserAgreementPage', '')
   }
 
   /**
    * 跳转至隐私政策
    */
-  static router2Privacy() {
-    YTRouter.getInstance().pushPathByName('Privacy', '')
+  router2Privacy() {
+    yTRouter.pushPathByName('Privacy', '')
   }
 
-  static router2AboutUS() {
-    YTRouter.getInstance().pushPathByName('AboutUS', '')
+  router2AboutUS() {
+    yTRouter.pushPathByName('AboutUS', '')
   }
 
-  static getAgreementPageParam() {
-    return YTRouter.getInstance().getParamByName('AgreementPage').pop() as '关于我们' | '隐私政策' | '用户协议'
+  getAgreementPageParam() {
+    return yTRouter.getParamByName('AgreementPage').pop() as '关于我们' | '隐私政策' | '用户协议'
   }
 
-  static router2LoginPage() {
-    YTRouter.getInstance().pushPathByName('LoginPage', '')
+  router2LoginPage() {
+    yTRouter.pushPathByName('LoginPage', '')
   }
 
-  static router2DelPhotoPage(param: DelPhotoParam) {
-    YTRouter.getInstance().pushPathByName('DelPhotoPage', param)
+  router2DelPhotoPage(param: DelPhotoParam) {
+    yTRouter.pushPathByName('DelPhotoPage', param)
   }
 
-  static getDelPhotoParam() {
-    return YTRouter.getInstance().getParamByName('DelPhotoPage').pop() as DelPhotoParam
+  getDelPhotoParam() {
+    return yTRouter.getParamByName('DelPhotoPage').pop() as DelPhotoParam
   }
 
-  static routerBack() {
-    YTRouter.getInstance().pop()
+  routerBack() {
+    yTRouter.pop()
   }
 }
+
+export const yTRouter = YTRouter.getInstance()

+ 10 - 5
commons/basic/src/main/ets/utils/YTToast.ets

@@ -2,15 +2,16 @@ import { BusinessError } from '@kit.BasicServicesKit';
 import { ComponentContent, promptAction } from '@kit.ArkUI';
 import { UIContext } from '@ohos.arkui.UIContext';
 import { BasicType, YTLog } from '../../../../Index';
-import { yTDoubleConfirm } from '../components/YtDoubleConfirm';
-import { AgreePrivacy } from '../components/AgreePrivacy';
-
+import { yTDoubleConfirm } from '../components/generalComp/YtDoubleConfirm';
+import { agreePrivacy } from '../components/generalComp/AgreePrivacy';
+import { LoginCollect } from '../models/LoginCollect';
 
 interface InitOption {
   context: UIContext;
   options: promptAction.BaseDialogOptions;
 }
 
+
 class Params<T> implements BasicType<T> {
   src?: ResourceStr
   acSrc?: ResourceStr
@@ -18,9 +19,10 @@ class Params<T> implements BasicType<T> {
   index?: number
   number?: number | undefined
   message?: string
+  loginType?: LoginCollect
   click?: () => void
 
-  constructor(item: BasicType<undefined>) {
+  constructor(item: BasicType<undefined> = {}) {
     this.src = item.src;
     this.text = item.text;
     this.index = item.index;
@@ -28,6 +30,7 @@ class Params<T> implements BasicType<T> {
     this.click = item.click;
     this.message = item.message;
     this.acSrc = item.acSrc;
+    this.loginType = item.loginType;
   }
 }
 
@@ -85,7 +88,7 @@ export class YTToast {
   }
 
   agreePrivacy(item: BasicType<undefined>) {
-    this.openToast(wrapBuilder(AgreePrivacy), item)
+    this.openToast(wrapBuilder(agreePrivacy), item)
   }
 
 
@@ -125,3 +128,5 @@ export class YTToast {
   }
 }
 
+export const yTToast = YTToast.getInstance()
+

+ 44 - 56
features/user/src/main/ets/components/LoginInput.ets

@@ -1,95 +1,83 @@
-import { IBestToast, YTRequest } from 'basic'
+import { LoginCollect } from 'basic/src/main/ets/models/LoginCollect'
 import { CodeInputType } from '../models'
 
 @Component
 export struct LoginInput {
   item?: CodeInputType
-  mgBottom: number = 24
-  @Link inputData: string
-  @Prop phoneNumber: string
   code: string = ''
-  @State time: number = 61
+  @Prop inputData: string = ''
+  marginBottom: number = 8
   needCode: boolean = true
-  private declare sa: number
+  declare loginCollect: LoginCollect
+  @Prop isPassword: boolean = false
+  @Prop isAgree: boolean = false
+  @Require inputChange: (_: string) => void
+  @State private time: number = 61
+  private declare setIntervalId: number
+  click: () => void = () => {
+  }
 
   aboutToDisappear(): void {
-    clearInterval(this.sa)
+    clearInterval(this.setIntervalId)
   }
 
   build() {
     Row({ space: 8 }) {
       Text(this.item?.txt)
-        .width(73)
-        .height(31)
-        .fontSize(12)
-        .border({ width: { bottom: 1 }, color: $r('[basic].color.main_na_color') })
-        .textAlign(TextAlign.Start)
-        .fontColor(Color.Black)
-      TextInput({ placeholder: this.item?.placeHolder, text: $$this.inputData })
+        .fontColor('#FF141111')
+        .fontSize(16)
+        .width(71)
+        .textAlign(TextAlign.Center)
+        .border({ width: { right: 1 }, color: '#FFB2B2B2' })
+      TextInput({ text: this.inputData, placeholder: this.item?.placeHolder })
         .layoutWeight(1)
-        .type(InputType.PhoneNumber)
+        .type(this.isPassword ? InputType.Password : InputType.PhoneNumber)
         .borderRadius(0)
-        .border({ width: { bottom: 1 }, color: $r('[basic].color.main_na_color') })
         .textAlign(TextAlign.Start)
         .height(31)
-        .placeholderFont({ size: 12 })
+        .placeholderFont({ size: 16 })
         .placeholderColor($r('[basic].color.main_na_color'))
         .backgroundColor(Color.Transparent)
         .padding(0)
         .caretColor($r('[basic].color.main_ac_color_dark'))
+        .onChange(this.inputChange)
+
       if (this.needCode) {
         Text(this.time == 61 ? '获取验证码' : this.time + '后重新发送')
-          .position({ right: 0 })
-          .height(31)
+          .height(30)
           .fontSize(12)
-          .fontColor($r('[basic].color.main_ac_color_dark'))
+          .fontColor(Color.White)
+          .borderRadius(16)
+          .backgroundColor($r('[basic].color.main_ac_color_dark'))
           .onClick(() => {
-            const rep = new RegExp('^1(3[0-9]|4[01456879]|5[0-35-9]|6[2567]|7[0-8]|8[0-9]|9[0-35-9])\\d{8}$');
-            if (this.phoneNumber.match(rep) && this.time == 61) {
+            this.loginCollect.requestSmsCode((res) => {
+              if (res.smsCode) {
+                this.inputData = res.smsCode
+              }
               this.time = 60
-              this.sa = setInterval(() => {
+              this.setIntervalId = setInterval(() => {
                 this.time--
                 if (this.time < 1) {
                   this.time = 61
-                  clearInterval(this.sa)
+                  clearInterval(this.setIntervalId)
                 }
               }, 1000)
-              // TODO  此处放置验证码获取逻辑
-              YTRequest.getCaptcha(this.phoneNumber, (res) => {
-                if (!res) {
-                  IBestToast.show({ message: '请勿重复发送验证码' })
-                  return
-                }
-
-                AppStorage.setOrCreate<string>('uuid', res)
-              }, (err) => {
-                IBestToast.show({ message: '验证码发送失败' })
-                this.time = 61
-              })
-              // YTRequest.post<CodeType, AskCodeNum>('/api/friendcase/member/sendSmsCode',
-              //   { phonenumber: this.phoneNumber })
-              //   .then(res => {
-              //     if (!res) {
-              //       IBestToast.show({ type: 'warning', message: '请勿重复发送验证码' })
-              //       return
-              //     }
-              //
-              //     AppStorage.setOrCreate<CodeType>('smsCode', res)
-              //   })
-              //   .catch((err: Error) => {
-              //     IBestToast.show({ type: 'fail', message: '验证码发送失败' })
-              //     this.time = 61
-              //   })
-            } else {
-              if (!this.phoneNumber.match(rep)) {
-                IBestToast.show({ message: '请输入正确的手机号' })
-              }
-            }
+            })
           })
           .enabled(this.time == 61)
+          .padding({
+            left: 12,
+            right: 12,
+            top: 6,
+            bottom: 6
+          })
+
       }
 
     }
-    .margin({ bottom: this.mgBottom })
+    .border({ width: { bottom: 1 }, color: '#f7f9fa' })
+    .height(56)
+    .width('100%')
+    .margin({ bottom: this.marginBottom })
   }
 }

+ 10 - 4
features/user/src/main/ets/components/OtherLoginMethods.ets

@@ -9,15 +9,21 @@ export struct OtherLoginMethods {
     Column() {
       Text('其他登入方式')
         .fontSize($r('[basic].float.page_text_font_size_10'))
-        .margin({ bottom: 24 })
-      Column({ space: 16 }) {
+        .margin({ bottom: 16 })
+      Row({ space: 16 }) {
         ForEach(this.loginMethodArr, (item: BasicType<undefined>) => {
-          LoginMethod(item)
+          // LoginMethod(item)
+          Image(item.src)
+            .width(40)
+            .aspectRatio(1)
+            .borderRadius(20)
+            .backgroundColor(Color.White)
+            .onClick(item.click)
         })
       }
 
     }
-    .alignItems(HorizontalAlign.Start)
+
   }
 }
 

+ 40 - 29
features/user/src/main/ets/components/Terms.ets

@@ -1,20 +1,30 @@
-import { YTRouter } from 'basic'
+import { yTRouter } from 'basic'
+
 
 @Extend(Span)
 function spanEx(click: () => void) {
-  .decoration({ type: TextDecorationType.Underline, color: $r('[basic].color.main_ac_color_dark') })
+  // .decoration({ type: TextDecorationType.Underline, color: $r('[basic].color.main_ac_color_dark') })
   .fontColor($r('[basic].color.main_ac_color_dark'))
   .onClick(click)
 }
 
 @Component
 export struct Terms {
-  @Link isAgree: boolean
+  @Prop isAgree: boolean
   mg: number = 39
+  @Require onAgreeChange: () => void
 
   build() {
     Column() {
       Row() {
+        Checkbox()
+          .width(12)
+          .aspectRatio(1)
+          .margin({ right: 5 })
+          .onChange(() => {
+            this.onAgreeChange()
+          })
+          .selectedColor($r('[basic].color.main_ac_color_dark'))
         Text() {
           Span('我已阅读并同意')
           // Span('《中国认证服务条款》')
@@ -23,43 +33,44 @@ export struct Terms {
           //   })
           //
           // Span('以及')
-          Span('"用户协议"')
+          Span('《小易决定用户协议》')
             .spanEx(() => {
-              YTRouter.router2userAgreement()
+              yTRouter.router2userAgreement()
 
             })
           Span('和')
-          Span('"隐私政策"')
+          Span('《隐私政策》')
             .spanEx(() => {
-              YTRouter.router2Privacy()
+              yTRouter.router2Privacy()
             })
           Span('。')
         }
-        .fontColor('#4D000000')
-        .fontSize($r('[basic].float.page_text_font_size_10'))
-        .margin({ bottom: this.mg })
+        .fontWeight(300)
+        .fontColor('#FF686868')
+        .fontSize(12)
+
       }
       .width('100%')
+      .alignItems(VerticalAlign.Center)
+      .margin({ bottom: this.mg })
 
-      Row() {
-        Text()
-          .height('100%')
-          .aspectRatio(1)
-          .backgroundColor(Color.White)
-          .borderRadius(18)
-      }
-      .padding(1)
-      .alignSelf(ItemAlign.End)
-      .width(39)
-      .aspectRatio(2)
-      .borderRadius(18)
-      .justifyContent(this.isAgree ? FlexAlign.End : FlexAlign.Start)
-      .backgroundColor(this.isAgree ? $r('[basic].color.main_ac_color_dark') : '#D9D9D9')
-      .onClick(() => {
-        animateTo({ duration: 200 }, () => {
-          this.isAgree = !this.isAgree
-        })
-      })
+      // Row() {
+      //   Text()
+      //     .height('100%')
+      //     .aspectRatio(1)
+      //     .backgroundColor(Color.White)
+      //     .borderRadius(18)
+      // }
+      // .padding(1)
+      // .alignSelf(ItemAlign.End)
+      // .width(39)
+      // .aspectRatio(2)
+      // .borderRadius(18)
+      // .justifyContent(this.isAgree ? FlexAlign.End : FlexAlign.Start)
+      // .backgroundColor(this.isAgree ? $r('[basic].color.main_ac_color_dark') : '#D9D9D9')
+      // .onClick(() => {
+      //   this.getUIContext().animateTo({ duration: 200 }, this.onAgreeChange)
+      // })
     }
 
   }

+ 3 - 3
features/user/src/main/ets/pages/AboutUS.ets

@@ -1,4 +1,4 @@
-import { YTAvoid, YTHeader, YTRouter } from 'basic';
+import { YTAvoid, YTHeader, yTRouter } from 'basic';
 import { bundleManager } from '@kit.AbilityKit';
 
 
@@ -50,10 +50,10 @@ export struct AboutUS {
               .onClick(() => {
                 switch (index) {
                   case 0:
-                    YTRouter.router2userAgreement()
+                    yTRouter.router2userAgreement()
                     break;
                   case 1:
-                    YTRouter.router2Privacy()
+                    yTRouter.router2Privacy()
                     break;
                 }
 

+ 11 - 11
features/user/src/main/ets/pages/DelPhotoPage.ets

@@ -1,4 +1,4 @@
-import { CropController, CropView, IBestToast, YTAvoid, YTLog, YTRequest, YTRouter } from 'basic'
+import { CropController, CropView, IBestToast, YTAvoid, YTLog, yTRouter, YTUserRequest } from 'basic'
 import { fileIo } from '@kit.CoreFileKit'
 import { util } from '@kit.ArkTS'
 import { emitter } from '@kit.BasicServicesKit'
@@ -24,8 +24,8 @@ struct DelPhotoPage {
   private declare context: Context
 
   aboutToAppear(): void {
-    this.selectPhoto = YTRouter.getDelPhotoParam().src
-    this.type = YTRouter.getDelPhotoParam().type
+    this.selectPhoto = yTRouter.getDelPhotoParam().src
+    this.type = yTRouter.getDelPhotoParam().type
     const tempContext = this.getUIContext().getHostContext()
     if (tempContext === undefined) {
       //抛出异常
@@ -34,11 +34,11 @@ struct DelPhotoPage {
       this.context = tempContext
     }
 
-    YTAvoid.setStatusBarContentColor('#FFFFFF', this.context)
+    YTAvoid.setStatusBarContentColor('#FFFFFFFF', this.context)
   }
 
   aboutToDisappear(): void {
-    YTAvoid.setStatusBarContentColor('#000000', this.context)
+    YTAvoid.setStatusBarContentColor('#FF000000', this.context)
   }
 
   build() {
@@ -177,7 +177,7 @@ struct DelPhotoPage {
           .width(36)
           .aspectRatio(1)
           .onClick(() => {
-            YTRouter.routerBack()
+            yTRouter.routerBack()
           })
 
         Image($r('app.media.make_sure'))
@@ -197,22 +197,22 @@ struct DelPhotoPage {
 
                   if (this.type == 'header') {
                     IBestToast.showLoading({ message: '上传中...' })
-                    YTRequest.uploadHeadImg(this.getUIContext().getHostContext()!, fullpath, () => {
-                      YTRequest.refreshUserInfo(() => {
+                    YTUserRequest.uploadHeadImg(this.getUIContext().getHostContext()!, fullpath, () => {
+                      YTUserRequest.refreshUserInfo(() => {
                         IBestToast.hide()
                         setTimeout(() => {
                           IBestToast.show({ message: '头像修改成功', type: 'success' })
                         }, 100)
                       })
                     })
-                    YTRouter.routerBack()
+                    yTRouter.routerBack()
                   }
                   if (this.type == 'image') {
                     IBestToast.showLoading({ message: '上传中...' })
-                    YTRequest.uploadFile(this.getUIContext().getHostContext()!, fullpath, (url) => {
+                    YTUserRequest.uploadFile(this.getUIContext().getHostContext()!, fullpath, (url) => {
                       emitter.emit('upLoadEnd', { data: url })
                       IBestToast.hide()
-                      YTRouter.routerBack()
+                      yTRouter.routerBack()
                     })
                   }
 

+ 106 - 109
features/user/src/main/ets/pages/LoginPage.ets

@@ -1,8 +1,9 @@
-import { BasicType, YTAvoid, YTButton, YTRequest, YTRouter, YTToast } from 'basic'
-import { CodeInputType } from '../models'
-import { LoginInput } from '../components/LoginInput'
-import { Terms } from '../components/Terms'
-import { OtherLoginMethods } from '../components/OtherLoginMethods'
+import { YTAvoid, yTRouter } from 'basic'
+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
@@ -15,40 +16,10 @@ function LoginBuilder() {
 
 @Component
 struct LoginPage {
-  @State isAgree: boolean = false
-  @StorageProp(YTAvoid.SAFE_TOP_KEY) safeTop: number = 0
-  @StorageProp(YTAvoid.SAFE_BOTTOM_KEY) safeBottom: number = 0
-  @State phoneNumber: string = ''
-  @State Captcha: string = ''
-  inputPhoneNumberType: CodeInputType = {
-    txt: '+86',
-    placeHolder: '请输入手机号'
-  }
-  inputCaptchaType: CodeInputType = {
-    txt: '验证码',
-    placeHolder: '请输入验证码'
-  }
-  loginMethodArr: BasicType<undefined>[] = [
-  // {
-  //   src: $r('app.media.wechat'),
-  //   txt: '微信登入',
-  //   click: () => {
-  //     //使用微信sdk实现微信登录
-  //
-  //   }
-  // },
-    {
-      // src: $r('app.media.hua_wei'),
-      text: '华为登录',
-      click: () => {
-        if (!this.isAgree) {
-          YTToast.getInstance().agreePrivacy({ text: '华为登录' })
-          return
-        }
-        YTRequest.huaweiLogin()
-      }
-    }
-  ]
+  @StorageProp(YTAvoid.SAFE_TOP_KEY) private safeTop: number = 0
+  @StorageProp(YTAvoid.SAFE_BOTTOM_KEY) private safeBottom: number = 0
+  @State private tabBarIndex: number = 0
+  private tabController: TabsController = new TabsController()
 
   aboutToAppear(): void {
 
@@ -56,82 +27,108 @@ struct LoginPage {
 
   build() {
     Column() {
-      Image($r('[basic].media.ic_back'))
-        .width(24)
-        .aspectRatio(1)
-        .margin({ bottom: 66 })
-        .onClick(() => {
-          YTRouter.routerBack()
-        })
-      Text('使用电话号码访问')
-        .fontSize($r('[basic].float.page_text_font_size_10'))
-        .margin({ bottom: 39 })
-        .fontColor(Color.Black)
-
-      LoginInput({ item: this.inputPhoneNumberType, inputData: this.phoneNumber, needCode: false })
-      LoginInput({ item: this.inputCaptchaType, inputData: this.Captcha, phoneNumber: this.phoneNumber })
-
-
-      Terms({ isAgree: this.isAgree, mg: 13 })
-        .margin({ bottom: 74 })
-
-      YTButton({
-        btContent: '登录', click: () => {
-          if (!this.isAgree) {
-            AppStorage.setOrCreate<Record<string, string>>('captchaLogin',
-              {
-                'phonenumber': this.phoneNumber,
-                'captcha': this.Captcha
-              })
-            YTToast.getInstance().agreePrivacy({ text: '验证码登录' })
-            return
-          }
-          YTRequest.phonenumberLogin({
-            'phonenumber': this.phoneNumber,
-            'captcha': this.Captcha
+      Column() {
+        Column() {
+          Text('跳过')
+            .fontSize(12)
+            .fontWeight(400)
+            .alignSelf(ItemAlign.End)
+            .textAlign(TextAlign.Center)
+            .fontColor($r('[basic].color.main_ac_color_light'))
+            .onClick(() => {
+              yTRouter.routerBack()
+            })
+            .height(24)
+            .width(48)
+            .borderRadius(12)
+            .backgroundColor('#4DFFFFFF')
+            .margin({ bottom: 24, right: 28, top: 20 })
+          Text('你好,\n欢迎来到盒小仓')
+            .lineHeight(40)
+            .fontSize(28)
+            .fontWeight(600)
+            .fontColor($r('[basic].color.main_ac_color_dark'))
+        }
+        .padding({ left: 16, })
+        .height(193)
+        .width('100%')
+        .alignItems(HorizontalAlign.Start)
+
+        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)
+            .textAlign(TextAlign.Center)
+            .height(48)
+            .borderRadius({ topLeft: 12, topRight: 12, bottomRight: this.tabBarIndex == 1 ? 12 : 0 })
+            .onClick(() => {
+              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
+            })
+            .backgroundColor(this.tabBarIndex == 1 ? Color.White : Color.Transparent)
+            .layoutWeight(1)
+            .height(48)
+            .textAlign(TextAlign.Center)
+            .fontColor(this.tabBarIndex == 1 ? '#FF141111' : '#80141111')
+            .onClick(() => {
+              this.tabBarIndex = 1
+              this.tabController.changeIndex(1)
+            })
+
+        }
+        .alignItems(VerticalAlign.Center)
+        .justifyContent(FlexAlign.SpaceBetween)
+        .width('100%')
+
+      }
+      .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 })
+
+        TabContent() {
+          LoginView({
+            forgetPassClick: () => {
+              this.tabBarIndex = 2
+              this.tabController.changeIndex(2)
+            }
           })
         }
-      })
-        .margin({ bottom: 81 })
-
-
-      // LoginButton('登录', () => {
-      //   if (!this.isAgree) {
-      //     PromptActionClass.openAgreePrivacy({})
-      //     return
-      //   }
-      //   const code = AppStorage.get<CodeType>('smsCode')
-      //   const askCodeNum: AskCodeNum = {
-      //     phonenumber: this.phoneNumber,
-      //     smsCode: this.Captcha,
-      //     uuid: code?.uuid
-      //   }
-      //
-      //   YTRequest.post<TokenType, AskCodeNum>('/api/friendcase/member/phoneLogin', askCodeNum)
-      //     .then(res => {
-      //       AppStorage.setOrCreate(AppstorageKey.TOKEN, res.token)
-      //       YTRequest.refreshUserInfo()
-      //       YTRouter.routerBack()
-      //       AppStorage.setOrCreate<string>(AppstorageKey.PHONE_NUMBER, this.phoneNumber)
-      //       IBestToast.show('登录成功')
-      //     })
-      //     .catch((err: Error) => {
-      //       YTLog.error(err)
-      //
-      //     })
-      //
-      // })
-
-      OtherLoginMethods({ loginMethodArr: this.loginMethodArr })
+        .padding({ left: 20, right: 20 })
+
+        TabContent() {
+          RegisterOrResetPassComp({ loginCollect: new LoginCollect("reset") })
+        }
+        .padding({ left: 20, right: 20 })
+      }
+      .scrollable(false)
+      .layoutWeight(1)
+      .barHeight(0)
+
     }
-    .backgroundColor(Color.White)
+
     .padding({
-      top: 10 + this.safeTop,
-      left: 16,
-      right: 16,
+
       bottom: this.safeBottom
     })
-    .alignItems(HorizontalAlign.Start)
     .height('100%')
   }
 }

+ 13 - 15
features/user/src/main/ets/pages/SettingPage.ets

@@ -10,9 +10,9 @@ import {
   YTButton,
   YTHeader,
   YTLog,
-  YTRequest,
-  YTRouter,
-  YTToast
+  yTRouter,
+  yTToast,
+  YTUserRequest
 } from 'basic'
 
 @Builder
@@ -25,7 +25,6 @@ function settingBuilder() {
 
 @Component
 struct SettingPage {
-  @StorageProp(YTAvoid.SAFE_TOP_KEY) safeTop: number = 0
   @StorageProp(YTAvoid.SAFE_BOTTOM_KEY) safeBottom: number = 0
   @StorageProp(UserInfo.KEY) userInfo: UserInfo = userInfo
   @State showReviseName: boolean = false
@@ -53,7 +52,7 @@ struct SettingPage {
         try {
           const fullpath = await takePicture(this.getUIContext().getHostContext()!)
           this.showHeaderImgRevise = false
-          YTRouter.router2DelPhotoPage({ src: fullpath, type: 'header' })
+          yTRouter.router2DelPhotoPage({ src: fullpath, type: 'header' })
         } catch (e) {
           YTLog.warn(e)
         }
@@ -64,7 +63,7 @@ struct SettingPage {
       click: () => {
         Upload.selectImage(this.getUIContext().getHostContext()!, (fullPath) => {
           this.showHeaderImgRevise = false
-          YTRouter.router2DelPhotoPage({ src: fullPath, type: 'image' })
+          yTRouter.router2DelPhotoPage({ src: fullPath, type: 'header' })
         })
       }
     },
@@ -100,7 +99,7 @@ struct SettingPage {
         YTButton({
           btContent: '退出登录', click: () => {
             this.userInfo.logout()
-            YTRouter.routerBack()
+            yTRouter.routerBack()
             IBestToast.show({ message: '退出登录成功' })
           }
         })
@@ -110,11 +109,11 @@ struct SettingPage {
           btFontColor: Color.Red,
           bgc: Color.White,
           click: () => {
-            YTToast.getInstance().doubleConfirm({
+            yTToast.doubleConfirm({
               text: '警告⚠', message: '确定要注销吗?\n注销后数据可能丢失无法恢复!', click: () => {
                 userInfo.logout()
-                YTToast.getInstance().hide()
-                YTRouter.routerBack()
+                yTToast.hide()
+                yTRouter.routerBack()
               }
             })
           }
@@ -126,12 +125,11 @@ struct SettingPage {
         backgroundColor: Color.White
       })
       .padding({
-        top: 29,
         left: 16,
         right: 16,
       })
     }
-    .padding({ top: this.safeTop, bottom: this.safeBottom })
+    .padding({ bottom: this.safeBottom })
 
   }
 
@@ -229,11 +227,11 @@ struct SettingPage {
               })
               return
             }
-            YTRequest.changeNickname(this.value, () => {
+            YTUserRequest.changeNickname(this.value, () => {
               IBestToast.show({ message: '名称修改成功' })
+              this.showReviseName = false
             })
-            //TODO 发送请求后关闭弹窗
-            this.showReviseName = false
+
           }
         })
       }

+ 5 - 5
features/user/src/main/ets/pages/SuggestionPage.ets

@@ -1,4 +1,4 @@
-import { IBestToast, YTAvoid, YTButton, YTHeader, YTRequest } from 'basic'
+import { IBestToast, YTAvoid, YTButton, YTHeader, YTUserRequest } from 'basic'
 
 @Builder
 function suggestionBuilder() {
@@ -10,9 +10,9 @@ function suggestionBuilder() {
 
 @Component
 struct SuggestionPage {
-  @StorageProp(YTAvoid.SAFE_BOTTOM_KEY) safeBottom: number = 0
-  @State description: string = ''
-  @State contact: string = ''
+  @StorageProp(YTAvoid.SAFE_BOTTOM_KEY) private safeBottom: number = 0
+  @State private description: string = ''
+  @State private contact: string = ''
 
   build() {
     Column() {
@@ -122,7 +122,7 @@ struct SuggestionPage {
               })
               return
             }
-            YTRequest.questionBack(this.description, this.contact)
+            YTUserRequest.questionBack(this.description, this.contact)
             // //TODO 发请求提交反馈
             // YTLog.info(this.description + this.contact + '反馈提交了')
           }

+ 136 - 0
features/user/src/main/ets/views/LoginView.ets

@@ -0,0 +1,136 @@
+import { BasicType, YTButton, } from 'basic'
+import { LoginCollect } from 'basic/src/main/ets/models/LoginCollect'
+import { LoginInput } from '../components/LoginInput'
+import { OtherLoginMethods } from '../components/OtherLoginMethods'
+import { Terms } from '../components/Terms'
+import { CodeInputType } from '../models'
+
+
+@Component
+export struct LoginView {
+  @State private loginCollect: LoginCollect = new LoginCollect('login')
+  @State private isPassword: boolean = false
+  private inputCaptchaType: CodeInputType = {
+    txt: '验证码',
+    placeHolder: '请输入验证码'
+  }
+  private inputPasswordType: CodeInputType = {
+    txt: '密码',
+    placeHolder: '请输入密码'
+  }
+  private loginMethodArr: BasicType<undefined>[] = [
+  // {
+  //   src: $r('app.media.wechat'),
+  //   txt: '微信登入',
+  //   click: () => {
+  //     //使用微信sdk实现微信登录
+  //
+  //   }
+  // },
+    {
+      src: $r('app.media.hua_wei'),
+      text: '华为登录',
+      click: () => {
+        this.loginCollect.executeLogin("harmony")
+      }
+    }
+  ]
+  private inputPhoneNumberType: CodeInputType = {
+    txt: '+86',
+    placeHolder: '请输入手机号'
+  }
+  forgetPassClick: () => void = () => {
+  }
+
+  build() {
+    Column() {
+      LoginInput({
+        item: this.inputPhoneNumberType,
+        inputData: this.loginCollect.phonenumber,
+        isPassword: false,
+        needCode: false,
+        inputChange: (value: string) => {
+          this.loginCollect.phonenumber = value
+        }
+      })
+      if (this.isPassword) {
+        LoginInput({
+          item: this.inputPasswordType,
+          inputData: this.loginCollect.password,
+          isPassword: true,
+          needCode: false,
+          inputChange: (value: string) => {
+            this.loginCollect.password = value
+          }
+        })
+      } else {
+        LoginInput({
+          item: this.inputCaptchaType,
+          inputData: this.loginCollect.smsCode,
+          loginCollect: this.loginCollect,
+          isAgree: this.loginCollect.isAgreePrivacy,
+          inputChange: (value: string) => {
+            this.loginCollect.smsCode = value
+          },
+          marginBottom: 19
+        })
+      }
+
+      Terms({
+        isAgree: this.loginCollect.isAgreePrivacy, mg: 13, onAgreeChange: () => {
+          this.loginCollect.isAgreePrivacy = !this.loginCollect.isAgreePrivacy
+        }
+      })
+
+      Row() {
+        if (!this.isPassword) {
+          Text('密码登录')
+            .fontColor($r('[basic].color.main_ac_color_dark'))
+            .fontSize(12)
+            .fontWeight(700)
+            .onClick(() => {
+              this.isPassword = true
+            })
+          Blank()
+        } else {
+          Text('验证码登录')
+            .fontColor($r('[basic].color.main_ac_color_dark'))
+            .fontWeight(700)
+            .fontSize(12)
+            .onClick(() => {
+              this.isPassword = false
+            })
+          Blank()
+          Text('忘记密码?')
+            .fontColor($r('[basic].color.main_ac_color_dark'))
+            .fontSize(12)
+            .fontWeight(700)
+            .onClick(() => {
+              this.forgetPassClick?.()
+            })
+        }
+      }
+      .width('100%')
+      .margin({ top: 20, bottom: 20 })
+
+
+      YTButton({
+        btContent: '登录',
+        click: () => {
+          this.loginCollect.executeLogin("common")
+        }
+      })
+
+
+      Text('未注册的手机号码登陆后将自动注册')
+        .fontColor($r('[basic].color.main_ac_color_dark'))
+        .fontSize(12)
+        .margin({ top: 16, bottom: 56 })
+        .alignSelf(ItemAlign.Start)
+
+      OtherLoginMethods({ loginMethodArr: this.loginMethodArr })
+    }
+    .width('100%')
+    .height('100%')
+  }
+}

+ 15 - 6
features/user/src/main/ets/views/Mine.ets

@@ -1,4 +1,13 @@
-import { BasicType, copyText, IBestToast, userInfo, UserInfo, YTAvoid, YTLog, YTRouter } from 'basic'
+import {
+  BasicType,
+  copyText,
+  IBestToast,
+  userInfo,
+  UserInfo,
+  YTAvoid,
+  YTLog,
+  yTRouter
+} from 'basic'
 import { common, Want } from '@kit.AbilityKit'
 import { BusinessError } from '@kit.BasicServicesKit'
 import { BUNDLE_NAME } from 'BuildProfile'
@@ -12,9 +21,9 @@ export struct Mine {
       text: '意见反馈',
       click: () => {
         if (this.userInfo.checkLogin()) {
-          YTRouter.router2SuggestionPage()
+          yTRouter.router2SuggestionPage()
         } else {
-          YTRouter.router2LoginPage()
+          yTRouter.router2LoginPage()
         }
       },
       src: $r('app.media.right_arrow')
@@ -40,7 +49,7 @@ export struct Mine {
     {
       text: '关于我们',
       click: () => {
-        YTRouter.router2AboutUS()
+        yTRouter.router2AboutUS()
       },
       src: $r('app.media.right_arrow')
     }
@@ -84,10 +93,10 @@ export struct Mine {
         .onClick(() => {
 
           if (this.userInfo.checkLogin()) {
-            YTRouter.router2SettingPage()
+            yTRouter.router2SettingPage()
             return
           }
-          YTRouter.router2LoginPage()
+          yTRouter.router2LoginPage()
         })
       }
       .width('100%')

+ 103 - 0
features/user/src/main/ets/views/RegisterOrResetPassView.ets

@@ -0,0 +1,103 @@
+import { YTButton } from 'basic'
+import { LoginCollect } from 'basic/src/main/ets/models/LoginCollect'
+import { CodeInputType } from '../models'
+import { LoginInput } from '../components/LoginInput'
+
+@Component
+export struct RegisterOrResetPassComp {
+  @State @Require loginCollect: LoginCollect
+  private mgBottom: number = 24
+  private inputPhoneNumberType: CodeInputType = {
+    txt: '+86',
+    placeHolder: '请输入手机号码'
+  }
+  private inputCaptchaType: CodeInputType = {
+    txt: '验证码',
+    placeHolder: '请输入验证码'
+  }
+  private inputPasswordType: CodeInputType = {
+    txt: '密码',
+    placeHolder: '设置密码'
+  }
+  private inputConfirmPasswordType: CodeInputType = {
+    txt: '密码',
+    placeHolder: '再次确认密码'
+  }
+
+  build() {
+    Column() {
+      LoginInput({
+        item: this.inputPhoneNumberType,
+        inputData: this.loginCollect.phonenumber,
+        needCode: false,
+        inputChange: (value) => {
+          this.loginCollect.phonenumber = value
+        }
+      })
+      LoginInput({
+        item: this.inputCaptchaType,
+        inputData: this.loginCollect.smsCode,
+        needCode: true,
+        loginCollect: this.loginCollect,
+        inputChange: (value) => {
+          this.loginCollect.smsCode = value
+        }
+      })
+      LoginInput({
+        item: this.inputPasswordType,
+        inputData: this.loginCollect.password,
+        needCode: false,
+        isPassword: true,
+        marginBottom: 0,
+        inputChange: (value) => {
+          this.loginCollect.password = value
+        }
+      })
+      LoginInput({
+        item: this.inputConfirmPasswordType,
+        inputData: this.loginCollect.confirmPassword,
+        isPassword: true,
+        needCode: false,
+        inputChange: (value) => {
+          this.loginCollect.confirmPassword = value
+        }
+      })
+
+      Text('*密码必须包含8-20位数字或字母、特殊符号')
+        .fontSize(10)
+        .fontColor('#e1e1e1')
+        .margin({ top: 4, bottom: 48 })
+        .fontColor('#FFEA4A18')
+
+
+      YTButton({
+        //: '立即重置'
+        btContent: this.calcButtonContent(),
+        click: () => {
+          this.loginCollect.executeLogin("common")
+        },
+        btHeight: 48,
+        btBorderRadius: 32
+      })
+
+      Text('注册成功后将自动登录')
+        .fontSize(10)
+        .fontColor($r('[basic].color.main_ac_color_dark'))
+        .margin({ top: 16 })
+    }
+    .width('100%')
+    .height('100%')
+    .alignItems(HorizontalAlign.Start)
+  }
+
+  private calcButtonContent() {
+    switch (this.loginCollect.getOperation()) {
+      case 'register':
+        return '立即注册'
+      case 'reset':
+        return '立即重置'
+      case 'login':
+        return '立即登录'
+    }
+  }
+}

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


+ 12 - 4
products/entry/src/main/ets/entryability/EntryAbility.ets

@@ -1,7 +1,15 @@
 import { AbilityConstant, bundleManager, ConfigurationConstant, UIAbility, Want } from '@kit.AbilityKit';
 import { hilog } from '@kit.PerformanceAnalysisKit';
 import { window } from '@kit.ArkUI';
-import { AppStorageKeyCollect, jHStartAd, PermissionControl, YTAvoid, YTBreakPoint, YTLog, YTRequest } from 'basic';
+import {
+  AppStorageKeyCollect,
+  jHStartAd,
+  permissionController,
+  YTAvoid,
+  YTBreakPoint,
+  YTLog,
+  YTUserRequest
+} from 'basic';
 import { preferences } from '@kit.ArkData';
 import { identifier } from '@kit.AdsKit';
 import { BusinessError } from '@kit.BasicServicesKit';
@@ -36,7 +44,7 @@ export default class EntryAbility extends UIAbility {
 
       PersistentStorage.persistProp<string>(AppStorageKeyCollect.TOKEN, '')
       if (AppStorage.get<string>(AppStorageKeyCollect.TOKEN)) {
-        YTRequest.refreshUserInfo()
+        YTUserRequest.refreshUserInfo()
       }
       // IBestInit(windowStage, this.context)
       bundleManager.getBundleInfoForSelf(bundleManager.BundleFlag.GET_BUNDLE_INFO_WITH_SIGNATURE_INFO)
@@ -46,9 +54,9 @@ export default class EntryAbility extends UIAbility {
         .catch((err: Error) => {
           YTLog.error(err)
         })
-      PermissionControl.getInstance().init(this.context)
+      permissionController.init(this.context)
         .then(() => {
-          PermissionControl.getInstance().askPermission(["ohos.permission.APP_TRACKING_CONSENT"], (res, err) => {
+          permissionController.askPermission(["ohos.permission.APP_TRACKING_CONSENT"], (res, err) => {
             if (err) {
               YTLog.error(err)
             } else {

+ 3 - 3
products/entry/src/main/ets/pages/Index.ets

@@ -1,4 +1,4 @@
-import { BasicType, YTAvoid, YTRouter, YTToast } from 'basic';
+import { BasicType, YTAvoid, yTRouter, yTToast } from 'basic';
 import { Mine } from 'user/src/main/ets/views/Mine';
 import { MainView, SecondView, ThirdView } from 'feature';
 
@@ -33,14 +33,14 @@ struct Index {
   tabsController: TabsController = new TabsController()
 
   aboutToAppear(): void {
-    YTToast.getInstance().init({
+    yTToast.init({
       context: this.getUIContext(),
       options: { alignment: DialogAlignment.Center, maskColor: '#80000000' }
     })
   }
 
   build() {
-    Navigation(YTRouter.getInstance()) {
+    Navigation(yTRouter) {
       Column() {
         Tabs({ controller: this.tabsController }) {
           ForEach(this.contentList, (_: BasicType<undefined>, index) => {