第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號安全,請及時綁定郵箱和手機立即綁定

開發(fā)體育賽事直播系統(tǒng):實現(xiàn)聊天交友的私聊功能技術(shù)實現(xiàn)全方案解析

標簽:
Android ThinkPHP

基于“东莞梦幻网络科技”体育赛事直播系统,展示前后端技术(PHP ThinkPHP + Vue.js + Android Java + iOS OC)实现的“用户与用户之间私聊”完整方案,包括功能描述、界面效果、技术实现、数据结构、接口设计及关键代码示例。
图片描述

一、私聊聊天功能模块包含:

1、用户与用户之间一对一私聊。
2、显示聊天记录、发送时间。
3、未读消息红点提示。
4、消息免打扰(可切换)。
5、聊天窗口置顶。
6、删除聊天、清空聊天记录。
7、发送消息、图片、表情等。

二、技术实现方案技术栈:

1、后端: PHP (ThinkPHP)
2、数据库: MySQL
3、实时通信: WebSocket + Redis(用于消息推送 & 未读消息计数)
4、前端(H5/PC): Vue.js
5、移动端: Java (Android)、Objective-C (iOS)

三、数据结构设计(MySQL)

1、用户表 users

CREATE TABLE `users` (
  `id` INT AUTO_INCREMENT PRIMARY KEY,
  `username` VARCHAR(50),
  `avatar` VARCHAR(255),
  `status` TINYINT DEFAULT 1
);

2、聊天消息表 chat_messages

CREATE TABLE `chat_messages` (
  `id` INT AUTO_INCREMENT PRIMARY KEY,
  `sender_id` INT,
  `receiver_id` INT,
  `content` TEXT,
  `send_time` DATETIME,
  `is_read` TINYINT DEFAULT 0,
  `is_deleted` TINYINT DEFAULT 0
);

3、聊天设置表 chat_settings

CREATE TABLE `chat_settings` (
  `id` INT AUTO_INCREMENT PRIMARY KEY,
  `user_id` INT,
  `chat_user_id` INT,
  `is_top` TINYINT DEFAULT 0,
  `no_disturb` TINYINT DEFAULT 0
);

四、后端接口设计(ThinkPHP

1、获取聊天列表

public function getChatList($userId)
{
    $chats = ChatModel::getChatListByUser($userId); // 关联读取chat_settings、last_message
    return json(['status' => 1, 'data' => $chats]);
}

2、获取聊天记录

public function getMessages(Request $request)
{
    $userId = $request->param('user_id');
    $peerId = $request->param('peer_id');
    $messages = ChatMessageModel::getMessages($userId, $peerId);
    return json(['status' => 1, 'data' => $messages]);
}

3、发送消息

public function sendMessage(Request $request)
{
    $data = $request->post();
    ChatMessageModel::send($data['sender_id'], $data['receiver_id'], $data['content']);
    // WebSocket推送
    WebSocketService::pushToUser($data['receiver_id'], $data);
    return json(['status' => 1, 'msg' => '发送成功']);
}

五、Vue 前端页面实现(关键代码)

1、聊天列表组件

<template>
  <div class="chat-list">
    <div v-for="chat in chatList" :key="chat.user_id" class="chat-item">
      <div class="avatar"><img :src="chat.avatar"></div>
      <div class="info">
        <div class="name">{{ chat.username }}</div>
        <div class="last-msg">{{ chat.last_message }}</div>
        <div class="time">{{ chat.last_time }}</div>
        <div v-if="chat.unread_count > 0" class="red-dot">{{ chat.unread_count }}</div>
      </div>
      <el-dropdown>
        <span class="el-dropdown-link">···</span>
        <el-dropdown-menu slot="dropdown">
          <el-dropdown-item @click.native="setTop(chat)">置顶聊天</el-dropdown-item>
          <el-dropdown-item @click.native="deleteChat(chat)">删除聊天</el-dropdown-item>
          <el-dropdown-item @click.native="clearMessages(chat)">清空消息</el-dropdown-item>
        </el-dropdown-menu>
      </el-dropdown>
    </div>
  </div>
</template>

2、聊天窗口

<template>
  <div class="chat-window">
    <div class="header">
      {{ targetUser.username }}
      <el-switch v-model="noDisturb" @change="toggleNoDisturb">消息免打扰</el-switch>
    </div>
    <div class="chat-content">
      <div v-for="msg in messages" :class="{'mine': msg.sender_id === userId}">
        <div class="message">{{ msg.content }}</div>
        <div class="time">{{ msg.send_time }}</div>
      </div>
    </div>
    <div class="input-area">
      <el-input v-model="input" @keyup.enter="sendMessage" placeholder="请输入消息..." />
    </div>
  </div>
</template>

六、Android Java 实现(部分代码)

public class ChatListActivity extends AppCompatActivity {
    private RecyclerView chatListView;
    private ChatListAdapter adapter;
    private List<ChatItem> chatItems = new ArrayList<>();
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_chat_list);
        
        chatListView = findViewById(R.id.chat_list_view);
        chatListView.setLayoutManager(new LinearLayoutManager(this));
        
        adapter = new ChatListAdapter(chatItems, new ChatListAdapter.OnItemClickListener() {
            @Override
            public void onItemClick(ChatItem item) {
                openChatWindow(item);
            }
            
            @Override
            public void onMoreClick(ChatItem item, View view) {
                showChatMenu(item, view);
            }
        });
        
        chatListView.setAdapter(adapter);
        
        loadChatList();
    }
    
    private void loadChatList() {
        // 调用API获取聊天列表
        ApiService.getInstance().getChatList(new ApiCallback<List<ChatItem>>() {
            @Override
            public void onSuccess(List<ChatItem> result) {
                chatItems.clear();
                chatItems.addAll(result);
                adapter.notifyDataSetChanged();
            }
            
            @Override
            public void onFailure(String error) {
                Toast.makeText(ChatListActivity.this, error, Toast.LENGTH_SHORT).show();
            }
        });
    }
    
    private void openChatWindow(ChatItem item) {
        Intent intent = new Intent(this, ChatActivity.class);
        intent.putExtra("chat_id", item.getId());
        intent.putExtra("user_name", item.getUsername());
        startActivity(intent);
    }
    
    private void showChatMenu(ChatItem item, View anchorView) {
        PopupMenu popupMenu = new PopupMenu(this, anchorView);
        popupMenu.getMenuInflater().inflate(R.menu.chat_item_menu, popupMenu.getMenu());
        
        // 设置菜单项状态
        popupMenu.getMenu().findItem(R.id.menu_top).setTitle(item.isTop() ? "取消置顶" : "置顶");
        popupMenu.getMenu().findItem(R.id.menu_mute).setTitle(item.isMuted() ? "关闭免打扰" : "消息免打扰");
        
        popupMenu.setOnMenuItemClickListener(menuItem -> {
            switch (menuItem.getItemId()) {
                case R.id.menu_top:
                    toggleTopChat(item, !item.isTop());
                    return true;
                case R.id.menu_mute:
                    toggleMuteChat(item, !item.isMuted());
                    return true;
                case R.id.menu_delete:
                    deleteChat(item);
                    return true;
                case R.id.menu_clear:
                    clearMessages(item);
                    return true;
                default:
                    return false;
            }
        });
        
        popupMenu.show();
    }
    
    private void toggleTopChat(ChatItem item, boolean isTop) {
        ApiService.getInstance().topChat(item.getId(), isTop, new ApiCallback<Void>() {
            @Override
            public void onSuccess(Void result) {
                loadChatList();
            }
            
            @Override
            public void onFailure(String error) {
                Toast.makeText(ChatListActivity.this, error, Toast.LENGTH_SHORT).show();
            }
        });
    }
    
    private void toggleMuteChat(ChatItem item, boolean isMuted) {
        ApiService.getInstance().muteChat(item.getId(), isMuted, new ApiCallback<Void>() {
            @Override
            public void onSuccess(Void result) {
                loadChatList();
            }
            
            @Override
            public void onFailure(String error) {
                Toast.makeText(ChatListActivity.this, error, Toast.LENGTH_SHORT).show();
            }
        });
    }
    
    private void deleteChat(ChatItem item) {
        new AlertDialog.Builder(this)
            .setTitle("删除聊天")
            .setMessage("确定要删除此聊天记录吗?")
            .setPositiveButton("确定", (dialog, which) -> {
                ApiService.getInstance().deleteChat(item.getId(), new ApiCallback<Void>() {
                    @Override
                    public void onSuccess(Void result) {
                        loadChatList();
                    }
                    
                    @Override
                    public void onFailure(String error) {
                        Toast.makeText(ChatListActivity.this, error, Toast.LENGTH_SHORT).show();
                    }
                });
            })
            .setNegativeButton("取消", null)
            .show();
    }
    
    private void clearMessages(ChatItem item) {
        new AlertDialog.Builder(this)
            .setTitle("清空消息")
            .setMessage("确定要清空此聊天中的所有消息吗?")
            .setPositiveButton("确定", (dialog, which) -> {
                ApiService.getInstance().clearMessages(item.getId(), new ApiCallback<Void>() {
                    @Override
                    public void onSuccess(Void result) {
                        loadChatList();
                    }
                    
                    @Override
                    public void onFailure(String error) {
                        Toast.makeText(ChatListActivity.this, error, Toast.LENGTH_SHORT).show();
                    }
                });
            })
            .setNegativeButton("取消", null)
            .show();
    }
}

七、iOS Objective-C 实现(部分代码)

#import "ChatListViewController.h"
#import "ChatItem.h"
#import "ChatViewController.h"
#import "ApiService.h"

@interface ChatListViewController ()

@end

@implementation ChatListViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    self.title = @"私聊";
    self.chatItems = [NSMutableArray array];
    
    // 设置表格视图
    self.tableView = [[UITableView alloc] initWithFrame:self.view.bounds style:UITableViewStylePlain];
    self.tableView.delegate = self;
    self.tableView.dataSource = self;
    [self.tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:@"ChatCell"];
    [self.view addSubview:self.tableView];
    
    // 加载数据
    [self loadChatList];
}

- (void)loadChatList {
    [[ApiService sharedInstance] getChatListWithCompletion:^(NSArray *chatItems, NSError *error) {
        if (error) {
            NSLog(@"Error loading chat list: %@", error.localizedDescription);
            return;
        }
        
        [self.chatItems removeAllObjects];
        [self.chatItems addObjectsFromArray:chatItems];
        [self.tableView reloadData];
    }];
}

#pragma mark - UITableViewDataSource

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    return self.chatItems.count;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"ChatCell" forIndexPath:indexPath];
    
    ChatItem *chatItem = self.chatItems[indexPath.row];
    
    // 配置单元格
    cell.textLabel.text = chatItem.username;
    cell.detailTextLabel.text = chatItem.lastMessage;
    cell.imageView.image = [UIImage imageNamed:chatItem.avatar ?: @"default_avatar"];
    
    // 显示未读消息数
    if (chatItem.unreadCount > 0) {
        UILabel *badge = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 20, 20)];
        badge.text = [NSString stringWithFormat:@"%ld", (long)chatItem.unreadCount];
        badge.textColor = [UIColor whiteColor];
        badge.backgroundColor = [UIColor redColor];
        badge.textAlignment = NSTextAlignmentCenter;
        badge.layer.cornerRadius = 10;
        badge.layer.masksToBounds = YES;
        cell.accessoryView = badge;
    } else {
        cell.accessoryView = nil;
    }
    
    // 置顶聊天背景色
    if (chatItem.isTop) {
        cell.backgroundColor = [UIColor colorWithRed:0.9 green:0.95 blue:1.0 alpha:1.0];
    } else {
        cell.backgroundColor = [UIColor whiteColor];
    }
    
    return cell;
}

#pragma mark - UITableViewDelegate

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    [tableView deselectRowAtIndexPath:indexPath animated:YES];
    
    ChatItem *chatItem = self.chatItems[indexPath.row];
    [self openChatWithChatItem:chatItem];
}

- (NSArray<UITableViewRowAction *> *)tableView:(UITableView *)tableView editActionsForRowAtIndexPath:(NSIndexPath *)indexPath {
    ChatItem *chatItem = self.chatItems[indexPath.row];
    
    // 置顶/取消置顶
    UITableViewRowAction *topAction = [UITableViewRowAction rowActionWithStyle:UITableViewRowActionStyleNormal 
        title:chatItem.isTop ? @"取消置顶" : @"置顶" 
        handler:^(UITableViewRowAction * _Nonnull action, NSIndexPath * _Nonnull indexPath) {
            [self toggleTopChat:chatItem];
        }];
    topAction.backgroundColor = [UIColor blueColor];
    
    // 删除
    UITableViewRowAction *deleteAction = [UITableViewRowAction rowActionWithStyle:UITableViewRowActionStyleDestructive 
        title:@"删除" 
        handler:^(UITableViewRowAction * _Nonnull action, NSIndexPath * _Nonnull indexPath) {
            [self deleteChat:chatItem];
        }];
    
    return @[deleteAction, topAction];
}

- (void)openChatWithChatItem:(ChatItem *)chatItem {
    ChatViewController *chatVC = [[ChatViewController alloc] init];
    chatVC.chatId = chatItem.chatId;
    chatVC.chatTitle = chatItem.username;
    [self.navigationController pushViewController:chatVC animated:YES];
}

- (void)toggleTopChat:(ChatItem *)chatItem {
    [[ApiService sharedInstance] topChat:chatItem.chatId isTop:!chatItem.isTop completion:^(BOOL success, NSError *error) {
        if (success) {
            [self loadChatList];
        } else {
            NSLog(@"Error toggling top chat: %@", error.localizedDescription);
        }
    }];
}

- (void)deleteChat:(ChatItem *)chatItem {
    UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"删除聊天" 
        message:@"确定要删除此聊天记录吗?" 
        preferredStyle:UIAlertControllerStyleAlert];
    
    [alert addAction:[UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:nil]];
    [alert addAction:[UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleDestructive handler:^(UIAlertAction * _Nonnull action) {
        [[ApiService sharedInstance] deleteChat:chatItem.chatId completion:^(BOOL success, NSError *error) {
            if (success) {
                [self loadChatList];
            } else {
                NSLog(@"Error deleting chat: %@", error.localizedDescription);
            }
        }];
    }]];
    
    [self presentViewController:alert animated:YES completion:nil];
}

@end
點擊查看更多內(nèi)容
TA 點贊

若覺得本文不錯,就分享一下吧!

評論

作者其他優(yōu)質(zhì)文章

正在加載中
  • 推薦
  • 評論
  • 收藏
  • 共同學(xué)習(xí),寫下你的評論
感謝您的支持,我會繼續(xù)努力的~
掃碼打賞,你說多少就多少
贊賞金額會直接到老師賬戶
支付方式
打開微信掃一掃,即可進行掃碼打賞哦
今天注冊有機會得

100積分直接送

付費專欄免費學(xué)

大額優(yōu)惠券免費領(lǐng)

立即參與 放棄機會
微信客服

購課補貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動學(xué)習(xí)伙伴

公眾號

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號

舉報

0/150
提交
取消