No.1-南波兔 冲刺随笔Day 6

No.1-南波兔 团队 2023-11-17 21:53:37

 

目录

 

一、项目燃尽图

二、冲刺内容

三、相关代码

四、程序的最新运行效果展示

五、会议照片


 

 

这个作业属于哪个课程2023-计算机学院-软件工程
这个作业要求在哪里团队作业——站立式会议+alpha冲刺
这个作业的目标No.1-南波兔 冲刺随笔 Day6
团队名称No.1-南波兔
团队项目                小福出行
团队置顶集合随笔链接No.1-南波兔——Alpha 冲刺随笔置顶

 

项目燃尽图

 

二、冲刺内容

成员       任务存在的问题/遇到的困难从现在到明天站立式会议的安排心得体会
102101108徐悦昕优化功能,开发聊天页面后端,设计相关接口对于框架并不是很熟悉,刚开始开发的时候产生了许多bug继续完善相关内容还需要继续学习
102101206陈妍完善帖子页面的部分后端代码,优化功能继续完善帖子页面的相关后端代码在项目开发过程中,我们要注重良好的前后端交流。
102101310黃心怡整合代码代码不够规范继续完善相关内容代码规范很重要  
102101602杜雅婷完善页面,测试相关功能发现bug,进行处理继续完善相关内容加强沟通,和组员多交流代码中的问题
102101603李欣妍完善广场及编辑帖子页面完善广场及编辑帖子页面继续加油
102101604杨嘉鑫设计聊天前端页面,开发我的管理模块继续完善聊天前端页面,开发我的管理模块-我的拼车前端页面良好的代码质量和规范对项目的成功至关重要
102101605林盈盈编写接口,完善数据库设计交互继续完善相关内容和组员的沟通很重要
102101607郭紫莹 设计用户界面相关接口,实现部分功能调试继续学习,完善相关内容在前后端交互的过程中,数据的传输和处理是非常重要的。需要注意数据的格式、编码问题
102101622何卓穎完善修改密码前端页面 继续完善完善登录注册及修改密码前端页面 项目的编写需要尽早开始,留足时间做测试、优化和修改

三、相关代码

消息界面与我的管理模块

前端:

<template>
  <view class="chat-page">
    <scroll-view class="chat-list" scroll-y>
      <view  v-for="(message, index) in messages" :key="index">
         <view class="messageLeft" v-show="message.huiFlag"> {{ message.msg }} </view>
         <view class="messageRight" v-show="message.faFlag"> {{ message.msg }} </view>
      </view>
    </scroll-view>

    <view class="text-input-wrapper">
      <input class="text-input" type="text" v-model="inputText" placeholder="请输入消息内容" />
      <view class="send-button" @click="sendMessage">发送</view>
    </view>
  </view>
</template>

<script>


import mqtt from "mqtt";
import {MQTT_IP, MQTT_OPTIONS} from "@/common/mqtt";

let client;
export default {
  data() {
    return {
      topic : "PCAR-CHAT",
      userId : "",
      messages: [{
          msg : "",
          huiFlag : false,
          faFlag : false
        }
      ],
      inputText: ''
    };
  },
  onLoad() {
    this.userId = this.$route.query.id;
    if(client == null){
      this.connect();
    }
    this.init()
  },
  methods: {
    init(){
      this.$u.api.chatList({
        toUserId : this.userId,
        fromUserId : localStorage.getItem("tokenId")
      }).then(res =>{
        if(res){
          this.messages = [];
          for (const resKey of res) {
            let obj={};
            obj.msg = resKey.msg;
            if(resKey.toUserId == localStorage.getItem("tokenId")){
              obj.huiFlag = true
              obj.faFlag = false
            }else {
              obj.huiFlag = false
              obj.faFlag = true
            }
            this.messages.push(obj);
          }
        }
      })
    },
    connect() {
      MQTT_OPTIONS.clientId = "PCAR_CHAT_"+localStorage.getItem("tokenId")
      const that = this;
      client = mqtt.connect('ws://' + MQTT_IP, MQTT_OPTIONS);
      client.on('connect', function() {
        console.log('连接成功')
        client.subscribe(that.topic+"-"+that.userId,function (err){
          if (!err) {
            console.log(that.topic+"-"+that.userId+'订阅成功')
          }
        })
      }).on('reconnect', function(error) {
        console.log('正在重连...', that.topic)
      }).on('error', function(error) {
        console.log('连接失败...', error)
      }).on('end', function() {
        console.log('连接断开')
      }).on('message', function(topic, message) {
       // if(topic != (that.topic+"-"+that.userId)){
          that.init();
          console.log(topic+'接收推送信息:', message.toString())
       // }
      })

    },

    sendMessage() {
      if (this.inputText === '') {
        return; // 如果输入内容为空,则不发送
      }


      this.$u.api.addChat({
        toUserId : this.userId,
        fromUserId : localStorage.getItem("tokenId"),
        msg : this.inputText
      }).then(res =>{
        if(res){
          this.init();
          this.inputText = '';
        }
      })



      // this.messages.push({
      //   huiFlag : false,
      //   faFlag : true,
      //   fromUserId : localStorage.getItem("tokenId"),
      //   toUserId : this.userId,
      //   msg: this.inputText
      // });


    }
  }
};
</script>

<style>
.chat-page {
  margin-top: 10px;
  display: flex;
  flex-direction: column;
  height: 90vh;
}

.chat-list {
  flex: 1;
  padding: 10px;
}

.messageLeft {
  margin-bottom: 10px;
  padding: 10px;
  background-color: #e7e7e7;
  border-radius: 5px;
}
.messageRight{
  margin-bottom: 10px;
  margin-right: 10px;
  padding: 10px;
  background-color: #e7e7e7;
  border-radius: 5px;
  text-align: right
}

.text-input-wrapper {
  display: flex;
  align-items: center;
  padding: 10px;
  background-color: #f5f5f5;
}

.text-input {
  flex: 1;
  height: 40px;
  margin-right: 10px;
  padding: 5px 10px;
  background-color: #ffffff;
  border-radius: 4px;
  border: 1px solid #ccc;
}

.send-button {
  width: 60px;
  height: 40px;
  line-height: 40px;
  text-align: center;
  background-color: #007aff;
  color: #ffffff;
  border-radius: 4px;
}
</style>

 

<template>
  <view>

    <view class="my-page">
      <image class="avatar" src="" />
      <text class="nickname">{{ nickname }} {{account}}</text>

      <navigator url="/pages/posts/addPosts" hover-class="navigator-hover">
        <view class="module">
          <text class="module-title">发起拼车</text>
        </view>
      </navigator>

      <navigator url="/pages/posts/myIndex" hover-class="navigator-hover">
        <view class="module">
          <text class="module-title">我的发帖</text>
        </view>
      </navigator>

      <navigator url="/pages/msg/index" hover-class="navigator-hover">
        <view class="module">
          <text class="module-title">我的消息</text>
        </view>
      </navigator>

      <navigator url="/pages/my/userInfo" hover-class="navigator-hover">
        <view class="module">
          <text class="module-title">我的资料</text>
        </view>
      </navigator>


      <button class="logout-btn" @click="logout">退出登录</button>
    </view>

    <Foot/>
  </view>
</template>

<script>
import Foot from "@/components/foot.vue";

export default {
  components: {
    Foot
  },
  data() {
    return {
      account: localStorage.getItem("token"),
      nickname: ""
    }
  },
  onLoad() {
    this.$u.api.userInfo({
      id : localStorage.getItem("tokenId")
    }).then(res => {
      if(res){
        this.nickname = res.nickname;
      }
    });
  },
  methods: {
    logout() {
       localStorage.removeItem("token");
       localStorage.removeItem("tokenId");
      uni.redirectTo({
        url: '/pages/index/index'
      })
    }
  }
}
</script>

<style scoped>
.my-page {
  padding: 20px;
  font-size: 16px;
}

.avatar {
  width: 100px;
  height: 100px;
  border-radius: 50%;
}

.nickname {
  font-size: 20px;
  margin-top: 10px;
}

.module {
  margin-top: 20px;
  border-bottom: 1px solid #ccc;
  padding-bottom: 20px;
}

.module-title {
  font-size: 18px;
  font-weight: bold;
  margin-bottom: 10px;
}


.logout-btn {
  width: 100%;
  height: 40px;
  background: #ff4d4f;
  border: none;
  border-radius: 5px;
  color: #fff;
  font-size: 16px;
  margin-top: 20px;
}
</style>

后端

package com.han.app.controller;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.han.app.config.Result;
import com.han.app.controller.dto.ChatDto;
import com.han.app.controller.vo.ChatInfoVo;
import com.han.app.entity.ChatInfo;
import com.han.app.entity.Post;
import com.han.app.entity.User;
import com.han.app.mqtt.MqttPushClient;
import com.han.app.service.ChatInfoService;
import com.han.app.service.UserService;
import lombok.Data;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.*;
import java.util.stream.Collectors;

@RestController
@RequestMapping("/Chat")
@RequiredArgsConstructor
public class ChatController {

    private final MqttPushClient mqttPushClient;
    private final ChatInfoService chatInfoService;
    private final UserService userService;

    @PostMapping("/SendMsg")
    public Result sendMsg(@RequestBody ChatInfo dto){
        dto.setFromToUserId(dto.getFromUserId()+"-"+dto.getToUserId());
        if(dto.getFromUserId() > dto.getToUserId()){
            dto.setFromToUserId(dto.getToUserId()+"-"+dto.getFromUserId());
        }
        dto.setAddTime(new Date());
        chatInfoService.save(dto);
        System.out.println("给  PCAR-CHAT-"+dto.getToUserId()+"  发送 "+dto.getMsg());
        mqttPushClient.publish("PCAR-CHAT-"+dto.getToUserId(),dto.getMsg());
        return Result.ok("ok");
    }


    @PostMapping("/ChatList")
    public Result chatList(@RequestBody ChatDto dto){
        String key = dto.getFromUserId()+"-"+dto.getToUserId();
        if(dto.getFromUserId() > dto.getToUserId()){
            key = (dto.getToUserId()+"-"+dto.getFromUserId());
        }
        LambdaQueryWrapper<ChatInfo> lqw = new LambdaQueryWrapper<>();
        lqw.eq(ChatInfo::getFromToUserId,key).orderByDesc(ChatInfo::getAddTime).last(" limit 10");
        List<ChatInfo> list = chatInfoService.list(lqw);
        List<ChatInfo> collect = list.stream().sorted(Comparator.comparing(ChatInfo::getId)).collect(Collectors.toList());
        return Result.ok(collect);
    }


    @PostMapping("/DeleteChat")
    public Result deleteChat(@RequestBody ChatDto dto){
        String key = dto.getFromUserId()+"-"+dto.getToUserId();
        if(dto.getFromUserId() > dto.getToUserId()){
            key = (dto.getToUserId()+"-"+dto.getFromUserId());
        }
        LambdaQueryWrapper<ChatInfo> lqw = new LambdaQueryWrapper<>();
        lqw.eq(ChatInfo::getFromToUserId,key);
        chatInfoService.remove(lqw);
        return Result.ok("ok");
    }



    @PostMapping("/ChatUserList")
    public Result chatUserList(@RequestBody ChatDto dto){
        LambdaQueryWrapper<ChatInfo> lqw = new LambdaQueryWrapper<>();
        lqw.like(ChatInfo::getFromToUserId,dto.getFromUserId()).groupBy(ChatInfo::getFromToUserId).orderByAsc(ChatInfo::getAddTime);
        List<ChatInfo> list = chatInfoService.list(lqw);
        ArrayList<ChatInfoVo> resList = new ArrayList<>();
        if(CollUtil.isNotEmpty(list)){
            HashSet<Integer> set = new HashSet<>();
            for (ChatInfo chatInfo : list) {
                set.add(chatInfo.getFromUserId());
                set.add(chatInfo.getToUserId());
            }

            LambdaQueryWrapper<User> userLqw = new LambdaQueryWrapper<>();
            userLqw.in(User::getId,set);
            List<User> userList = userService.list(userLqw);
            Map<Integer, String> collect = userList.stream().collect(Collectors.toMap(User::getId, User::getAccount));

            for (ChatInfo chatInfo : list) {
                ChatInfoVo vo = new ChatInfoVo();
                vo.setMsg(chatInfo.getMsg());
                if(NumberUtil.equals(chatInfo.getFromUserId(),dto.getFromUserId()) ){
                    vo.setUserName(collect.getOrDefault(chatInfo.getToUserId(),""));
                    vo.setUserId(chatInfo.getToUserId());
                }else {
                    vo.setUserName(collect.getOrDefault(chatInfo.getFromUserId(),""));
                    vo.setUserId(chatInfo.getFromUserId());
                }
                resList.add(vo);
            }
        }
        return Result.ok(resList);
    }
}
package com.han.app.entity;

import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import java.io.Serializable;
import java.util.Date;

import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;

/**
 * 
 * @TableName chat_info
 */
@TableName(value ="chat_info")
@Data
public class ChatInfo implements Serializable {
    /**
     * 
     */
    @TableId(type = IdType.AUTO)
    private Integer id;

    /**
     * 
     */
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private Date addTime;

    /**
     * 
     */
    private Integer fromUserId;

    /**
     * 
     */
    private Integer toUserId;

    /**
     * 
     */
    private String msg;

    /**
     * 
     */
    private String fromToUserId;

    @TableField(exist = false)
    private static final long serialVersionUID = 1L;
}

 

四、程序的最新运行效果展示

 

 

五、会议照片

 

...全文
10 回复 打赏 收藏 转发到动态 举报
写回复
用AI写文章
回复
切换为时间正序
请发表友善的回复…
发表回复

152

社区成员

发帖
与我相关
我的任务
社区描述
FZU-CS-SE
软件工程 高校
社区管理员
  • LinQF39
  • Jcandc
  • 助教-陈锦辉
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧