【UniApp开发小程序】私聊功能uniapp界面实现 (买家、卖家 沟通商品信息)【后端基于若依管理系统开发】

文章目录

  • 效果显示
  • WebSocket连接
    • 使用全局变量
    • WebSocket连接细节
  • 最近和自己聊天的用户信息
    • 界面效果
    • 界面代码
      • 最近的聊天内容太长
      • 日期时间显示
      • 未读消息数量显示
  • 私聊界面
    • 界面展示
    • 代码实现
      • 英文长串不换行问题
      • 聊天区域自动滑动到底部
      • 键盘呼出,聊天区域收缩,聊天区域滑动到底部
      • 通知WebSocket服务器哪两个用户开始聊天

效果显示

在这里插入图片描述

WebSocket连接

使用全局变量

本小程序在用户浏览首页的时候创建WebSocket连接,并将连接获得的WebSocket对象存储到全局变量中,方便其他页面来使用WebSocket

首先在项目的main.js文件中声明全局变量socket

在这里插入图片描述

Vue.prototype.$socket = null

对全局变量进行赋值

Vue.prototype.$socket = this.$socket;

后续如果需要使用全局变量,直接使用this.$socket即可

WebSocket连接细节

下面的代码中有一个headbeat方法,该方法主要用来定时给WebSocket服务器发送一个信号,告诉WebSocket服务器当前客户端还处于连接状态。当心跳停止的时候(比如客户端断网),后端服务就会将用户信息从连接中移除

/*** 创建websocket连接*/
initWebsocket() {// console.log("this.socket:" + this.$socket)if (this.$socket == null || this.$socket.readyState != 1) {this.$socket = uni.connectSocket({url: "ws://10.23.17.146:8085/websocket/" + uni.getStorageSync("curUser").userName,success(res) {console.log('WebSocket连接成功', res);},})// console.log("this.socket:" + this.$socket)// 监听WebSocket连接打开事件this.$socket.onOpen((res) => {console.log("websocket连接成功")Vue.prototype.$socket = this.$socket;// 连接成功,开启心跳this.headbeat();});// 连接异常this.$socket.onError((res) => {console.log("websocket连接出现异常");// 重连this.reconnect();})// 连接断开this.$socket.onClose((res) => {console.log("websocket连接关闭");// 重连this.reconnect();})}
},
/*** 重新连接*/
reconnect() {console.log("重连");// 防止重复连接if (this.lockReconnect == true) {return;}// 锁定,防止重复连接this.lockReconnect = true;this.initWebsocket();// 连接完成,设置为falsethis.lockReconnect = false;
},
// 开启心跳
headbeat() {console.log("websocket心跳");var that = this;setTimeout(function() {if (that.$socket.readyState == 1) {// websocket已经连接成功that.$socket.send({data: JSON.stringify({status: "ping"})})// 调用启动下一轮的心跳that.headbeat();} else {// websocket还没有连接成功,重连that.reconnect();}}, that.heartbeatTime);
},

最近和自己聊天的用户信息

界面效果

在这里插入图片描述

界面代码

<template><view class="container"><scroll-view @scrolltolower="getMoreChatUserVo"><view v-for="(chatUserVo,index) in chatUserVoList" :key="index" @click="trunToChat(chatUserVo)"><view style="height: 10px;"></view><view class="chatUserVoItem"><view style="display: flex;align-items: center;"><uni-badge class="uni-badge-left-margin" :text="chatUserVo.unReadChatNum" absolute="rightTop"size="small"><u--image :showLoading="true" :src="chatUserVo.userAvatar" width="50px" height="50px":fade="true" duration="450"><view slot="error" style="font-size: 24rpx;">加载失败</view></u--image></uni-badge></view><view style="margin: 10rpx;"></view><viewstyle="line-height: 20px;width: 100%;display: flex;justify-content: space-between;flex-direction: column;"><view style="display: flex;	justify-content: space-between;"><view><view class="nickname">{{chatUserVo.userNickname}}</view><view class="content">{{chatUserVo.lastChatContent}}</view></view><view class="date">{{formatDateToString(chatUserVo.lastChatDate)}}</view></view><!-- <view style="height: 10px;"></view> --><u-line></u-line></view></view></view></scroll-view></view>
</template><script>import {listChatUserVo} from "@/api/market/chat.js";import {listChat} from "@/api/market/chat.js"export default {data() {return {chatUserVoList: [],page: {pageNum: 1,pageSize: 15},}},created() {},methods: {/*** 滑动到底部,自动加载新一页的数据*/getMoreChatUserVo() {this.page.pageNum++;this.listChatUserVo();},listChatUserVo() {listChatUserVo(this.page).then(res => {// console.log("res:"+JSON.stringify(res.rows))// this.chatUserVoList = res.rows;for (var i = 0; i < res.rows.length; i++) {this.chatUserVoList.push(res.rows[i]);}})},/*** 格式化日期* @param {Object} date*/formatDateToString(dateStr) {let date = new Date(dateStr);// 今天的日期let curDate = new Date();if (date.getFullYear() == curDate.getFullYear() && date.getMonth() == curDate.getMonth() && date.getDate() == curDate.getDate()) {// 如果和今天的年月日都一样,那就只显示时间return this.toDoubleNum(date.getHours()) + ":" + this.toDoubleNum(date.getMinutes());} else {// 如果年份一样,就只显示月日return (curDate.getFullYear() == date.getFullYear() ? "" : (date.getFullYear() + "-")) + this.toDoubleNum((date.getMonth() + 1)) +"-" +this.toDoubleNum(date.getDate());}},/*** 如果传入的数字是两位数,直接返回;* 否则前面拼接一个0* @param {Object} num*/toDoubleNum(num) {if (num >= 10) {return num;} else {return "0" + num;}},/*** 转到私聊页面*/trunToChat(chatUserVo) {let you = {avatar: chatUserVo.userAvatar,nickname: chatUserVo.userNickname,username: chatUserVo.userName}uni.navigateTo({url: "/pages/chat/chat?you=" + encodeURIComponent(JSON.stringify(you))})},/*** 接收消息*/receiveMessage() {this.$socket.onMessage((response) => {// console.log("接收消息:" + response.data);let message = JSON.parse(response.data);// 收到消息,将未读消息数量加一for (var i = 0; i < this.chatUserVoList.length; i++) {if (this.chatUserVoList[i].userName == message.from) {this.chatUserVoList[i].unReadChatNum++;// 显示对方发送的最新消息listChat(message.from, {pageNum: 1,pageSize: 1}).then(res => {this.chatUserVoList[i].lastChatContent = res.rows[0].content});break;}}})},},onLoad(e) {this.receiveMessage();},onShow: function() {this.chatUserVoList = [];this.listChatUserVo();},}
</script><style lang="scss">.container {padding: 20rpx;.chatUserVoItem {display: flex;margin: 0 5px;.nickname {font-weight: 700;}.content {color: #A7A7A7;font-size: 14px;/* 让消息只显示1行,超出的文字内容使用...来代替 */overflow: hidden;text-overflow: ellipsis;display: -webkit-box;-webkit-line-clamp: 1;-webkit-box-orient: vertical;}.date {color: #A7A7A7;font-size: 12px;}}// .uni-badge-left-margin {// 	margin-left: 10px;// }}
</style>

最近的聊天内容太长

当最近的一条聊天内容太长的时候,页面不太美观,缺少整齐的感觉
在这里插入图片描述
解决的方式非常简单,只需要添加以下样式即可

.content {/* 让消息只显示1行,超出的文字内容使用...来代替 */overflow: hidden;text-overflow: ellipsis;display: -webkit-box;-webkit-line-clamp: 1;-webkit-box-orient: vertical;
}

在这里插入图片描述

日期时间显示

本文显示日期时间的时候,遵循以下原则:

  • 如果上次聊天时间的年月日和今天一致,那就只显示时间,即显示 时:分
  • 如果上次聊天时间的年份和今年一致,那就只显示月-日
  • 如果上面的条件都不满足,就显示年-月-日

在显示月、日、时、分的时候,如果数字是一位数字,就在前面补一个零,具体操作如方法toDoubleNum

/*** 格式化日期* @param {Object} date*/
formatDateToString(dateStr) {let date = new Date(dateStr);// 今天的日期let curDate = new Date();if (date.getFullYear() == curDate.getFullYear() && date.getMonth() == curDate.getMonth() && date.getDate() == curDate.getDate()) {// 如果和今天的年月日都一样,那就只显示时间return this.toDoubleNum(date.getHours()) + ":" + this.toDoubleNum(date.getMinutes());} else {// 如果年份一样,就只显示月日return (curDate.getFullYear() == date.getFullYear() ? "" : (date.getFullYear() + "-")) + this.toDoubleNum((date.getMonth() + 1)) +"-" +this.toDoubleNum(date.getDate());}
},
/**
* 如果传入的数字是两位数,直接返回;* 否则前面拼接一个0* @param {Object} num*/
toDoubleNum(num) {if (num >= 10) {return num;} else {return "0" + num;}
},

未读消息数量显示

未读消息数量显示使用角标组件,即uni-badge,使用该组件需要下载安装插件,下载链接,下载之前需要看广告,哈哈哈,当然有钱可以不看

在这里插入图片描述
显示效果如下图
在这里插入图片描述

<uni-badge class="uni-badge-left-margin" :text="chatUserVo.unReadChatNum" absolute="rightTop"size="small"><u--image :showLoading="true" :src="chatUserVo.userAvatar" width="50px" height="50px":fade="true" duration="450"><view slot="error" style="font-size: 24rpx;">加载失败</view></u--image>
</uni-badge>

私聊界面

界面展示

【微信公众平台模拟的手机界面】
在这里插入图片描述
【手机端,键盘呼出之后的聊天区域】
在这里插入图片描述

代码实现

<template><view style="height:100vh;"><!-- @scrolltoupper:上滑到顶部执行事件,此处用来加载历史消息 --><!-- scroll-with-animation="true" 设置滚动条位置的时候使用动画过渡,让动作更加自然 --><scroll-view :scroll-into-view="scrollToView" scroll-y="true" class="messageListScrollView":style="{height:scrollViewHeight}" @scrolltoupper="getHistoryChat()":scroll-with-animation="!isFirstListChat" ref="chatScrollView"><view v-for="(message,index) in messageList" :key="message.id" :id="`message`+message.id"style="width: 750rpx;min-height: 60px;"><view style="height: 10px;"></view><view v-if="message.type==0" class="messageItemLeft"><view style="width: 8px;"></view><u--image :showLoading="true" :src="you.avatar" width="50px" height="50px" radius="3"></u--image><view style="width: 7px;"></view><view class="messageContent left">{{message.content}}</view></view><view v-if="message.type==1" class="messageItemRight"><view class="messageContent right">{{message.content}}</view><view style="width: 7px;"></view><u--image :showLoading="true" :src="me.avatar" width="50px" height="50px" radius="3"></u--image><view style="width: 8px;"></view></view></view></scroll-view><view class="messageSend"><view class="messageInput"><u--textarea v-model="messageInput" placeholder="请输入消息内容" autoHeight></u--textarea></view><view style="width:5px"></view><view class="commmitButton" @click="send()">发 送</view></view></view></template><script>import {getUserProfileVo} from "@/api/user";import {listChat} from "@/api/market/chat.js"let socket;export default {data() {return {webSocketUrl: "",socket: null,messageInput: '',// 我自己的信息me: {},// 对方信息you: {},scrollViewHeight: undefined,messageList: [],// 底部滑动到哪里scrollToView: '',page: {pageNum: 1,pageSize: 15},isFirstListChat: true,loadHistory: false,// 消息总条数total: 0,}},created() {this.me = uni.getStorageSync("curUser");},beforeDestroy() {console.log("执行销毁方法");this.endChat();},onLoad(e) {// 设置初始高度this.scrollViewHeight = `calc(100vh - 20px - 44px)`;this.you = JSON.parse(decodeURIComponent(e.you));uni.setNavigationBarTitle({title: this.you.nickname,})this.startChat();this.listChat();this.receiveMessage();},onReady() {// 监听键盘高度变化,以便设置输入框的高度uni.onKeyboardHeightChange(res => {let keyBoardHeight = res.height;console.log("keyBoardHeight:" + keyBoardHeight);this.scrollViewHeight = `calc(100vh - 20px - 44px - ${keyBoardHeight}px)`;this.scrollToView = '';setTimeout(() => {this.scrollToView = 'message' + this.messageList[this.messageList.length - 1].id;}, 150)})},methods: {/*** 发送消息*/send() {if (this.messageInput != '') {let message = {from: this.me.userName,to: this.you.username,text: this.messageInput}// console.log("this.socket.send:" + this.$socket)// 将组装好的json发送给服务端,由服务端进行转发this.$socket.send({data: JSON.stringify(message)});this.total++;let newMessage = {// code: this.messageList.length,type: 1,content: this.messageInput};this.messageList.push(newMessage);this.messageInput = '';this.toBottom();}},/*** 开始聊天*/startChat() {let message = {from: this.me.userName,to: this.you.username,text: "",status: "start"}// 告诉服务端要开始聊天了this.$socket.send({data: JSON.stringify(message)});},/*** 结束聊天*/endChat() {let message = {from: this.me.userName,to: this.you.username,text: "",status: "end"}// 告诉服务端要结束聊天了this.$socket.send({data: JSON.stringify(message)});},/*** 接收消息*/receiveMessage() {this.$socket.onMessage((response) => {// console.log("接收消息:" + response.data);let message = JSON.parse(response.data);let newMessage = {// code: this.messageList.length,type: 0,content: message.text};this.messageList.push(newMessage);this.total++;// 让scroll-view自动滚动到最新的数据那里// this.$nextTick(() => {// 	// 滑动到聊天区域最底部// 	this.scrollToView = 'message' + this.messageList[this// 		.messageList.length - 1].id;// });this.toBottom();})},/*** 查询对方和自己最近的聊天数据*/listChat() {return new Promise((resolve, reject) => {listChat(this.you.username, this.page).then(res => {for (var i = 0; i < res.rows.length; i++) {this.total = res.total;if (res.rows[i].fromWho == this.me.userName) {res.rows[i].type = 1;} else {res.rows[i].type = 0;}// 将消息放到数组的首位this.messageList.unshift(res.rows[i]);}if (this.isFirstListChat == true) {// this.$nextTick(function() {// 	// 滑动到聊天区域最底部// 	this.scrollToView = 'message' + this.messageList[this// 		.messageList.length - 1].id;// })this.toBottom();this.isFirstListChat = false;}resolve();})})},/*** 滑到最顶端,分页加一,拉取更早的数据*/getHistoryChat() {// console.log("获取历史消息")this.loadHistory = true;if (this.messageList.length < this.total) {// 当目前的消息条数小于消息总量的时候,才去查历史消息this.page.pageNum++;this.listChat().then(() => {})}},/*** 滑动到聊天区域最底部*/toBottom() {// 让scroll-view自动滚动到最新的数据那里this.scrollToView = '';setTimeout(() => {// 滑动到聊天区域最底部this.scrollToView = 'message' + this.messageList[this.messageList.length - 1].id;}, 150)}}}
</script><style lang="scss">.messageListScrollView {background: #F5F5F5;overflow: auto;.messageItemLeft {display: flex;align-items: flex-start;justify-content: flex-start;.messageContent {max-width: calc(750rpx - 10px - 50px - 15px - 10px - 50px - 15px);padding: 10px;// margin-top: 10px;border-radius: 7px;font-family: sans-serif;// padding: 10px;// 让view只包裹文字width: auto;// display: inline-block !important;// display: inline;// 解决英文字符串、数字不换行的问题word-break: break-all;word-wrap: break-word;}}.messageItemRight {display: flex;align-items: flex-start;justify-content: flex-end;.messageContent {max-width: calc(750rpx - 10px - 50px - 15px - 10px - 50px - 15px);padding: 10px;// margin-top: 10px;border-radius: 7px;font-family: sans-serif;// padding: 10px;// 让view只包裹文字width: auto;// display: inline-block !important;// display: inline;// 解决长英文字符串、数字不换行的问题word-wrap: break-word;}}.right {background-color: #94EA68;}.left {background-color: #ffffff;}}.messageSend {display: flex;background: #ffffff;padding-top: 5px;padding-bottom: 15px;.messageInput {border: 1px #EBEDF0 solid;border-radius: 5px;width: calc(750rpx - 65px);margin-left: 5px;}.commmitButton {height: 38px;border-radius: 5px;width: 50px;display: flex;align-items: center;justify-content: center;color: #ffffff;background: #3C9CFF;}}
</style>

英文长串不换行问题

在这里插入图片描述

这个问题属于是整串英文被以为是一个单词了,所以没有换行,看下面的句子,英文单词可以比较短的,所以会自动换行
在这里插入图片描述

解决这个问题只需要添加下面的css即可

// 解决长英文字符串、数字不换行的问题
word-wrap: break-word;

下面是添加之后的效果

在这里插入图片描述

聊天区域自动滑动到底部

在聊天的时候,无论是发送一条新的消息,还是接收到一条新的消息,聊天区域都需要自动滑动到最新的消息那里。本文使用scroll-view组件来包裹显示聊天消息,在scroll-view组件中,可以通过给scroll-into-view属性赋值来指定聊天区域所显示到的位置。使用时需要注意如下问题:

  • 需要先给每一条消息设置一个id属性,id属性存储的内容不能以数字开头,因此本文在id之间拼接了一个字符串’message’
  • scroll-view需要被设置好高度,本文通过绑定一个变量来设置高度,如:style="{height:scrollViewHeight}",因为手机端使用小程序打字时键盘呼出会影响聊天区域的高度

在这里插入图片描述

后续通过给scrollToView设置不同的值即可控制聊天区域的滑动,比如每接收到一条新的消息,就调用toBottom方法,该方法通过设置scrollToView为'message' + this.messageList[this.messageList.length - 1].id将聊天区域滑动到最新的消息处。需要注意的是,在进行该值的设置之前,需要延迟一段时间,否则滑动可能不成功,本文延迟150ms,读者也可以探索不同的值,该值不能太大或者太小。

通过设置scroll-view的属性scroll-with-animation的值为true,可以让消息区域在滑动的时候使用动画过渡,这样滑动更加自然。

键盘呼出,聊天区域收缩,聊天区域滑动到底部

当键盘呼出时,需要将聊天区域的高度减去键盘的高度。同时将scrollToView赋值为最后一条消息的id。需要注意的是,在设置scrollToView之前,需要先将scrollToView设置为空字符串,否则滑动效果可能不成功

onReady() {// 监听键盘高度变化,以便设置输入框的高度uni.onKeyboardHeightChange(res => {let keyBoardHeight = res.height;console.log("keyBoardHeight:" + keyBoardHeight);this.scrollViewHeight = `calc(100vh - 20px - 44px - ${keyBoardHeight}px)`;this.scrollToView = '';setTimeout(() => {this.scrollToView = 'message' + this.messageList[this.messageList.length - 1].id;}, 150)})
},

通知WebSocket服务器哪两个用户开始聊天

为了便于后端在存储聊天数据的时候辨别消息是否为已读状态。比如,在小王开始聊天之前,需要先告诉后端:“小王要开始和小明聊天了”,如果正好小明也告诉后端:“我要和小王聊天了”,那小王发出去的消息就会被设置为已读状态,因为他们两个此时此刻正在同时和对方聊天,那小王发出去的消息就默认被小明看到了,因此设置为已读状态

/**
* 开始聊天
*/
startChat() {let message = {from: this.me.userName,to: this.you.username,text: "",status: "start"}// 告诉服务端要开始聊天了this.$socket.send({data: JSON.stringify(message)});
},
/*** 结束聊天*/
endChat() {let message = {from: this.me.userName,to: this.you.username,text: "",status: "end"}// 告诉服务端要结束聊天了this.$socket.send({data: JSON.stringify(message)});
},

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/105939.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

lnmp架构-nginx

1 Nginx服务的部署 前面高可用负载均衡做流量均摊只是用到 iso 前四层 下面针对某个请求 在七层模型 上做 apache也是可以的 但是 apache一般吞吐性能没有nigix 强 nigix可以做负载均衡器 也可以做常规的web服务器 作为网站的发布服务器 官网下载好之后 直接拖到软件中 源…

Qt 自定义提示框 右下角冒泡

网页右下角上经常会出现一些提示性的信息&#xff0c;B/S有的东西&#xff0c;C/S当然也可以有&#xff0c;就像QQ的消息提示一样&#xff01; 实现一个类似的东西并不困难&#xff0c;只要想明白原理实现起来就很简单了&#xff01; 实现原理&#xff1a; &#xff08;1&#…

yo!这里是Linux权限入门理解

目录 前言 权限概念 权限管理 分类 1.用户 2.文件&&目录 表示 设置 1.chmod指令 2.chown指令 3.chgrp指令 4.umask指令 粘滞位 后记 前言 对于Linux基本指令&#xff0c;基本上就是操作文件或者目录&#xff0c;但是&#xff0c;是谁可以操作文件或目录&…

Python requests实现图片上传接口自动化测试

最近帮别人写个小需求&#xff0c;需要本地自动化截图&#xff0c;然后图片自动化上传到又拍云&#xff0c;实现自动截图非常简单&#xff0c;在这里就不详细介绍了&#xff0c;主要和大家写下&#xff0c;如何通过Pythonrequests实现上传本地图片到又拍云服务器。 话不多说&a…

政府网站定期巡检:构建高效、安全与透明的数字政务

在数字时代&#xff0c;政府网站已不仅仅是一个信息发布窗口&#xff0c;更是政府与公众互动的桥梁、政务服务的主要渠道以及数字化治理的重要平台。因此&#xff0c;确保政府网站的高效运行、信息安全与透明公开就显得尤为重要。在此背景下&#xff0c;定期的网站巡检与巡查成…

【自适应稀疏度量方法和RQAM】疏度测量、RQAM特征、AWSPT和基于AWSPT的稀疏度测量研究(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

Linux:基础指令

目录 Linux的基础指令 1.ls指令 2.pwd指令 3.cd指令 4.touch指令 5.mkdir指令 6.rmdir指令和rm指令 7.man指令&#xff08;重要&#xff09; 8.cp指令&#xff08;重要&#xff09; 9.mv指令&#xff08;重要&#xff09; 10.cat指令 11.nano指令 12.more指令 13.…

欢迎使用Markdown编辑器

这里写自定义目录标题 欢迎使用Markdown编辑器新的改变功能快捷键合理的创建标题&#xff0c;有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants 创建一个自定义列表如何创建一个…

基于Java+SpringBoot+Vue前后端分离学生干部管理系统设计和实现

博主介绍&#xff1a;✌全网粉丝30W,csdn特邀作者、博客专家、CSDN新星计划导师、Java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专…

Mainline Linux 和 U-Boot编译

By Toradex胡珊逢 Toradex 自从 Linux BSP v6 开始在使用 32位处理器的 Arm 模块如 iMX6、iMX6ULL、iMX7 上提供 mainline/upstream kernel &#xff0c;部分 64位处理器模块如 Verdin iMX8M Mini/Plus 也提供实验性支持。文章将以季度发布版本 Linux BSP V6.3.0 为例介绍如何下…

ARM(实验二)

uart4.h #ifndef __H__ #define __H__#include "stm32mp1xx_rcc.h" #include "stm32mp1xx_gpio.h" #include "stm32mp1xx_uart.h"//RCC/GPIO/UART4章节初始化 void hal_uart4_init();//发送一个字符函数 void hal_put_char(const char str);//发…

IT运维软件的费用是多少?

正常一套IT运维软件费用一般在5千-50万之间不等&#xff0c;而且分为一次性付费或年付费模式&#xff0c;付费方式导致的价格也不同。 正常情况下IT运维软件的具体价格&#xff0c;是需要根据企业的实际需求来进行综合评估&#xff0c;一般来说&#xff0c;影响具体价格费用有以…

MongoDB Long 类型 shell 查询

场景 1、某数据ID为Long类型&#xff0c;JAVA 定义实体类 Id Long id 2、查询数据库&#xff0c;此数据存在 3、使用 shell 查询&#xff0c;查不到数据 4、JAVA代码查询Query.query 不受任何影响 分析 尝试解决&#xff08;一&#xff09; long 在 mongo中为 int64 类型…

命令全局安装 ts

1.全局安装 typeScript编译 npm install -g typescript2.查看版本 tsc-v安装成功的画面

电脑显示“Operating System not found”该怎么办?

“Operating System not found”是一种常见的电脑错误提示&#xff0c;这类错误会导致你无法成功启动Windows。那么电脑显示“Operating System not found”该怎么办呢&#xff1f; 方法1. 检查硬盘 首先&#xff0c;您可以测试硬盘是否存在问题。为此&#xff0c;您可以采取以…

什么是住宅ip,静态和动态怎么选?

上文我们介绍了数据中心代理&#xff0c;这次我们来介绍下住宅代理ip&#xff0c;住宅代理ip分类两种类型&#xff1a;静态住宅代理和动态住宅代理&#xff0c;他们有什么区别又能用在什么场景呢&#xff1f;我们先从他们是如何运作开始。 一、什么是住宅代理ip isp住宅代理i…

Dev-C++ 下载和安装

TOC 1. 下载 Dev-C 访问 sourceforge 网站&#xff0c;然后单击 Download&#xff0c; 2. 安装 Dev-C 双击下载的安装文件进行安装。 3. 在线环境 https://cpp.sh/ 完结&#xff01;

构建高性能云原生大数据处理平台:融合人工智能优化数据分析流程

文章目录 架构要点优势与应用案例研究&#xff1a;基于云原生大数据平台的智能营销分析未来展望&#xff1a;大数据与人工智能的融合结论 &#x1f388;个人主页&#xff1a;程序员 小侯 &#x1f390;CSDN新晋作者 &#x1f389;欢迎 &#x1f44d;点赞✍评论⭐收藏 ✨收录专栏…

GE 8920-PS-DC安全模块

安全控制&#xff1a; 这个安全模块通常用于实现工业自动化系统中的安全控制功能。它可以监测各种安全参数&#xff0c;如机器运动、温度、压力等&#xff0c;以确保系统在安全范围内运行。 PLC兼容性&#xff1a; 通常&#xff0c;这种安全模块可以与可编程逻辑控制器&#x…

【业务功能篇81】微服务SpringCloud-ElasticSearch-Kibanan-docke安装-入门实战

ElasticSearch 一、ElasticSearch概述 1.ElasticSearch介绍 ES 是一个开源的高扩展的分布式全文搜索引擎&#xff0c;是整个Elastic Stack技术栈的核心。它可以近乎实时的存储&#xff0c;检索数据&#xff1b;本身扩展性很好&#xff0c;可以扩展到上百台服务器&#xff0c;…