PersonList.ets 7.4 KB
import { AxiosResponse } from '@ohos/axios'
import { getCompanyPersonList } from '../api/originalRecords'
import { companyPersonTest, companyPersonRow, QueryParams } from '../api/recordsType'
import { router } from '@kit.ArkUI'
import preferencesUtils from '../utils/preferences'
import baseUrl from '../utils/baseUrl'
import AddPersonDialog from '../dialog/AddPersonDialog'

@Extend(Text) function primary () {
  .fontColor('#1890ff').backgroundColor('#e8f4ff')
  .borderColor('#d1e9ff')
}
@Extend(Text) function success () {
  .fontColor('#13ce66').backgroundColor('#e7faf0')
  .borderColor('#d0f5e0')
}
@Extend(Text) function danger () {
  .fontColor('#ff4949').backgroundColor('#ffeded')
  .borderColor('#ffdbdb')
}

let companyId = preferencesUtils.get('XF_COMPANY_ID', '') as number
let getTextInfo = (state: string | null) => {
  if(state == '0') {
    return '离职'
  } else if(state == '1') {
    return '待确定'
  } else if(state == '2') {
    return '在职'
  } else {
    return ''
  }
}
@Entry
@Component
struct PersonList {
  dialogController: CustomDialogController = new CustomDialogController({
    builder: AddPersonDialog(),
    cornerRadius: 10
  })
  @State params: QueryParams = {
    pageNum: 1,
    pageSize: 10,
    companyId: companyId,
    personName: ''
  }
  @State totalAll: number = 0
  @State personList: companyPersonRow[] = []
  @State refreshing: boolean = false;
  @State refreshOffset: number = 0;
  @State canLoad: boolean = false;
  @State refreshState: RefreshStatus = RefreshStatus.Inactive; // 刷新状态
  @State isLoading: boolean = false; // 是否在加载
  @State loadingText: string = ''; // 加载是文字
  getList = async () => {
    const personRes: AxiosResponse<companyPersonTest> = await getCompanyPersonList(this.params)
    this.personList = personRes.data.rows
    this.totalAll = personRes.data.total
  }
  async onPageShow(){
    await this.getList()
  }

  // 自定义刷新布局
  @Builder
  refreshBuilder() {
    Stack({ alignContent: Alignment.Bottom }) {
      // 可以通过刷新状态控制是否存在Progress组件
      // 当刷新状态处于下拉中或刷新中状态时Progress组件才存在
      if (this.refreshState != RefreshStatus.Inactive && this.refreshState != RefreshStatus.Done) {
        Row() {
          LoadingProgress().height(32)
          Text("Refreshing...").fontSize(16).margin({ left: 20 })
        }
        .alignItems(VerticalAlign.Center)
      }
    }
    .clip(true)
    .height("100%")
    .width("100%")
  }

  // 自定义加载布局
  @Builder
  footer() {
    Row() {
      LoadingProgress().height(32).width(48)
        .visibility(this.isLoading ? Visibility.Visible : Visibility.None)
      Text(this.loadingText)
    }.width("100%")
    .height(64)
    .justifyContent(FlexAlign.Center)
  }
  // 刷新测试数据
  private async refreshData(){
    this.personList = []
    this.params = {
      pageNum: 1,
      pageSize: 10,
      companyId
    }
    await this.getList()
    this.refreshing = false;
  }

  // 加载更多测试数据
  private async loadMoreData(){
    if(this.params.pageSize >= this.totalAll) {
      this.isLoading = false
      this.loadingText = '已加载全部数据'
    }else {
      this.params.pageSize += 10
      this.loadingText = '加载中'
      await this.getList()
      this.isLoading = false
    }
  }
  build() {
    Column(){
      // 顶部搜索
      Row(){
        Search({ value: $$this.params.personName, placeholder: '请输入人员姓名' })
          .searchButton('搜索', {
            fontSize: 12
          })
          .width('95%')
          .height(30)
          .backgroundColor('#fff')
          .placeholderColor(Color.Grey)
          .placeholderFont({ size: 12, weight: 400 })
          .textFont({ size: 12, weight: 400 })
          .layoutWeight(1)
          .onSubmit(async () => {
            this.personList = []
            this.params.pageSize = 10
            await this.getList()
          })
        Image($r('app.media.add')).width(20).onClick(() => {
          this.dialogController.open()
        })
      }.padding({left: 5, right: 5})
      Refresh({ refreshing: $$this.refreshing, builder: this.refreshBuilder() }) {
        List({space: 10}) {
          ForEach(this.personList, (item: companyPersonRow, index: number) => {
            ListItem(){
              Row(){
                Row({space: 10}){
                  Image(baseUrl + item.personalImg).width(60).height(60).borderRadius(10)
                  Column(){
                    Text(item.personName).fontSize(14).fontWeight(600).lineHeight(19).margin({bottom: 5})
                      .fontColor('#3d3d3d').textOverflow({overflow: TextOverflow.Ellipsis}).maxLines(1)
                    Text(item.certificateLevel + item.certificateName).fontColor('#999').fontSize(12)
                    Text(item.createTime).fontColor('#999').fontSize(12).lineHeight(16)
                  }.alignItems(HorizontalAlign.Start)
                }.layoutWeight(1)
                Row(){
                  Text(getTextInfo(item.state)).padding({bottom: 5, top: 5, left: 15, right: 15}).success()
                    .visibility(item.state == '2' ? Visibility.Visible: Visibility.None).borderWidth(1).borderRadius(4).fontSize(12)
                  Text(getTextInfo(item.state)).padding({bottom: 5, top: 5, left: 15, right: 15}).primary()
                    .visibility(item.state == '1' ? Visibility.Visible: Visibility.None).borderWidth(1).borderRadius(4).fontSize(12)
                  Text(getTextInfo(item.state)).padding({bottom: 5, top: 5, left: 15, right: 15}).danger()
                    .visibility(item.state == '0' ? Visibility.Visible: Visibility.None).borderWidth(1).borderRadius(4).fontSize(12)
                  Image($r('app.media.right_3')).width(12)
                }
              }.width('100%').justifyContent(FlexAlign.SpaceBetween)
              .border({width: {bottom: this.personList.length == index + 1 ? 0 : 1}, color: '#eee'}).padding({top: 15, bottom: 15})
              .onClick(() => {
                router.pushUrl({
                  url: 'pages/PersonDetail',
                  params: {
                    personId: item.personId
                  }
                })
              })
            }.padding({left: 10, right: 10}).backgroundColor(Color.White)
          })
          ListItem() {
            this.footer();
          }
        }
        .onScrollIndex((start: number, end: number) => {
          // 当达到列表末尾时,触发新数据加载
          if (this.canLoad && end >= this.personList.length - 1) {
            this.canLoad = false;
            this.isLoading = true;
            this.loadMoreData()
          }
        })
        .onScrollFrameBegin((offset: number) => {
          // 只有当向上滑动时触发新数据加载
          if (offset > 5 && !this.isLoading) {
            this.canLoad = true;
          }
          return { offsetRemain: offset };
        })
        .scrollBar(BarState.Off)
        // 开启边缘滑动效果
        .edgeEffect(EdgeEffect.Spring, { alwaysEnabled: true })
      }
      .width('100%')
      .height('100%')
      .backgroundColor('#f2f3f7')
      .padding(10)
      .onOffsetChange((offset: number) => {
        this.refreshOffset = offset;
      })
      .onStateChange((state: RefreshStatus) => {
        this.refreshState = state;
      })
      .onRefreshing(() => {
        this.refreshData()
      })
    }.width('100%').height('100%')
  }
}