鸿蒙next boss直聘招聘app 聊天功能实现来

2024-12-09 01:22:42
155次阅读
0个评论
最后修改时间:2024-12-25 00:07:33

前言:

之前一直在线下教学 所以很久没有更新代码了。所以最近就更新下我自己博客也算是回馈粉丝吧,今天就是把之前boss直聘的聊天功能补齐

效果图

image.png

image.png

image.png

消息列表页面实现


import {Messagedata, MessageModel} from  '../bean/MessageModel'
import Logger from '../utils/Logger';
import { httpRequestGet } from '../utils/OkhttpUtils';
import CommonConstant, * as commonConst from '../common/CommonConstants';
import { router } from '@kit.ArkUI';

/**
 *
 * 创建人:xuqing
 * 创建时间:2024年6月30日21:08:21
 * 类说明:消息模块
 *
 */
@Entry
@Component
export default struct MessageList {

  @State message:Messagedata=new Messagedata();
  @State JokeList:Array<Messagedata>=[];

  async  aboutToAppear() {
    let messageurl=CommonConstant.MESSAGE;
    httpRequestGet(messageurl).then((data)=>{
      Logger.error("请求消息数据返回 -- >"+data.toString());
      let messagemodel:MessageModel=JSON.parse(data.toString());
      if(messagemodel.code==200){
        this.JokeList=messagemodel.data;
      }else{

      }
    });

  }

  build() {
    Row(){
      Column(){
        Row(){
          Text("消息")
            .fontSize(25)
            .fontColor(Color.White)
            .textAlign(TextAlign.Center)
        }.width('100%')
        .height(40)
        .backgroundColor(Color.Green)
        .justifyContent(FlexAlign.Center)
        List({space:16}){
          ForEach(this.JokeList,(item:Messagedata)=>{
            ListItem(){
              Column(){
                Row(){
                  Image(item?.headportraiturl).width(100).height(100).
                  objectFit(ImageFit.Contain).borderRadius(8).margin({left:10})
                    .clip(true);
                  Column(){
                    Text(item?.nickname).fontSize(18).fontColor(Color.Black)
                      .margin({top:5})
                    Text(item?.companyname).fontSize(15).fontColor(Color.Gray)
                      .margin({top:5})
                    Text(item?.msg).fontSize(15).fontColor(Color.Black)
                      .margin({top:5})
                  }.justifyContent(FlexAlign.Start).margin({left:20}).alignItems(HorizontalAlign.Start)

                }.justifyContent(FlexAlign.Start)
                .height('90%')
                .width('100%')
                Line().width('100%').height(1).backgroundColor(Color.Black)
              }.height(100)
              .width('100%')
            }.onClick(()=>{
              router.pushUrl({
                url:"pages/MessageListdetails",
                params:item
              })
            })
          })
        }
      }.width('100%')
      .height('100%')
      Line().width('100%').height(1).backgroundColor(Color.Black)
    }.justifyContent(FlexAlign.Center)
    .width('100%')
    .height('100%')


  }
}

和HR聊天页面和实现

import { Messagedata } from '../bean/MessageModel'
import { UserMessageBase } from '../bean/UserMessageBase'
import { Prompt, router } from '@kit.ArkUI';



@Entry
@Component
struct MessageListdetails{
  @State inputMessage:string = ''
  @State isSendFlag:boolean = false;
  @State messageId:number = 10;
  private  flag:boolean=false;
  @State chatMessageList:UserMessageBase[]=[];
  messagedata?:Messagedata



  aboutToAppear(): void {
    this.messagedata=router.getParams()as  Messagedata;
    this.chatMessageList.push({
      id:0,
      img:$r('app.media.icon_head_default'),
      content:this.messagedata?.msg,
      category:0
    })
  }

  build() {
    RelativeContainer(){
      RelativeContainer(){
        Image($r('app.media.bossback'))
          .width(25)
          .height(25)
          .onClick(()=>{
            router.back()
          }).alignRules({
          center: { anchor: '__container__', align: VerticalAlign.Center },
          left: { 'anchor': '__container__', 'align': HorizontalAlign.Start }
        }).margin({left:5,top:7})
        Text(this.messagedata?.nickname)
          .id("nameText")
          .fontSize(16)
          .alignRules({
            center: { anchor: '__container__', align: VerticalAlign.Center },
            middle: { anchor: '__container__', align: HorizontalAlign.Center }
          })
        Divider()
          .backgroundColor("#ffe1ee9")
          .height(1)
          .width("100%")
          .alignRules({
            bottom:{'anchor':"__container__",'align':VerticalAlign.Bottom}
          })
      }.id("topBar")
      .width("100%")
      .height(45)
      List(){
        ForEach(this.chatMessageList,(item:UserMessageBase)=>{
          if(item.category==0){
            //左边item布局
            this.leftLayout(this.messagedata,item)
          }else {
            //右边布局
            this.rightLayout(this.messagedata,item)
          }
        })

      }.id("chatList")
      .width("100%")
      .backgroundColor("#f4f4f4")
      .padding({
        left:16,
        right:16
      }).alignRules({
        top:{'anchor':"topBar",'align':VerticalAlign.Bottom},
        left:{'anchor':"__container__",'align':HorizontalAlign.Start},
        right:{'anchor':'__container__','align':HorizontalAlign.End},
        bottom:{'anchor':'bottomControl','align':VerticalAlign.Top}

      })

      Row({space:12}){
        Image($r('app.media.voice'))
          .width(25)
          .height(25)
        TextArea({text:this.inputMessage})
          .width(100)
          .height(40)
          .layoutWeight(2)
          .borderRadius(6)
          .backgroundColor(Color.White)
          .onChange((value)=>{
            if(value==""){
              this.isSendFlag=false;
            }else{
              this.isSendFlag=true;
            }
            this.inputMessage=value;

          })

        Stack(){
          Image($r('app.media.more'))
            .width(25)
            .height(25)
            .visibility(this.isSendFlag?Visibility.Hidden:Visibility.Visible)
          Button("发送")
            .width(70)
            .height(30)
            .type(ButtonType.Normal)
            .borderRadius(6)
            .visibility(this.isSendFlag?Visibility.Visible:Visibility.None)
            .onClick(()=>{
              if(this.inputMessage!=""){
                this.chatMessageList.push({
                  id:this.messageId++,
                  img:$r('app.media.icon_head_girl'),
                  content:this.inputMessage,
                  category:1
                })
                this.flag=true;

                this.inputMessage="";
              }
              setTimeout(()=>{
                this.chatMessageList.push({
                  id:this.messageId++,
                  img:$r('app.media.icon_head_boy'),
                  content:"很高兴认识你",
                  category:0
                })
              },500)
            })
        }
      }.id('bottomControl')
      .backgroundColor("#ffddd9d9")
      .alignRules({
        bottom:{'anchor':"__container__",'align':VerticalAlign.Bottom}
      })
      .width("100%")
      .height(50)
      .padding({
        left:20,
        right:20,
        top:10,
        bottom:10
      })

    }.width("100%")
  }


  @Builder
  private  leftLayout(userinfo:Messagedata|undefined,item:UserMessageBase){
    Row({space:15}){
      Image(userinfo?.headportraiturl)
        .width(30)
        .height(30)
      Text(item.content)
        .fontColor(Color.Black)
        .backgroundImage($r('app.media.bg_text_revice'))
        .backgroundImageSize({
          width:"100%",
          height:"100%"
        })
        .backgroundImageResizable({
          slice:{
            top:30,
            bottom:30,
            left:30,
            right:30
          }
        })
        .padding({
          left:20,
          right:20,
          top:10,
          bottom:10
        })
    }.width("100%")
    .height(60)


  }

  @Builder
  private  rightLayout(messagedata:Messagedata|undefined,item:UserMessageBase){
    ListItem(){
      Row({space:15}){
        Text(item.content)
          .fontColor(Color.Black)
          .backgroundImage($r('app.media.bg_text_send'))
          .backgroundImageSize({
            width:"100%",
            height:"100%"
          })
          .backgroundImageResizable({
            slice:{
              top:50,
              bottom:50,
              left:30,
              right:30
            }

          }).padding({
          left:20,
          right:20,
          top:10,
          bottom:10
        })

        Image($r('app.media.icon_head_default'))
          .width(30)
          .height(30)

      }.width("100%")
      .justifyContent(FlexAlign.End)
    }

  }



}

聊天页面通过listview的多布局实现通过消息类型来显示在左边布局还是右边布局.

网络请求工具类

import http from '@ohos.net.http';
import Logger from './Logger'
import Constants, { ContentType } from '../common/Constants';
import { connection } from '@kit.NetworkKit';
import { healthStore } from '@kit.HealthServiceKit';


export  function   httpRequestGet(url:string,params?:string){
  return httpRequest(url,http.RequestMethod.GET,params);
}
export  function   httpRequestPost(url:string,params?:string){

  return httpRequest(url,http.RequestMethod.POST,params);
}
function  httpRequest(url:string ,method:http.RequestMethod,params?:string):Promise<string>{
   let  httpRequest=http.createHttp();
   let responseResult=httpRequest.request(url,{
     method:method,
     readTimeout:Constants.HTTP_READ_TIMEOUT, //读取超时时间可选  默认 600000
     header:{
       'Content-Type':ContentType.JSON
     },
     connectTimeout:Constants.HTTP_READ_TIMEOUT, //连接超时时间  可选,默认为60000ms
     extraData:params // 请求参数

   });
   let getjson:string='';
   return responseResult.then((value:http.HttpResponse)=>{
      Logger.error("请求状态-- >"+value.responseCode);
      if(value.responseCode===200){
        Logger.error("请求成功");
        let result= `${value.result}`;
        Logger.error("请求返回数据",JSON.parse(result));
        getjson=result;
      }else{
        getjson='';
      }
     return getjson;
   }).catch(()=>{
      //httpRequest.off("headerReceive");
     httpRequest.destroy();
     return '';
   });
}

路由跳转携带对象

router.pushUrl({
  url:"pages/MessageListdetails",
  params:itemts
})

HR自动回复实现逻辑

setTimeout(()=>{
  this.chatMessageList.push({
    id:this.messageId++,
    img:$r('app.media.icon_head_boy'),
    content:"很高兴认识你",
    category:0
  })
},500)

消息列表model




/**
 *
 * 消息model
 *
 */

export  class  MessageModel{
  msg:string=""
  data:Array<Messagedata>=[]
  code:number=0
}

export  class Messagedata{
  id:string="";
  msg:string="";
  jobname:string="";
  companyname:string="";
  nickname:string="";
  headportraiturl:string="";




}

聊天信息model

export class UserMessageBase{
  id: number = 0;
  content: string = '';
  img: Resource | null = null;
  category: number = 0
}

最后总结:

整个案例实现通过请求网络接口数据显示我们和HR聊天的列表,然后点击后把聊天信息通过路由跳转携带到我们的聊天详情页面 之前有讲过路由跳转携带参数跟我们今天用法差不多,然后我们通过定时器来模拟HR的自动回复。今

团队介绍

团队介绍:作者: 坚果派-徐庆 坚果派由坚果等人创建,团队由12位华为HDE以及若干热爱鸿蒙的开发者和其他领域的三十余位万粉博主运营。专注于分享 HarmonyOS/OpenHarmony,ArkUI-X,元服务,仓颉,团队成员聚集在北京,上海,南京,深圳,广州,宁夏等地,目前已开发鸿蒙 原生应用,三方库60+,欢迎进行课程,项目等合作。

项目地址 :

码云: https://gitee.com/qiuyu123/messagedemo

收藏00

登录 后评论。没有帐号? 注册 一个。