本文主要是介绍No.1-南波兔 冲刺随笔Day 6,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
目录
一、项目燃尽图
二、冲刺内容
三、相关代码
四、程序的最新运行效果展示
五、会议照片
这个作业属于哪个课程 | 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 = trueobj.faFlag = false}else {obj.huiFlag = falseobj.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;
}
四、程序的最新运行效果展示
五、会议照片
这篇关于No.1-南波兔 冲刺随笔Day 6的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!