EditUser.ets 14.3 KB
import AreaPickerDialog from '../dialog/AreaPickerDialog'
import { ValidateInputHandle } from '../utils/validateInputHandle'
import { personData, personTest } from '../api/userType'
import preferencesUtil from '../utils/preferences'
import baseUrl from '../utils/baseUrl'
import { updatePersonInfo, getPersonInfo, getEmailCode, emailType } from '../api/user'
import { promptAction } from '@kit.ArkUI';
import { AxiosResponse } from '@ohos/axios'
import PhotoBrowser from '../dialog/PhotoBrowserDialog'
import { uploadFile, uploadResult } from '../utils/uploadFile'
import { request } from '@kit.BasicServicesKit'
import NavHeader from '../components/NavHeader'
import LoadingDialog from '../dialog/LoadingDialog'

@Entry
@Component
struct EditUser {
  @Builder indicatorBuilder(icon: ResourceStr) {
    Image(icon)
  }
  @State isShowCode: boolean = false
  @State userInfo: personData = JSON.parse(preferencesUtil.get('XF_PERSON_INFO', '') as string)
  @State pickerValue:string[] = ['广西壮族自治区','南宁市','青秀区']//省市区选中值
  @State photoList: string[] = [baseUrl + this.userInfo.personalImg, baseUrl + this.userInfo.idImgFront, baseUrl + this.userInfo.idImgBack]
  @State initEmail: string = this.userInfo.email
  @State codeStr: string = '' // 存储验证码对比
  @State timerCount: number = 300
  formKey: string[] = ['personName', 'email', 'birthDate', 'idNo', 'phone', 'personalImg', 'idImgFront', 'idImgBack']
  async aboutToAppear() {
    const info: AxiosResponse<personTest> = await getPersonInfo()
    preferencesUtil.set('XF_PERSON_INFO', JSON.stringify(info.data.data))
    this.userInfo = JSON.parse(preferencesUtil.get('XF_PERSON_INFO', '') as string)
    this.userInfo.address = this.pickerValue.join(' ')
  }
  // 区域弹窗
  areaController: CustomDialogController = new CustomDialogController({
    builder: AreaPickerDialog({
      value:this.pickerValue,//首次默认选中值
      onChange: (value:string[]) => {//选择改变回调
        this.pickerValue = value
        this.userInfo.address = this.pickerValue.join(' ')
      }
    }),
    customStyle: true,
    autoCancel: false
  })
  private selectedDate: Date = new Date('2000-01-01')
  // 图片预览
  photoBrowserController: CustomDialogController = new CustomDialogController({
    builder: PhotoBrowser({ imagesList: this.photoList}),
    customStyle: true,
    offset: { dx: 0, dy: 0 },
    alignment: DialogAlignment.Top,
  })
  // 加载弹窗
  loadingController: CustomDialogController = new CustomDialogController({
    builder: LoadingDialog(),
    customStyle: true,
    offset: { dx: 0, dy: 0 },
    alignment: DialogAlignment.Center,
    autoCancel: false
  })
  // 获取验证码
  getCode = async () => {
    if(this.codeStr == '') {
      this.loadingController.open()
      let emailRes: AxiosResponse<emailType> = await getEmailCode(this.userInfo.email)
      this.codeStr = emailRes.data.data
      this.loadingController.close()
      let timer = setInterval(() => {
        this.timerCount--
        if(this.timerCount === 0){
          clearInterval(timer)
          this.codeStr = ''
          this.timerCount = 300
        }
      }, 1000)
      promptAction.showToast({
        message: '已发送至邮箱,请查收'
      })
    } else {
      promptAction.showToast({
        message: '验证码已发送,300s内不在发送'
      })
    }
  }

  // 校验函数
  ValidateHandle = (arr: string[], obj: personData): boolean => {
    let keyArr: string[] = Object.keys(obj)
    let valueArr: (string | number | null)[] = Object.values(obj)
    for(let i = 0; i < keyArr.length; i++) {
      if(arr.includes(keyArr[i]) && valueArr[i] == '') return false
    }
    return true
  }

  // 提交修改
  submitForm = async () => {
    if(!this.ValidateHandle(this.formKey, this.userInfo)) return promptAction.showToast({message: '带星号的为必填项'})
    if(!ValidateInputHandle(this.userInfo.idNo, 'idCard')) return promptAction.showToast({message: '身份证输入有误'})
    if(!ValidateInputHandle(this.userInfo.phone, 'phone')) return promptAction.showToast({message: '手机号输入有误'})
    if(!ValidateInputHandle(this.userInfo.email, 'email')) return promptAction.showToast({message: '邮箱输入有误'})
    if(this.isShowCode && (this.userInfo.code == '' || this.userInfo.code == undefined)) return promptAction.showToast({message: '请输入验证码'})
    if(this.isShowCode && this.userInfo.code !== this.codeStr) return promptAction.showToast({message: '验证码输入有误'})
    await updatePersonInfo(this.userInfo)
    const info: AxiosResponse<personTest> = await getPersonInfo()
    preferencesUtil.set('XF_PERSON_INFO', JSON.stringify(info.data.data))
    this.userInfo = JSON.parse(preferencesUtil.get('XF_PERSON_INFO', '') as string)
    promptAction.showToast({ message: '修改成功', duration: 2000 })
  }

  build() {
    Column(){
      NavHeader({title: '编辑个人信息'})
      Scroll(){
        Column(){
         Column(){
           Row(){
             Row(){
               Image($r('app.media.require')).width(20)
               Text('姓名')
             }.width(90)
             TextInput({placeholder: '请输入姓名', text: $$this.userInfo.personName})
               .backgroundColor('#fff').layoutWeight(1)
           }.border({width: {bottom: 1}, color: '#eee'}).padding({top: 10, bottom: 10})
           Row(){
             Row(){
               Image($r('app.media.require')).width(20)
               Text('邮箱')
             }.width(90)
             TextInput({placeholder: '请输入邮箱', text: $$this.userInfo.email})
               .backgroundColor('#fff').layoutWeight(1).type(InputType.Email)
               .showError(ValidateInputHandle(this.userInfo.email, 'email') ? '' : '请正确输入邮箱')
               .onChange((value) => {
                 this.isShowCode = this.initEmail !== value
               })
           }.border({width: {bottom: 1}, color: '#eee'}).padding({top: 10, bottom: 10})
           Row(){
             Row(){
               Image($r('app.media.require')).width(20)
               Text('验证码')
             }.width(90)
             Row(){
               TextInput({placeholder: '请输入验证码', text: $$this.userInfo.code})
                 .backgroundColor('#fff').layoutWeight(1)
               Text(this.codeStr == '' ? '获取验证码' : `${this.timerCount}s后重新获取`).fontSize(12).backgroundColor('#1890ff').borderRadius(5)
                 .padding({top: 4, bottom: 4, left: 10, right: 10}).fontColor('#fff')
                 .onClick(() => {
                   this.getCode()
                 })
             }.layoutWeight(1)
           }.border({width: {bottom: 1}, color: '#eee'}).padding({top: 10, bottom: 10})
           .visibility(this.isShowCode ? Visibility.Visible : Visibility.None)
           Row(){
             Row(){
               Image($r('app.media.require')).width(20)
               Text('性别')
             }.width(90)
             Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center }) {
               Row() {
                 Radio({ value: '0', group: 'radioGroup',
                   indicatorType:RadioIndicatorType.CUSTOM,
                   indicatorBuilder:()=>{this.indicatorBuilder($r('app.media.man'))}
                 }).checked(this.userInfo.gender == '0')
                   .height(20)
                   .width(20)
                   .onChange(() => {
                     this.userInfo.gender = '0'
                   })
                 Text('男')
               }
               Row() {
                 Radio({ value: '1', group: 'radioGroup',
                   indicatorType:RadioIndicatorType.CUSTOM,
                   indicatorBuilder:()=>{this.indicatorBuilder($r('app.media.pain_woman'))}
                 }).checked(this.userInfo.gender == '1')
                   .height(20)
                   .width(20)
                   .onChange(() => {
                     this.userInfo.gender = '1'
                   })
                 Text('女')
               }
             }
           }.border({width: {bottom: 1}, color: '#eee'}).padding({top: 10, bottom: 10})
           Row(){
             Row(){
               Image($r('app.media.require')).width(20)
               Text('出生日期')
             }.width(90)
             Text(this.userInfo.birthDate).padding({top: 8, bottom: 8, left: 16, right: 16})
               .backgroundColor('#fff').layoutWeight(1).fontColor('#000').onClick(() => {
               CalendarPickerDialog.show({
                 selected: this.selectedDate,
                 onAccept: (value) => {
                  this.userInfo.birthDate = JSON.stringify(value).slice(1, 11)
                 }
               })
             })
           }.border({width: {bottom: 1}, color: '#eee'}).padding({top: 10, bottom: 10})
           Row(){
             Row(){
               Image($r('app.media.require')).width(20)
               Text('身份证号')
             }.width(90)
             TextInput({placeholder: '请输入身份证号', text: $$this.userInfo.idNo})
               .backgroundColor('#fff').layoutWeight(1).type(InputType.Number)
               .showError(ValidateInputHandle(this.userInfo.idNo, 'idCard') ? '' : '请正确输入身份证')
           }.border({width: {bottom: 1}, color: '#eee'}).padding({top: 10, bottom: 10})
           Row(){
             Row(){
               Image($r('app.media.require')).width(20)
               Text('手机号')
             }.width(90)
             TextInput({placeholder: '请输入手机号', text: $$this.userInfo.phone})
               .backgroundColor('#fff').layoutWeight(1).type(InputType.PhoneNumber)
               .showError(ValidateInputHandle(this.userInfo.phone, 'phone') ? '' : '请正确输入手机号')
           }.border({width: {bottom: 1}, color: '#eee'}).padding({top: 10, bottom: 10})
           Row(){
             Row(){
               Image($r('app.media.require')).width(20)
               Text('个人照片')
             }.width(90)
             Row(){
               Image(baseUrl + this.userInfo.personalImg || $r('app.media.userAvatar')).width(80)
                 .onClick(async () => {
                   let that = this
                   let uploader = await uploadFile() as request.UploadTask
                   // 3. 监控上传错误
                   uploader.on('fail', (err) => {
                     console.log('上传错误--->', JSON.stringify(err))
                   })
                   //   4. 获取服务器返回来的数据
                   uploader.on('headerReceive',(res)=>{
                     let uploadInfo = JSON.parse(res['body']) as uploadResult
                     that.userInfo.personalImg = uploadInfo.fileName as string
                   })
                 })
             }.layoutWeight(1).margin({left: 20})
           }.border({width: {bottom: 1}, color: '#eee'}).padding({top: 10, bottom: 10})
           Row(){
             Row(){
               Image($r('app.media.require')).width(20)
               Text('证件正面')
             }.width(90)
             Row(){
               Image(baseUrl + this.userInfo.idImgFront || $r('app.media.idCard')).width(120)
                 .onClick(async () => {
                   let that = this
                   let uploader = await uploadFile() as request.UploadTask
                   // 3. 监控上传错误
                   uploader.on('fail', (err) => {
                     console.log('上传错误--->', JSON.stringify(err))
                   })
                   //   4. 获取服务器返回来的数据
                   uploader.on('headerReceive',(res)=>{
                     let uploadInfo = JSON.parse(res['body']) as uploadResult
                     that.userInfo.idImgFront = uploadInfo.fileName as string
                   })
                 })
             }.layoutWeight(1).margin({left: 20})
           }.border({width: {bottom: 1}, color: '#eee'}).padding({top: 10, bottom: 10})
           Row(){
             Row(){
               Image($r('app.media.require')).width(20)
               Text('证件反面')
             }.width(90)
             Row(){
               Image(baseUrl + this.userInfo.idImgBack || $r('app.media.unIdCard')).width(120)
                 .onClick(async () => {
                   let that = this
                   let uploader = await uploadFile() as request.UploadTask
                   // 3. 监控上传错误
                   uploader.on('fail', (err) => {
                     console.log('上传错误--->', JSON.stringify(err))
                   })
                   //   4. 获取服务器返回来的数据
                   uploader.on('headerReceive',(res)=>{
                     let uploadInfo = JSON.parse(res['body']) as uploadResult
                     that.userInfo.idImgBack = uploadInfo.fileName as string
                   })
                 })
             }.layoutWeight(1).margin({left: 20})
           }.border({width: {bottom: 1}, color: '#eee'}).padding({top: 10, bottom: 10})
           Row(){
             Row(){
               Image($r('app.media.require')).width(20)
               Text('地址')
             }.width(70)
             Text(this.pickerValue.join(' ')).layoutWeight(1).padding({top: 8, bottom: 8, left: 16, right: 16})
               .backgroundColor('#fff').fontColor('#999').textOverflow({overflow: TextOverflow.Ellipsis}).maxLines(2)
               .onClick(() => {
               this.areaController?.open()
             })
           }.border({width: {bottom: 1}, color: '#eee'}).padding({top: 10, bottom: 10})
         }.backgroundColor('#fff').width('100%').padding({left: 5, right: 5}).borderRadius(10)
        }.padding(10).margin({bottom: 20, top: 10})
      }.layoutWeight(1).scrollBar(BarState.Off)

      // 底部区域
      Row({ space: 10}){
        Text('提交').borderRadius(5).layoutWeight(1).height(30).fontColor('#fff')
          .backgroundColor('#1B65FD').fontSize(14).textAlign(TextAlign.Center)
          .onClick(() => {
            this.submitForm()
          })
        Text('图片预览').borderRadius(5).layoutWeight(1).height(30).fontColor('#fff')
          .backgroundColor('#1B65FD').fontSize(14).textAlign(TextAlign.Center)
          .onClick(async () => {
            this.photoBrowserController.open()
          })
      }.width('100%').height(40).backgroundColor('#fff').padding({left: 10, right: 10})
    }.width('100%').height('100%').backgroundColor('#f2f3f7')
  }
}