//php 后端
on('open', function (Swoole\WebSocket\Server $server, $request) {
//$server->push($request->fd, '欢迎进入我们的聊天室~');
});
//接收客户端发送的信息
//$frame 是 Swoole\WebSocket\Frame 对象,包含了客户端发来的数据帧信息
//$frame->fd 代表客户端的唯一标识 客户id
//$frame->data 代表客户端发送的消息
$server->on('message', function (Swoole\WebSocket\Server $server, $frame) {
//获取客户端发送的消息
$type = json_decode($frame->data,true);
if($type['type'] != 'active'){
$result['data'] = $frame->data;
$types = 1;
$framedata = json_decode($frame->data,true);
$openid = $framedata['openid'];
$endopenid = $framedata['endopenid'];
$imgtype = $framedata['imgtype'];
$url = 'http://www.xxx.com/';
$wxapp = '/app/index.php?i=2&t=0&v=1.01&from=wxapp&c=entry&a=wxapp';
// 会话列表创建会话接口
$socket_add = '&do=chat_socket_add&m=gc_school&';
//会话信息查询接口
$socket_find = '&do=chat_socket_find&m=gc_school&';
//用户openid 绑定会话 fd 接口
$user_fid = '&do=chat_user_find&m=gc_school&';
//存储消息记录
$socket_log = '&do=socket_log&m=gc_school&';
//重置fd为0
$socket_isfd = '&do=socket_isfd&m=gc_school&';
//查询对方的fd
$user_endfind = '&do=chat_user_endfind&m=gc_school&';
//查询用户信息
$Socket_users = '&do=Socket_users&m=gc_school&';
//如果不存在会话id 就去创建会话ID
// var_dump(
f
r
a
m
e
−
>
r
e
l
a
t
i
o
n
)
;
d
i
e
;
i
f
(
frame->relation);die; if(
frame−>relation);die;if(framedata[‘relation’]){
u
s
e
s
s
=
′
i
d
s
=
′
.
usess = 'ids='.
usess=′ids=′.framedata[‘relation’];
//如果存在会话id就去查询会话id的信息
$relation_url =
u
r
l
.
url.
url.wxapp.
s
o
c
k
e
t
f
i
n
d
.
socket_find.
socketfind.usess;
r
e
l
a
t
i
o
n
d
a
t
a
=
f
i
l
e
g
e
t
c
o
n
t
e
n
t
s
(
relationdata = file_get_contents(
relationdata=filegetcontents(relation_url); // 查询会话信息
}else{
u
s
e
s
s
=
′
o
p
e
n
i
d
=
′
.
usess = 'openid='.
usess=′openid=′.openid.‘&endopenid=’.$endopenid;
//拼接创建会话id信息并请求接口
$relation_url =
u
r
l
.
url.
url.wxapp.
s
o
c
k
e
t
a
d
d
.
socket_add.
socketadd.usess;
r
e
l
a
t
i
o
n
d
a
t
a
=
f
i
l
e
g
e
t
c
o
n
t
e
n
t
s
(
relationdata = file_get_contents(
relationdata=filegetcontents(relation_url); // 建立会话信息
}
j
s
o
n
f
d
=
j
s
o
n
d
e
c
o
d
e
(
json_fd = json_decode(
jsonfd=jsondecode(relationdata,true);
//openid 和 fd 一起查询,以当前的fd为准每次发消息
if($openid){
f
d
d
a
t
a
=
′
r
e
l
a
t
i
o
n
=
′
.
fddata = 'relation='.
fddata=′relation=′.json_fd[‘data’][‘id’].‘&fd=’.KaTeX parse error: Expected 'EOF', got '&' at position 12: frame->fd.'&̲openid='.openid;
$relationurlfd =
u
r
l
.
url.
url.wxapp.
u
s
e
r
f
i
d
.
user_fid.
userfid.fddata;
u
s
e
r
f
d
=
f
i
l
e
g
e
t
c
o
n
t
e
n
t
s
(
user_fd = file_get_contents(
userfd=filegetcontents(relationurlfd); // fd信息
}
//查询对方的fd
if($openid){
e
n
d
f
d
d
a
t
a
=
′
r
e
l
a
t
i
o
n
=
′
.
endfddata = 'relation='.
endfddata=′relation=′.json_fd[‘data’][‘id’].‘&fd=’.KaTeX parse error: Expected 'EOF', got '&' at position 12: frame->fd.'&̲openid='.openid;
$endrelationurlfd =
u
r
l
.
url.
url.wxapp.
u
s
e
r
e
n
d
f
i
n
d
.
user_endfind.
userendfind.endfddata;
e
n
d
u
s
e
r
f
d
=
f
i
l
e
g
e
t
c
o
n
t
e
n
t
s
(
enduser_fd = file_get_contents(
enduserfd=filegetcontents(endrelationurlfd); // fd信息
}
e
n
d
r
e
=
j
s
o
n
d
e
c
o
d
e
(
endre = json_decode(
endre=jsondecode(enduser_fd,true);
// file_get_contents($url);
// file_get_contents();
r
e
=
j
s
o
n
d
e
c
o
d
e
(
re = json_decode(
re=jsondecode(user_fd,true);
c
o
n
t
e
n
t
=
j
s
o
n
d
e
c
o
d
e
(
content = json_decode(
content=jsondecode(frame->data,true);
s
o
c
k
e
t
l
o
g
d
a
t
a
=
′
r
e
l
a
t
i
o
n
=
′
.
socket_logdata = 'relation='.
socketlogdata=′relation=′.json_fd[‘data’][‘id’].‘&content=’.KaTeX parse error: Expected 'EOF', got '&' at position 21: …nt['content'].'&̲type='.framedata[‘typess’].‘&openid=’.KaTeX parse error: Expected 'EOF', got '&' at position 9: openid.'&̲endopenid='.endopenid.‘&imgtype=’.
i
m
g
t
y
p
e
;
/
/
添
加
聊
天
记
录
i
f
(
imgtype; // 添加聊天记录 if(
imgtype;//添加聊天记录if(type[‘type’] != ‘active’){
$relationurl =
u
r
l
.
url.
url.wxapp.
s
o
c
k
e
t
l
o
g
.
socket_log.
socketlog.socket_logdata;
file_get_contents($relationurl); // fd
}
//查询用信息
$fds = 'openid='.$openid;
$users = $url.$wxapp.$Socket_users.$fds;
$udata = file_get_contents($users);
$uc = json_decode($udata,true);
$content['users'] = $uc['data'];
//
r
e
=
j
s
o
n
d
e
c
o
d
e
(
re = json_decode(
re=jsondecode(result[‘data’],true);
// $re[‘users’] = $content;
r
e
s
u
l
t
[
′
d
a
t
a
′
]
=
j
s
o
n
e
n
c
o
d
e
(
result['data'] = json_encode(
result[′data′]=jsonencode(content);
// $result[‘data’][‘users’] = $content;
$data = [
‘msg’ => ‘ *** 作成功’,
‘data’ => $result,
‘fd’ =>
f
r
a
m
e
−
>
f
d
,
′
e
r
r
o
r
c
o
d
e
′
=
>
0
,
′
t
y
p
e
s
′
=
>
frame->fd, 'error_code' => 0, 'types'=>
frame−>fd,′errorcode′=>0,′types′=>types,
‘imgtype’=>$imgtype,
];
// 检测fd 是否在线
if ($server->isEstablished($endre['data']['fd'])) {
$server->push($frame->fd, json_encode($data)); // 推给自己
$server->push($endre['data']['fd'], json_encode($data)); // 推给对方
}else{
$fds = 'ids='.$endre['data']['id'];
$isfd = $url.$wxapp.$socket_isfd.$fds;
file_get_contents($isfd); // 推送对方用户不在线重置fd为0
$server->push($frame->fd, json_encode($data)); // 推给自己
}
}else{
$types = 0;
$data = [
'msg' => ' *** 作成功',
'data' => [],
'fd' => $frame->fd,
'error_code' => 0,
'types'=>$types,
];
$server->push($frame->fd, json_encode($data)); // 定时任务推送自己防止断线
}
});
$server->on('close', function ($ser, $fd) {
echo "client {$fd} closed\n";
});
$server->start();
//具体消息接口这些东西需要自行写入目前逻辑仅代表个人观点 每次修改切记运行下php文件(不是访问切记)
宝塔反向代理
upstream websocket{
hash KaTeX parse error: Expected 'EOF', got '}' at position 87: …l_timeout=30s; }̲ server { list… https://$host$1 permanent;
}
server
{
# listen 80;
listen 443 ssl http2;
server_name socket.flyccampus.com;
index index.php index.html index.htm default.php default.htm default.html;
root /www/wwwroot/socket.flyccampus.com;
#SSL-START SSL相关配置,请勿删除或修改下一行带注释的404规则
#error_page 404/404.html;
ssl_certificate /www/server/panel/vhost/cert/socket.flyccampus.com/fullchain.pem;
ssl_certificate_key /www/server/panel/vhost/cert/socket.flyccampus.com/privkey.pem;
ssl_protocols TLSv1.1 TLSv1.2 TLSv1.3;
ssl_ciphers EECDH+CHACHA20:EECDH+CHACHA20-draft:EECDH+AES128:RSA+AES128:EECDH+AES256:RSA+AES256:EECDH+3DES:RSA+3DES:!MD5;
ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
add_header Strict-Transport-Security "max-age=31536000";
error_page 497 https://$host$request_uri;
#SSL-END
#ERROR-PAGE-START 错误页配置,可以注释、删除或修改
#error_page 404 /404.html;
#error_page 502 /502.html;
#ERROR-PAGE-END
#PHP-INFO-START PHP引用配置,可以注释或修改
#清理缓存规则
location / {
if (!-e KaTeX parse error: Expected '}', got '#' at position 26: …lename) { #̲一级目录 rewri… /index.php?s=$1 last;
break;
}
#wss配置
client_max_body_size 100m;
proxy_redirect off;
proxy_set_header Host $host;# http请求的主机域名
proxy_set_header X-Real-IP $remote_addr;# 远程真实IP地址
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;#反向代理之后转发之前的IP地址
proxy_read_timeout 604800s;#websocket心跳时间,默认是60s
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection “Upgrade”;
proxy_pass http://websocket;#反向代理转发地址
}
location ~ /purge(/.*) {
proxy_cache_purge cache_one $host$is_args$args;
#access_log /www/wwwlogs/socket.flyccampus.com_purge_cache.log;
}
#引用反向代理规则,注释后配置的反向代理将无效
include /www/server/panel/vhost/nginx/proxy/socket.flyccampus.com/*.conf;
include enable-php-00.conf;
#PHP-INFO-END
#REWRITE-START URL重写规则引用,修改后将导致面板设置的伪静态规则失效
include /www/server/panel/vhost/rewrite/socket.flyccampus.com.conf;
#REWRITE-END
#禁止访问的文件或目录
location ~ ^/(\.user.ini|\.htaccess|\.git|\.svn|\.project|LICENSE|README.md)
{
return 404;
}
#一键申请SSL证书验证目录相关设置
location ~ \.well-known{
allow all;
}
access_log /www/wwwlogs/socket.flyccampus.com.log;
error_log /www/wwwlogs/socket.flyccampus.com.error.log;
}
//前端代码
utils/config.js
module.exports = {
// 请求域名 格式: https://您的域名
HTTP_REQUEST_URL:‘http://socket.flyccampus.com’,
// Socket链接 暂不做配置
WSS_SERVER_URL:‘wss://xxx.com’,
//JWT token 名称
TOKEN_NAME:‘token’,
//用户注册id 名称
USER_ID:‘uid’,
//用户注册openid 名称
OPEN_ID:‘openid’,
// 以下配置非开发者,无需修改
// 请求头
HEADER:{
‘content-type’: ‘application/json’
},
}
utils/websocket.js
import {WSS_SERVER_URL} from “config.js”
//定时标识
let timing = false
function connect(user, func) {
wx.connectSocket({
url: ${WSS_SERVER_URL}?type=ask&fid=${user.id}&tid=100
,
header: { ‘content-type’: ‘application/json’ },
success: function () {
console.log(‘websocket连接成功~’)
},
fail: function () {
console.log(‘websocket连接失败~’)
}
})
wx.onSocketOpen(function (res) {
// wx.showToast({
// title: ‘websocket已开通~’,
// icon: “success”,
// duration: 2000
// })
//接受服务器消息
wx.onSocketMessage(func);//func回调可以拿到服务器返回的数据
});
//启动心跳包
linkWebsocketXin(40000, true)
wx.onSocketError(function (res) {
wx.showToast({
title: ‘websocket连接失败,请检查!’,
icon: “none”,
duration: 1000
})
})
}
//心跳包
function linkWebsocketXin(time, status) {
if (status == true) {
timing = setInterval(function () {
console.log(“当前心跳已重新连接”);
//循环执行代码
wx.sendSocketMessage({
data: JSON.stringify({
type: ‘active’,
}),
fail(res) {
// console.log(res)
}
});
}, time) //循环时间,注意不要超过1分钟
} else {
//关闭定时器
clearInterval(timing);
console.log(“当前心跳已关闭”);
}
}
//发送消息
function send(msg) {
//关闭心跳包定时器
linkWebsocketXin(40000, false)
wx.sendSocketMessage({
data: msg,
success:res=>{
//重启心跳包
linkWebsocketXin(40000, true)
}
});
}
module.exports = {
connect: connect,
send: send,
linkWebsocketXin:linkWebsocketXin
}
utils/util.js
const formatTime = date => {
const year = date.getFullYear()
const month = date.getMonth() + 1
const day = date.getDate()
const hour = date.getHours()
const minute = date.getMinutes()
const second = date.getSeconds()
return ${[year, month, day].map(formatNumber).join('/')} ${[hour, minute, second].map(formatNumber).join(':')}
}
const formatNumber = n => {
n = n.toString()
return n[1] ? n : 0${n}
}
module.exports = {
formatTime
}
/聊天列表
chat.js
const app = getApp()
var websocket = require(‘…/…/…/utils/websocket.js’);
var utils = require(‘…/…/…/utils/util.js’);
import {HTTP_REQUEST_URL, HEADER, USER_ID, OPEN_ID} from “…/…/…/utils/config.js”
Page({
/**
-
页面的初始数据
/
data: {
newslist: [],
userInfo: {},
scrollTop: 0,
increase: false,//图片添加区域隐藏
aniStyle: true,//动画效果
message: “”,
previewImgList: [],
relation:0, // 会话id
openid:‘’,
endopenid:‘’,
img:‘’,
imgtype:0,
toView:‘msg-0’,
top:0,
pages:1,
moban:‘’
},
/* -
生命周期函数–监听页面加载
*/
onLoad: function (options) {
this.getfd()
this.getmoban()
this.setData({
openid: wx.getStorageSync(‘openid’) // 本用户的openid
})
if(options.relation){ // 如果有会话id
this.setData({
relation: options.relation // 赋值会话id
})
this.getlist()
}
if(this.data.relation == 0){
this.setData({
endopenid: options.openid // 赋值需要聊天人的openid
})
this.getrelation()
}var that = this
if (app.globalData.userInfo) {
this.setData({
userInfo: app.globalData.userInfo
})
}
//调通接口
websocket.connect(this.data.userInfo, function (res) {
console.log(res,‘—’)
var list = []
list = that.data.newslist
var data = JSON.parse(res.data)
console.log(data.types,‘datatype----’)
if(data.types != 0) {
var datas = JSON.parse(data.data.data)
console.log(datas.content,‘data----’)
// list = datas.content
// } else {
list.push(datas)
}
that.setData({
newslist: list
})
// that.bottom()
})
},
// 页面卸载
onUnload() {
wx.closeSocket();
// wx.showToast({
// title: '连接已断开~',
// icon: "none",
// duration: 2000
// })
},
onPullDownRefresh(){
console.log(111)
this.getpagedata()
},
getrelation(){
var that = this;
app.util.request({
url: ‘entry/wxapp/socket_users_socket’,
data: {
openid:that.data.openid,
endopenid:that.data.endopenid
},
success(res) {
console.log(res.data.data,‘—lll—’)
if(res.data.errno == 0){
that.setData({
relation: res.data.data.id // 赋值会话id
})
that.getlist()
}
}
})
},
//加载历史消息
getpagedata(){
var that = this;
app.util.request({
url: ‘entry/wxapp/socket_user_log’,
data: {
openid:that.data.openid,
relation:that.data.relation,
page:that.data.pages
},
success(res) {
console.log(res.data.data,‘—lll—’)
that.setData({
newslist: [
…res.data.data,
…that.data.newslist
],
// newslist:res.data.data,
pages:that.data.pages+=1
})
// setTimeout(()=>{
// that.pageScrollToBottom();
// },500)
}
})
},
getfd(){
let msg = {
type:‘active’,//咨询
openid:this.data.openid,
endopenid:this.data.endopenid,
relation:this.data.relation // 会话id
};
websocket.send(JSON.stringify(msg))
},
//图片上传
choose()
{
wx.chooseImage({
count: 1,
sizeType: [‘original’, ‘compressed’], //可以指定是原图还是压缩图,默认二者都有
sourceType: [‘album’], //从相册选择
success: (res) => {
console.log(‘path’,res)
this.uploads(res)
}
})
},
uploads(res) {
var that = this;
wx.showLoading({
title: '上传中',
})
wx.uploadFile({
url: app.util.url() + 'c=entry&a=wxapp&do=ImgPost&m=gc_school', // 仅为示例,非真实的接口地址
filePath: res.tempFilePaths[0],
header: {
'content-type': 'application/x-www-form-urlencoded'
},
name: 'file',
success: (result) => {
wx.hideLoading()
var resu = JSON.parse(result.data)
console.log(resu)
if(resu.errno==0)
{
that.setData({
img:resu.data
})
that.setData({
imgtype:1
})
that.send()
}else{
wx.showToast({
title: resu.message,
icon:'none'
})
}
}
})
},
getlist(){
var that = this;
app.util.request({
url: ‘entry/wxapp/socket_user_log’,
data: {
openid:that.data.openid,
relation:that.data.relation,
page:that.data.pages
},
success(res) {
console.log(res.data.data,‘—lll—’)
that.setData({
newslist:res.data.data,
pages:2
})
setTimeout(()=>{
that.pageScrollToBottom();
},1000)
}
})
},
//图片预览
preview(e)
{
// this.setData({
// freshen:false
// })
console.log(e.currentTarget.dataset.index,‘—’)
var content = this.data.newslist[e.currentTarget.dataset.index].content;
console.log(content,‘—’)
wx.previewImage({
current:content,
urls: [content],
})
},
//事件处理函数
send: function () {
var flag = this
let uid = wx.getStorageSync(USER_ID)
if(this.data.img.trim() == “” && this.data.imgtype == 1){
wx.showToast({
title: ‘图片不能为空哦~’,
icon: “none”,
duration: 2000
})
return
}
if (this.data.message.trim() == "" && this.data.imgtype == 0) {
wx.showToast({
title: '消息不能为空哦~',
icon: "none",
duration: 2000
})
return
}
setTimeout(function () {
flag.setData({
increase: false
})
}, 1000)
if(flag.data.imgtype == 1){
var msg = {
content:this.data.img,
date:utils.formatTime(new Date()),
type:'ask',//咨询
fid:uid,
imgtype:1,
tid:100,
openid:this.data.openid,
endopenid:this.data.endopenid,
relation:this.data.relation // 会话id
};
}else{
var msg = {
content:this.data.message,
date:utils.formatTime(new Date()),
type:'ask',//咨询
fid:uid,
imgtype:0,
tid:100,
openid:this.data.openid,
endopenid:this.data.endopenid,
relation:this.data.relation // 会话id
};
}
flag.setData({
imgtype: 0
})
websocket.send(JSON.stringify(msg))
/*
websocket.send('{ "content": "' + this.data.message + '", "date": "' + utils.formatTime(new Date()) + '","type":"text", "nickName": "' + this.data.userInfo.nickName + '", "avatarUrl": "' + this.data.userInfo.avatarUrl + '" }')
*/
//发完消息值改为空
this.setData({
message: '',
})
setTimeout(()=>{
flag.pageScrollToBottom();
},1000)
// this.bottom()
},
//监听input值的改变
bindChange(res) {
this.setData({
message: res.detail.value
})
},
cleanInput() {
//button会自动清空,所以不能再次清空而是应该给他设置目前的input值
this.setData({
message: this.data.message
})
},
increase() {
this.setData({
increase: true,
aniStyle: true
})
},
//点击空白隐藏message下选框
outbtn() {
this.setData({
increase: false,
aniStyle: true
})
},
//发送图片
chooseImage() {
var that = this
wx.chooseImage({
count: 1, // 默认9
sizeType: [‘original’, ‘compressed’], // 可以指定是原图还是压缩图,默认二者都有
sourceType: [‘album’, ‘camera’], // 可以指定来源是相册还是相机,默认二者都有
success: function (res) {
// 返回选定照片的本地文件路径列表,tempFilePath可以作为img标签的src属性显示图片
var tempFilePaths = res.tempFilePaths
// console.log(tempFilePaths)
wx.uploadFile({
url: ‘wss://www.xxx.cn’, //服务器地址
filePath: tempFilePaths[0],
name: ‘file’,
headers: {
‘Content-Type’: ‘form-data’
},
success: function (res) {
if (res.data) {
that.setData({
increase: false
})
websocket.send(‘{“images”:"’ + res.data + ‘“,“date”:”’ + utils.formatTime(new Date()) + ‘“,“type”:“image”,“nickName”:”’ + that.data.userInfo.nickName + ‘“,“avatarUrl”:”’ + that.data.userInfo.avatarUrl + ‘"}’)
that.bottom()
}
}
})
}
})
},
//图片预览
previewImg(e) {
var that = this
//必须给对应的wxml的image标签设置data-set=“图片路径”,否则接收不到
var res = e.target.dataset.src
var list = this.data.previewImgList //页面的图片集合数组
//判断res在数组中是否存在,不存在则push到数组中, -1表示res不存在
if (list.indexOf(res) == -1) {
this.data.previewImgList.push(res)
}
wx.previewImage({
current: res, // 当前显示图片的http链接
urls: that.data.previewImgList // 需要预览的图片http链接列表
})
},
//聊天消息始终显示最底端
bottom: function () {
this.setData({
message: ‘’,
})
var query = wx.createSelectorQuery()
query.select(‘#flag’).boundingClientRect()
query.selectViewport().scrollOffset()
query.exec(function (res) {
wx.pageScrollTo({
scrollTop: res[0].bottom // #the-id节点的下边界坐标
})
res[1].scrollTop // 显示区域的竖直滚动位置
})
},
pageScrollToBottom: function() {
wx.createSelectorQuery().select(‘#flag’).boundingClientRect(function(rect){
// 使页面滚动到底部
wx.pageScrollTo({
scrollTop: rect.bottom
})
}).exec()
},
getmoban(){
var that = this;
app.util.request({
url: ‘entry/wxapp/template_comment’,
data: {
},
success(res) {
console.log(res.data.data,‘—lll—’)
if(res.data.errno == 0){
that.setData({
moban: res.data.data.template_comment // 赋值会话id
})
that.getlist()
}
}
})
},
ticing(){
console.log("d出框")
var self = this;
// self.chuo()
wx.getSetting({
withSubscriptions:true,
success (res) {
console.log("设置",res)
console.log(res.subscriptionsSetting)
}
})
wx.requestSubscribeMessage({
tmplIds: [self.data.moban], // 此处可填写多个模板 ID,但低版本微信不兼容只能授权一个
success (res) {
self.chuo()
}
})
},
chuo(){
var that = this;
app.util.request({
url: ‘entry/wxapp/tsuisong’,
data: {
‘openid’:that.data.openid,
‘relation’:that.data.relation
},
success(res) {
console.log(res.data.data,‘—lll—’)
if(res.data.errno == 0){
that.setData({
moban: res.data.data.template_comment // 赋值会话id
})
that.getlist()
}
}
})
}
})
chat.json
{
“usingComponents”: {},
“enablePullDownRefresh”: true
}
chat.wxml
返回聊天
{{item.date}}
发送
chat.wxss
/* pages/socks/socks.wxss */
page {
background-color: #f7f7f7;
height: 100%;
}
/* 聊天内容 /
.news {
padding-top: 30rpx;
text-align: center;
/ height:100%; */
box-sizing: border-box;
}
#flag {
margin-bottom: 100rpx;
height: 30rpx;
}
.chat-notice {
text-align: center;
font-size: 30rpx;
padding: 10rpx 0;
color: #666;
}
.historycon {
height: 100%;
width: 100%;
/* flex-direction: column; */
display: flex;
border-top: 0px;
}
/* 聊天 */
.chat-news {
width: 100%;
overflow: hidden;
}
.chat-news .my_right {
float: right;
/* right: 40rpx; */
padding: 10rpx 10rpx;
}
.chat-news .name {
margin-right: 10rpx;
}
.chat-news .you_left {
float: left;
/* left: 5rpx; */
padding: 10rpx 10rpx;
}
.selectImg {
display: inline-block;
width: 150rpx;
height: 150rpx;
margin-left: 50rpx;
}
.my_right .selectImg {
margin-right: 80rpx;
}
.new_img {
width: 60rpx;
height: 60rpx;
border-radius: 50%;
vertical-align: middle;
margin-right: 10rpx;
}
.new_txt {
max-width: 300rpx;
display: inline-block;
border-radius: 6rpx;
line-height: 60rpx;
background-color: #95d4ff;
padding: 5rpx 20rpx;
margin: 0 10rpx;
margin-left: 50rpx;
}
.my_right .new_txt {
margin-right: 60rpx;
}
.you {
background-color: lightgreen;
}
.my {
border-color: transparent transparent transparent #95d4ff;
}
.you {
border-color: transparent #95d4ff transparent transparent;
}
.hei {
margin-top: 50px;
height: 20rpx;
}
.history {
height: 100%;
margin-top: 15px;
padding: 10rpx;
font-size: 14px;
line-height: 40px;
word-break: break-all;
}
::-webkit-scrollbar {
width: 0;
height: 0;
color: transparent;
z-index: -1;
}
/* 信息输入区域 */
.message {
position: fixed;
bottom: 0;
width: 100%;
}
.sendMessage {
height: 80rpx;
padding: 10rpx 10rpx;
background-color: #fff;
border-top: 2rpx solid #eee;
border-bottom: 2rpx solid #eee;
/z-index: 3;/
}
.sendMessage input {
float: left;
height: 42px;
line-height: 100%;
border-bottom: 1rpx solid #ccc;
padding: 0 10rpx;
font-size: 35rpx;
color: #666;
}
.sendMessage button {
float: right;
font-size: 35rpx;
}
.sendMessage view {
display: inline-block;
width: 80rpx;
height: 80rpx;
line-height: 80rpx;
font-size: 60rpx;
text-align: center;
color: #999;
border: 1rpx solid #ccc;
border-radius: 50%;
margin-left: 10rpx;
}
.increased {
width: 100%;
/* height: 150rpx; */
padding: 40rpx 30rpx;
background-color: #fff;
}
.increased .image {
width: 100rpx;
height: 100rpx;
border: 3rpx solid #ccc;
line-height: 100rpx;
text-align: center;
border-radius: 8rpx;
font-size: 35rpx;
}
@keyframes slidedown {
from {
transform: translateY(0);
}
to {
transform: translateY(100%);
}
}
.slidedown {
animation: slidedown 0.5s linear;
}
.slideup {
animation: slideup 0.5s linear;
}
@keyframes slideup {
from {
transform: translateY(100%);
}
to {
transform: translateY(0);
}
}
前端采用colorui样式插件
完成示例图
///注意会话列表是自己写的
有啥问题加我微信或者QQ1446891130 看到有空给你说一下
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)