mirror of
https://github.com/openimsdk/open-im-server.git
synced 2025-05-20 11:39:18 +08:00
Merge remote-tracking branch 'origin/main'
This commit is contained in:
commit
f5f2cf4746
3
.github/workflows/openimci.yml
vendored
3
.github/workflows/openimci.yml
vendored
@ -161,7 +161,8 @@ jobs:
|
|||||||
```
|
```
|
||||||
${{ env.containers }}
|
${{ env.containers }}
|
||||||
```
|
```
|
||||||
GITHUB_TOKEN: ${{ secrets.BOT_GITHUB_TOKEN }}
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
continue-on-error: true
|
||||||
|
|
||||||
execute-scripts:
|
execute-scripts:
|
||||||
name: Execute OpenIM Script On ${{ matrix.os }}
|
name: Execute OpenIM Script On ${{ matrix.os }}
|
||||||
|
@ -35,52 +35,62 @@
|
|||||||
|
|
||||||
## Ⓜ️ 关于 OpenIM
|
## Ⓜ️ 关于 OpenIM
|
||||||
|
|
||||||
OpenIM 不仅仅是一个开源的即时消息组件,它是你的应用程序生态系统的一个不可或缺的部分。查看下面的图表,了解 AppServer、AppClient、OpenIMServer 和 OpenIMSDK 是如何交互的。
|
OpenIM 是一个专门设计用于在应用程序中集成聊天、音视频通话、通知以及AI聊天机器人等通信功能的服务平台。它通过提供一系列强大的API和Webhooks,使开发者可以轻松地在他们的应用中加入这些交互特性。OpenIM 本身并不是一个独立运行的聊天应用,而是作为一个平台,为其他应用提供支持,实现丰富的通信功能。下图展示 AppServer、AppClient、OpenIMServer 和 OpenIMSDK 之间的交互关系来具体说明。
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
## 🚀 关于 OpenIMSDK
|
## 🚀 关于 OpenIMSDK
|
||||||
|
|
||||||
**OpenIMSDK** 无缝集成到您的应用中,提供丰富、实时的消息体验,无需复杂的 UI 集成。它提供:
|
**OpenIMSDK** 是为 **OpenIMServer** 设计的IM SDK,专为嵌入客户端应用而生。其主要功能及模块如下:
|
||||||
|
|
||||||
+ **本地存储**:用于快速数据检索和消息同步。
|
+ 🌟 主要功能:
|
||||||
+ **监听器回调**:确保实时消息交互性。
|
|
||||||
+ **API 封装**:简化开发流程。
|
|
||||||
+ **连接管理**:保证可靠的消息传递。
|
|
||||||
|
|
||||||
它使用 Golang 构建,并支持跨平台部署,确保在所有平台上提供一致的消息体验。
|
- 📦 本地存储
|
||||||
|
- 🔔 监听器回调
|
||||||
|
- 🛡️ API封装
|
||||||
|
- 🌐 连接管理
|
||||||
|
|
||||||
|
## 📚 主要模块:
|
||||||
|
|
||||||
|
1. 🚀 初始化及登录
|
||||||
|
2. 👤 用户管理
|
||||||
|
3. 👫 好友管理
|
||||||
|
4. 🤖 群组功能
|
||||||
|
5. 💬 会话处理
|
||||||
|
|
||||||
|
它使用 Golang 构建,并支持跨平台部署,确保在所有平台上提供一致的接入体验。
|
||||||
|
|
||||||
👉 **[探索 GO SDK](https://github.com/openimsdk/openim-sdk-core)**
|
👉 **[探索 GO SDK](https://github.com/openimsdk/openim-sdk-core)**
|
||||||
|
|
||||||
## 🌐 关于 OpenIMServer
|
## 🌐 关于 OpenIMServer
|
||||||
|
|
||||||
精心用 Golang 开发的 **OpenIMServer** 通过多重方式确保了卓越的即时消息服务器能力:
|
+ **OpenIMServer** 具有以下特点:
|
||||||
|
- 🌐 微服务架构:支持集群模式,包括网关(gateway)和多个rpc服务。
|
||||||
+ **模块组成**:它由多个模块组成,例如网关和多个 RPC 服务,提供一个多功能的消息环境。
|
- 🚀 部署方式多样:支持源代码、kubernetes或docker部署。
|
||||||
+ **微服务架构**:支持集群模式,确保出色的性能和可伸缩性,以有效管理各个实例间的通信。
|
- 海量用户支持:十万超级大群,千万用户,及百亿消息
|
||||||
+ **多样的部署选项**:适应你的操作偏好,通过源代码、Kubernetes 或 Docker 提供部署选项。
|
|
||||||
|
|
||||||
### 增强的业务功能:
|
### 增强的业务功能:
|
||||||
|
|
||||||
+ **REST API**:OpenIMServer 为业务系统提供 REST API,旨在通过后端接口为您的操作提供附加功能,如群组创建和消息推送。
|
+ **REST API**:OpenIMServer 提供了REST API供业务系统使用,旨在赋予业务更多功能,例如通过后台接口建立群组、发送推送消息等。
|
||||||
+ **回调**:为了扩展其在各种业务形式中的实用性,OpenIMServer 提供了回调能力。即,在事件发生之前或之后,它向业务服务器发送请求,比如发送消息,丰富通信过程中的交互和数据交换流。
|
+ **Webhooks**:OpenIMServer提供了回调能力以扩展更多的业务形态,所谓回调,即OpenIMServer会在某一事件发生之前或者之后,向业务服务器发送请求,如发送消息之前或之后的回调。
|
||||||
|
|
||||||
👉 **[了解更多](https://doc.rentsoft.cn/guides/introduction/product)**
|
👉 **[了解更多](https://docs.openim.io/guides/introduction/product)**
|
||||||
|
|
||||||
## :rocket: 快速开始
|
## :rocket: 快速开始
|
||||||
|
|
||||||
你只需要一个简单的命令,就可以快速学习 OpenIM 的工程解决方案:
|
在线体验iOS/Android/H5/PC/Web:
|
||||||
|
|
||||||
```
|
👉 **[OpenIM online demo](https://www.openim.io/zh/commercial)**
|
||||||
bashCopy code
|
|
||||||
$ make demo
|
|
||||||
```
|
|
||||||
|
|
||||||
🤲 为了方便用户体验,我们提供了多种部署解决方案,您可以根据下面的列表选择自己的部署方法:
|
🤲 为了方便用户体验,我们提供了多种部署解决方案,您可以根据下面的列表选择自己的部署方法:
|
||||||
|
|
||||||
+ **[源代码部署指南](https://doc.rentsoft.cn/guides/gettingStarted/imSourceCodeDeployment)**
|
+ **[源代码部署指南](https://docs.openim.io/guides/gettingStarted/imSourceCodeDeployment)**
|
||||||
+ **[Docker 部署指南](https://doc.rentsoft.cn/guides/gettingStarted/dockerCompose)**
|
+ **[Docker 部署指南](https://docs.openim.io/guides/gettingStarted/dockerCompose)**
|
||||||
+ **[Kubernetes 部署指南](https://github.com/openimsdk/open-im-server/tree/main/deployments)**
|
+ **[Kubernetes 部署指南](https://docs.openim.io/guides/gettingStarted/k8s-deployment)**
|
||||||
|
|
||||||
## :hammer_and_wrench: 开始开发 OpenIM
|
## :hammer_and_wrench: 开始开发 OpenIM
|
||||||
|
|
||||||
|
176
README.md
176
README.md
@ -25,178 +25,56 @@
|
|||||||
|
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
|
||||||
## Ⓜ️ About OpenIM
|
## Ⓜ️ About OpenIM
|
||||||
|
|
||||||
OpenIM isn't just an open-source instant messaging component, it's an integral part of your application ecosystem. Check out this diagram to understand how AppServer, AppClient, OpenIMServer, and OpenIMSDK interact.
|
OpenIM is a service platform specifically designed for integrating chat, audio-video calls, notifications, and AI chatbots into applications. It provides a range of powerful APIs and Webhooks, enabling developers to easily incorporate these interactive features into their applications. OpenIM is not a standalone chat application, but rather serves as a platform to support other applications in achieving rich communication functionalities. The following diagram illustrates the interaction between AppServer, AppClient, OpenIMServer, and OpenIMSDK to explain in detail.
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
## 🚀 About OpenIMSDK
|
## 🚀 About OpenIMSDK
|
||||||
|
|
||||||
**OpenIMSDK** seamlessly integrates into your application, delivering a rich, real-time messaging experience without requiring intricate UI integration. It provides:
|
**OpenIMSDK** is an IM SDK designed for **OpenIMServer**, created specifically for embedding in client applications. Its main features and modules are as follows:
|
||||||
|
|
||||||
+ **Local Storage**: For quick data retrieval and message synchronization.
|
+ 🌟 Main Features:
|
||||||
+ **Listener Callbacks**: Ensuring real-time message interactivity.
|
|
||||||
+ **API Encapsulation**: Streamlining development processes.
|
|
||||||
+ **Connection Management**: Guaranteeing reliable message delivery.
|
|
||||||
|
|
||||||
It's crafted in Golang and supports cross-platform deployment, ensuring a coherent messaging experience across all platforms.
|
- 📦 Local storage
|
||||||
|
- 🔔 Listener callbacks
|
||||||
|
- 🛡️ API wrapping
|
||||||
|
- 🌐 Connection management
|
||||||
|
|
||||||
|
## 📚 Main Modules:
|
||||||
|
|
||||||
|
1. 🚀 Initialization and Login
|
||||||
|
2. 👤 User Management
|
||||||
|
3. 👫 Friend Management
|
||||||
|
4. 🤖 Group Functions
|
||||||
|
5. 💬 Conversation Handling
|
||||||
|
|
||||||
|
It is built using Golang and supports cross-platform deployment, ensuring a consistent access experience across all platforms.
|
||||||
|
|
||||||
👉 **[Explore GO SDK](https://github.com/openimsdk/openim-sdk-core)**
|
👉 **[Explore GO SDK](https://github.com/openimsdk/openim-sdk-core)**
|
||||||
|
|
||||||
## 🌐 About OpenIMServer
|
## 🌐 About OpenIMServer
|
||||||
|
|
||||||
**OpenIMServer**, meticulously developed in Golang, ensures a stellar instant messaging server capability with a multifold approach:
|
+ **OpenIMServer** has the following characteristics:
|
||||||
|
- 🌐 Microservice architecture: Supports cluster mode, including a gateway and multiple rpc services.
|
||||||
|
- 🚀 Diverse deployment methods: Supports deployment via source code, Kubernetes, or Docker.
|
||||||
|
- Support for massive user base: Super large groups with hundreds of thousands of users, tens of millions of users, and billions of messages.
|
||||||
|
|
||||||
+ **Modular Composition**: It's comprised of several modules, such as the gateway and multiple RPC services, offering a versatile messaging environment.
|
### Enhanced Business Functionality:
|
||||||
+ **Microservices Architecture**: Supporting cluster modes, it assures outstanding performance and scalability to manage communication effectively across various instances.
|
|
||||||
+ **Diverse Deployment Options**: Adapts to your operational preferences, offering deployment via source code, Kubernetes, or Docker.
|
|
||||||
|
|
||||||
### Enhanced Business Functionalities:
|
+ **REST API**: OpenIMServer offers REST APIs for business systems, aimed at empowering businesses with more functionalities, such as creating groups and sending push messages through backend interfaces.
|
||||||
|
+ **Webhooks**: OpenIMServer provides callback capabilities to extend more business forms. A callback means that OpenIMServer sends a request to the business server before or after a certain event, like callbacks before or after sending a message.
|
||||||
+ **REST API**: OpenIMServer provides REST API for business systems, aiming to empower your operations with additional functionalities like group creation and message push via backend interfaces.
|
|
||||||
+ **Callbacks**: To expand its utility across varied business forms, OpenIMServer offers callback capabilities. That is, it sends a request to the business server before or after an event occurs, such as sending a message, enriching the interaction and data exchange flow in the communication processes.
|
|
||||||
|
|
||||||
👉 **[Learn More](https://docs.openim.io/guides/introduction/product)**
|
|
||||||
|
|
||||||
<!--
|
|
||||||
|
|
||||||
## :star2: Why OpenIM
|
|
||||||
|
|
||||||
**🔍 Function screenshot display**
|
|
||||||
|
|
||||||
<div align="center">
|
|
||||||
|
|
||||||
| 💻🔄📱 Multi Terminal Synchronization 🔄🖥️ | 📅⚡ Efficient Meetings 🚀💼 |
|
|
||||||
| :----------------------------------------------------------: | :---------------------------------------------------------: |
|
|
||||||
|  |  |
|
|
||||||
| 📲🔄 **One-to-one and Group Chats** 👥🗣️ | 🎁💻 **Special Features - Custom Messages** ✉️🎨|
|
|
||||||
|  |  |
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
**OpenIM** offers a powerful and reliable instant messaging platform, ensuring versatile communication across multiple platforms with the following key features:
|
|
||||||
|
|
||||||
✅ **Versatile Messaging:** Support for text, images, emojis, voice, video, and more, alongside one-on-one and multi-person audio/video calls.
|
|
||||||
|
|
||||||
✅ **Robust Chat Capabilities:** Including roles (application administrator, group owner, etc.) and features like muting, group announcements, and dynamic message loading.
|
|
||||||
|
|
||||||
✅ **Unique Interaction Features:** Offering read-and-burn private chats and a message editing function to broaden social scenarios.
|
|
||||||
|
|
||||||
✅ **Open Source:** The code of OpenIM is open source and aims to build a leading global IM open source community. [GitHub Repository](https://github.com/OpenIMSDK)
|
|
||||||
|
|
||||||
✅ **Extensibility:** Implemented in Golang, OpenIM introduces an "everything is a message" communication model, simplifying custom messages and feature extension.
|
|
||||||
|
|
||||||
✅ **High Performance:** Supports a hierarchical governance architecture tested and abstracts the storage model of various message types.
|
|
||||||
|
|
||||||
✅ **Full Platform Support:** Native support for iOS, Android, Flutter, uni-app, ReactNative, Electron, and Web.
|
|
||||||
|
|
||||||
-->
|
|
||||||
|
|
||||||
|
👉 **[Learn more](https://docs.openim.io/guides/introduction/product)**
|
||||||
|
|
||||||
## :rocket: Quick Start
|
## :rocket: Quick Start
|
||||||
|
|
||||||
We support many platforms. Here are the addresses for quick experience on the web side:
|
🤲 To facilitate user experience, we offer various deployment solutions. You can choose your deployment method from the list below:
|
||||||
|
|
||||||
👉 **[OpenIM online web demo](https://web-enterprise.rentsoft.cn/)**
|
|
||||||
|
|
||||||
You can quickly learn OpenIM engineering solutions, all it takes is one simple command:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
$ make demo
|
|
||||||
```
|
|
||||||
|
|
||||||
🤲 In order to facilitate the user experience, we have provided a variety of deployment solutions, you can choose your own deployment method according to the list below:
|
|
||||||
|
|
||||||
<!--
|
|
||||||
<details> <summary>Deploying with Docker Compose</summary>
|
|
||||||
|
|
||||||
It is recommended to use Docker Compose for deployment, which can easily and quickly deploy the entire OpenIM service on a single node
|
|
||||||
|
|
||||||
+ [https://github.com/openimsdk/openim-docker](https://github.com/openimsdk/openim-docker)
|
|
||||||
|
|
||||||
|
|
||||||
> **Note**
|
|
||||||
>
|
|
||||||
> If you don't know OpenIM's versioning policy, 📚Read our release policy: https://github.com/openimsdk/open-im-server/blob/main/docs/contrib/version.md
|
|
||||||
|
|
||||||
|
|
||||||
</details>
|
|
||||||
|
|
||||||
<details> <summary>Compile from Source</summary>
|
|
||||||
|
|
||||||
|
|
||||||
Ur need `Go 1.20` or higher version, and `make`.
|
|
||||||
|
|
||||||
|
|
||||||
```bash
|
|
||||||
go version && make --version || echo "Error: One of the commands failed."
|
|
||||||
```
|
|
||||||
|
|
||||||
Version Details: https://github.com/openimsdk/open-im-server/blob/main/docs/contrib/version.md
|
|
||||||
|
|
||||||
You can get the version number from the command below or from [github releases](https://github.com/openimsdk/open-im-server/tags).
|
|
||||||
|
|
||||||
```bash
|
|
||||||
$ curl --silent "https://api.github.com/repos/openimsdk/open-im-server/releases" | jq -r '.[].tag_name'
|
|
||||||
```
|
|
||||||
|
|
||||||
We have our own version management policy, if you are interested in our version management, I recommend reading [📚 OpenIM Version](https://github.com/openimsdk/open-im-server/blob/main/docs/contrib/version.md), We recommend using stable versions such as `v3.3.0` and `v3.2.0` whenever possible. `v3.1.1-alpha.3` as well as `v3.3.0-beta.0` and `v3.2.0-rc.0` are pre-release or beta versions and are not recommended.
|
|
||||||
|
|
||||||
Set `OPENIM_VERSION` environment variables for the latest `OPENIM_VERSION` number, or replace the `OPENIM_VERSION` for you to install the OpenIM-Server `OPENIM_VERSION`:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
$ OPENIM_VERSION=`curl -s https://api.github.com/repos/openimsdk/open-im-server/releases/latest | grep -oE '"tag_name": "[^"]+"' | head -n1 | cut -d'"' -f4`
|
|
||||||
# OPENIM_VERSION=v3.3.0
|
|
||||||
```
|
|
||||||
|
|
||||||
Deploy basic components at the click of a command:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# install openim dependency
|
|
||||||
$ git clone https://github.com/openimsdk/open-im-server openim/openim-server && export openim=$(pwd)/openim/openim-server && cd $openim/openim-server && git checkout $OPENIM_VERSION
|
|
||||||
$ make init && docker compose up -d && make start && make check
|
|
||||||
```
|
|
||||||
|
|
||||||
> `make help` to help you see the instructions supported by OpenIM.
|
|
||||||
|
|
||||||
|
|
||||||
You can use the `make help-all` see OpenIM in action.
|
|
||||||
|
|
||||||
</details>
|
|
||||||
|
|
||||||
<details> <summary>Component Configuration Instructions</summary>
|
|
||||||
|
|
||||||
Read: Configuration center document:https://github.com/openimsdk/open-im-server/blob/main/docs/contrib/environment.md
|
|
||||||
|
|
||||||
</details>
|
|
||||||
|
|
||||||
|
|
||||||
<details> <summary>Deployed with kubernetes</summary>
|
|
||||||
|
|
||||||
+ https://github.com/openimsdk/open-im-server/blob/main/deployments/README.md
|
|
||||||
|
|
||||||
</details>
|
|
||||||
-->
|
|
||||||
|
|
||||||
+ **[Source Code Deployment Guide](https://docs.openim.io/guides/gettingStarted/imSourceCodeDeployment)**
|
+ **[Source Code Deployment Guide](https://docs.openim.io/guides/gettingStarted/imSourceCodeDeployment)**
|
||||||
+ **[Production deployment of Linux systems](https://github.com/openimsdk/open-im-server/blob/main/docs/contrib/install-openim-linux-system.md)**
|
|
||||||
+ **[Docker Deployment Guide](https://docs.openim.io/guides/gettingStarted/dockerCompose)**
|
+ **[Docker Deployment Guide](https://docs.openim.io/guides/gettingStarted/dockerCompose)**
|
||||||
+ **[Kubernetes Deployment Guide](https://github.com/openimsdk/open-im-server/tree/main/deployments)**
|
+ **[Kubernetes Deployment Guide](https://docs.openim.io/guides/gettingStarted/k8s-deployment)**
|
||||||
|
|
||||||
<!--
|
|
||||||
## :link: OpenIM and your application
|
|
||||||
|
|
||||||
OpenIM isn't just an open-source instant messaging component, it's an integral part of your application ecosystem. Check out this diagram to understand how AppServer, AppClient, OpenIMServer, and OpenIMSDK interact.
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
## :building_construction: Overall Architecture
|
|
||||||
|
|
||||||
Delve into the heart of Open-IM-Server's functionality with our architecture diagram.
|
|
||||||
|
|
||||||
 -->
|
|
||||||
|
|
||||||
## :hammer_and_wrench: To start developing OpenIM
|
## :hammer_and_wrench: To start developing OpenIM
|
||||||
|
|
||||||
|
@ -320,6 +320,14 @@ callback:
|
|||||||
enable: ${CALLBACK_ENABLE}
|
enable: ${CALLBACK_ENABLE}
|
||||||
timeout: ${CALLBACK_TIMEOUT}
|
timeout: ${CALLBACK_TIMEOUT}
|
||||||
failedContinue: ${CALLBACK_FAILED_CONTINUE}
|
failedContinue: ${CALLBACK_FAILED_CONTINUE}
|
||||||
|
beforeUpdateUserInfoEx:
|
||||||
|
enable: ${CALLBACK_ENABLE}
|
||||||
|
timeout: ${CALLBACK_TIMEOUT}
|
||||||
|
failedContinue: ${CALLBACK_FAILED_CONTINUE}
|
||||||
|
afterUpdateUserInfoEx:
|
||||||
|
enable: ${CALLBACK_ENABLE}
|
||||||
|
timeout: ${CALLBACK_TIMEOUT}
|
||||||
|
failedContinue: ${CALLBACK_FAILED_CONTINUE}
|
||||||
afterSendSingleMsg:
|
afterSendSingleMsg:
|
||||||
enable: ${CALLBACK_ENABLE}
|
enable: ${CALLBACK_ENABLE}
|
||||||
timeout: ${CALLBACK_TIMEOUT}
|
timeout: ${CALLBACK_TIMEOUT}
|
||||||
|
4
go.mod
4
go.mod
@ -4,8 +4,8 @@ go 1.19
|
|||||||
|
|
||||||
require (
|
require (
|
||||||
firebase.google.com/go v3.13.0+incompatible
|
firebase.google.com/go v3.13.0+incompatible
|
||||||
github.com/OpenIMSDK/protocol v0.0.44
|
github.com/OpenIMSDK/protocol v0.0.47
|
||||||
github.com/OpenIMSDK/tools v0.0.21
|
github.com/OpenIMSDK/tools v0.0.23
|
||||||
github.com/bwmarrin/snowflake v0.3.0 // indirect
|
github.com/bwmarrin/snowflake v0.3.0 // indirect
|
||||||
github.com/dtm-labs/rockscache v0.1.1
|
github.com/dtm-labs/rockscache v0.1.1
|
||||||
github.com/gin-gonic/gin v1.9.1
|
github.com/gin-gonic/gin v1.9.1
|
||||||
|
8
go.sum
8
go.sum
@ -18,10 +18,10 @@ firebase.google.com/go v3.13.0+incompatible/go.mod h1:xlah6XbEyW6tbfSklcfe5FHJIw
|
|||||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||||
github.com/IBM/sarama v1.41.3 h1:MWBEJ12vHC8coMjdEXFq/6ftO6DUZnQlFYcxtOJFa7c=
|
github.com/IBM/sarama v1.41.3 h1:MWBEJ12vHC8coMjdEXFq/6ftO6DUZnQlFYcxtOJFa7c=
|
||||||
github.com/IBM/sarama v1.41.3/go.mod h1:Xxho9HkHd4K/MDUo/T/sOqwtX/17D33++E9Wib6hUdQ=
|
github.com/IBM/sarama v1.41.3/go.mod h1:Xxho9HkHd4K/MDUo/T/sOqwtX/17D33++E9Wib6hUdQ=
|
||||||
github.com/OpenIMSDK/protocol v0.0.44 h1:P+9gJ9EW3y+VmzrjPludzn/5r1fjubaC19mKYJ7Oiew=
|
github.com/OpenIMSDK/protocol v0.0.47 h1:DTJMFSONzqT0i/wa4Q1CtDT/jVATVudIRHcpY1zSWYE=
|
||||||
github.com/OpenIMSDK/protocol v0.0.44/go.mod h1:F25dFrwrIx3lkNoiuf6FkCfxuwf8L4Z8UIsdTHP/r0Y=
|
github.com/OpenIMSDK/protocol v0.0.47/go.mod h1:F25dFrwrIx3lkNoiuf6FkCfxuwf8L4Z8UIsdTHP/r0Y=
|
||||||
github.com/OpenIMSDK/tools v0.0.21 h1:iTapc2mIEVH/xl5Nd6jfwPub11Pgp44tVcE1rjB3a48=
|
github.com/OpenIMSDK/tools v0.0.23 h1:xozfrGzhbpNPlDTap5DLVPk+JfgZ/ZyIj4Cuu3/bm9w=
|
||||||
github.com/OpenIMSDK/tools v0.0.21/go.mod h1:eg+q4A34Qmu73xkY0mt37FHGMCMfC6CtmOnm0kFEGFI=
|
github.com/OpenIMSDK/tools v0.0.23/go.mod h1:eg+q4A34Qmu73xkY0mt37FHGMCMfC6CtmOnm0kFEGFI=
|
||||||
github.com/QcloudApi/qcloud_sign_golang v0.0.0-20141224014652-e4130a326409/go.mod h1:1pk82RBxDY/JZnPQrtqHlUFfCctgdorsd9M06fMynOM=
|
github.com/QcloudApi/qcloud_sign_golang v0.0.0-20141224014652-e4130a326409/go.mod h1:1pk82RBxDY/JZnPQrtqHlUFfCctgdorsd9M06fMynOM=
|
||||||
github.com/alcortesm/tgz v0.0.0-20161220082320-9c5fe88206d7 h1:uSoVVbwJiQipAclBbw+8quDsfcvFjOpI5iCf4p/cqCs=
|
github.com/alcortesm/tgz v0.0.0-20161220082320-9c5fe88206d7 h1:uSoVVbwJiQipAclBbw+8quDsfcvFjOpI5iCf4p/cqCs=
|
||||||
github.com/alcortesm/tgz v0.0.0-20161220082320-9c5fe88206d7/go.mod h1:6zEj6s6u/ghQa61ZWa/C2Aw3RkjiTBOix7dkqa1VLIs=
|
github.com/alcortesm/tgz v0.0.0-20161220082320-9c5fe88206d7/go.mod h1:6zEj6s6u/ghQa61ZWa/C2Aw3RkjiTBOix7dkqa1VLIs=
|
||||||
|
@ -33,8 +33,8 @@ func (o *ConversationApi) GetAllConversations(c *gin.Context) {
|
|||||||
a2r.Call(conversation.ConversationClient.GetAllConversations, o.Client, c)
|
a2r.Call(conversation.ConversationClient.GetAllConversations, o.Client, c)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o *ConversationApi) GetConversationsList(c *gin.Context) {
|
func (o *ConversationApi) GetSortedConversationList(c *gin.Context) {
|
||||||
a2r.Call(conversation.ConversationClient.GetConversationList, o.Client, c)
|
a2r.Call(conversation.ConversationClient.GetSortedConversationList, o.Client, c)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o *ConversationApi) GetConversation(c *gin.Context) {
|
func (o *ConversationApi) GetConversation(c *gin.Context) {
|
||||||
|
@ -164,6 +164,8 @@ func (m *MessageApi) getSendMsgReq(c *gin.Context, req apistruct.SendMsg) (sendM
|
|||||||
data = apistruct.VideoElem{}
|
data = apistruct.VideoElem{}
|
||||||
case constant.File:
|
case constant.File:
|
||||||
data = apistruct.FileElem{}
|
data = apistruct.FileElem{}
|
||||||
|
case constant.AtText:
|
||||||
|
data = apistruct.AtElem{}
|
||||||
case constant.Custom:
|
case constant.Custom:
|
||||||
data = apistruct.CustomElem{}
|
data = apistruct.CustomElem{}
|
||||||
case constant.OANotification:
|
case constant.OANotification:
|
||||||
@ -172,7 +174,6 @@ func (m *MessageApi) getSendMsgReq(c *gin.Context, req apistruct.SendMsg) (sendM
|
|||||||
if err = m.userRpcClient.GetNotificationByID(c, req.SendID); err != nil {
|
if err = m.userRpcClient.GetNotificationByID(c, req.SendID); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return nil, errs.ErrArgs.WithDetail("not support err contentType")
|
return nil, errs.ErrArgs.WithDetail("not support err contentType")
|
||||||
}
|
}
|
||||||
|
@ -83,6 +83,7 @@ func NewGinRouter(discov discoveryregistry.SvcDiscoveryRegistry, rdb redis.Unive
|
|||||||
userRouterGroup.POST("/process_user_command_delete", ParseToken, u.ProcessUserCommandDelete)
|
userRouterGroup.POST("/process_user_command_delete", ParseToken, u.ProcessUserCommandDelete)
|
||||||
userRouterGroup.POST("/process_user_command_update", ParseToken, u.ProcessUserCommandUpdate)
|
userRouterGroup.POST("/process_user_command_update", ParseToken, u.ProcessUserCommandUpdate)
|
||||||
userRouterGroup.POST("/process_user_command_get", ParseToken, u.ProcessUserCommandGet)
|
userRouterGroup.POST("/process_user_command_get", ParseToken, u.ProcessUserCommandGet)
|
||||||
|
userRouterGroup.POST("/process_user_command_get_all", ParseToken, u.ProcessUserCommandGetAll)
|
||||||
|
|
||||||
userRouterGroup.POST("/add_notification_account", ParseToken, u.AddNotificationAccount)
|
userRouterGroup.POST("/add_notification_account", ParseToken, u.AddNotificationAccount)
|
||||||
userRouterGroup.POST("/update_notification_account", ParseToken, u.UpdateNotificationAccountInfo)
|
userRouterGroup.POST("/update_notification_account", ParseToken, u.UpdateNotificationAccountInfo)
|
||||||
@ -204,7 +205,7 @@ func NewGinRouter(discov discoveryregistry.SvcDiscoveryRegistry, rdb redis.Unive
|
|||||||
conversationGroup := r.Group("/conversation", ParseToken)
|
conversationGroup := r.Group("/conversation", ParseToken)
|
||||||
{
|
{
|
||||||
c := NewConversationApi(*conversationRpc)
|
c := NewConversationApi(*conversationRpc)
|
||||||
conversationGroup.POST("/get_conversations_list", c.GetConversationsList)
|
conversationGroup.POST("/get_sorted_conversation_list", c.GetSortedConversationList)
|
||||||
conversationGroup.POST("/get_all_conversations", c.GetAllConversations)
|
conversationGroup.POST("/get_all_conversations", c.GetAllConversations)
|
||||||
conversationGroup.POST("/get_conversation", c.GetConversation)
|
conversationGroup.POST("/get_conversation", c.GetConversation)
|
||||||
conversationGroup.POST("/get_conversations", c.GetConversations)
|
conversationGroup.POST("/get_conversations", c.GetConversations)
|
||||||
|
@ -221,6 +221,11 @@ func (u *UserApi) ProcessUserCommandGet(c *gin.Context) {
|
|||||||
a2r.Call(user.UserClient.ProcessUserCommandGet, u.Client, c)
|
a2r.Call(user.UserClient.ProcessUserCommandGet, u.Client, c)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ProcessUserCommandGet user general function get all
|
||||||
|
func (u *UserApi) ProcessUserCommandGetAll(c *gin.Context) {
|
||||||
|
a2r.Call(user.UserClient.ProcessUserCommandGetAll, u.Client, c)
|
||||||
|
}
|
||||||
|
|
||||||
func (u *UserApi) AddNotificationAccount(c *gin.Context) {
|
func (u *UserApi) AddNotificationAccount(c *gin.Context) {
|
||||||
a2r.Call(user.UserClient.AddNotificationAccount, u.Client, c)
|
a2r.Call(user.UserClient.AddNotificationAccount, u.Client, c)
|
||||||
}
|
}
|
||||||
|
@ -37,7 +37,7 @@ func callbackOfflinePush(
|
|||||||
msg *sdkws.MsgData,
|
msg *sdkws.MsgData,
|
||||||
offlinePushUserIDs *[]string,
|
offlinePushUserIDs *[]string,
|
||||||
) error {
|
) error {
|
||||||
if !config.Config.Callback.CallbackOfflinePush.Enable {
|
if !config.Config.Callback.CallbackOfflinePush.Enable || msg.ContentType == constant.Typing {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
req := &callbackstruct.CallbackBeforePushReq{
|
req := &callbackstruct.CallbackBeforePushReq{
|
||||||
@ -73,7 +73,7 @@ func callbackOfflinePush(
|
|||||||
}
|
}
|
||||||
|
|
||||||
func callbackOnlinePush(ctx context.Context, userIDs []string, msg *sdkws.MsgData) error {
|
func callbackOnlinePush(ctx context.Context, userIDs []string, msg *sdkws.MsgData) error {
|
||||||
if !config.Config.Callback.CallbackOnlinePush.Enable || utils.Contain(msg.SendID, userIDs...) {
|
if !config.Config.Callback.CallbackOnlinePush.Enable || utils.Contain(msg.SendID, userIDs...) || msg.ContentType == constant.Typing {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
req := callbackstruct.CallbackBeforePushReq{
|
req := callbackstruct.CallbackBeforePushReq{
|
||||||
@ -107,7 +107,7 @@ func callbackBeforeSuperGroupOnlinePush(
|
|||||||
msg *sdkws.MsgData,
|
msg *sdkws.MsgData,
|
||||||
pushToUserIDs *[]string,
|
pushToUserIDs *[]string,
|
||||||
) error {
|
) error {
|
||||||
if !config.Config.Callback.CallbackBeforeSuperGroupOnlinePush.Enable {
|
if !config.Config.Callback.CallbackBeforeSuperGroupOnlinePush.Enable || msg.ContentType == constant.Typing {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
req := callbackstruct.CallbackBeforeSuperGroupOnlinePushReq{
|
req := callbackstruct.CallbackBeforeSuperGroupOnlinePushReq{
|
||||||
|
@ -101,11 +101,9 @@ func (p *Pusher) DeleteMemberAndSetConversationSeq(ctx context.Context, groupID
|
|||||||
|
|
||||||
func (p *Pusher) Push2User(ctx context.Context, userIDs []string, msg *sdkws.MsgData) error {
|
func (p *Pusher) Push2User(ctx context.Context, userIDs []string, msg *sdkws.MsgData) error {
|
||||||
log.ZDebug(ctx, "Get msg from msg_transfer And push msg", "userIDs", userIDs, "msg", msg.String())
|
log.ZDebug(ctx, "Get msg from msg_transfer And push msg", "userIDs", userIDs, "msg", msg.String())
|
||||||
// callback
|
|
||||||
if err := callbackOnlinePush(ctx, userIDs, msg); err != nil {
|
if err := callbackOnlinePush(ctx, userIDs, msg); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// push
|
// push
|
||||||
wsResults, err := p.GetConnsAndOnlinePush(ctx, msg, userIDs)
|
wsResults, err := p.GetConnsAndOnlinePush(ctx, msg, userIDs)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -120,7 +118,7 @@ func (p *Pusher) Push2User(ctx context.Context, userIDs []string, msg *sdkws.Msg
|
|||||||
}
|
}
|
||||||
|
|
||||||
for _, v := range wsResults {
|
for _, v := range wsResults {
|
||||||
if msg.SendID != v.UserID && (!v.OnlinePush) {
|
if !v.OnlinePush && msg.SendID == v.UserID {
|
||||||
if err = callbackOfflinePush(ctx, userIDs, msg, &[]string{}); err != nil {
|
if err = callbackOfflinePush(ctx, userIDs, msg, &[]string{}); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -130,6 +128,7 @@ func (p *Pusher) Push2User(ctx context.Context, userIDs []string, msg *sdkws.Msg
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -89,8 +89,8 @@ func (c *conversationServer) GetConversation(ctx context.Context, req *pbconvers
|
|||||||
return resp, nil
|
return resp, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *conversationServer) GetConversationList(ctx context.Context, req *pbconversation.GetConversationListReq) (resp *pbconversation.GetConversationListResp, err error) {
|
func (m *conversationServer) GetSortedConversationList(ctx context.Context, req *pbconversation.GetSortedConversationListReq) (resp *pbconversation.GetSortedConversationListResp, err error) {
|
||||||
log.ZDebug(ctx, "GetConversationList", "seqs", req, "userID", req.UserID)
|
log.ZDebug(ctx, "GetSortedConversationList", "seqs", req, "userID", req.UserID)
|
||||||
var conversationIDs []string
|
var conversationIDs []string
|
||||||
if len(req.ConversationIDs) == 0 {
|
if len(req.ConversationIDs) == 0 {
|
||||||
conversationIDs, err = m.conversationDatabase.GetConversationIDs(ctx, req.UserID)
|
conversationIDs, err = m.conversationDatabase.GetConversationIDs(ctx, req.UserID)
|
||||||
@ -129,30 +129,37 @@ func (m *conversationServer) GetConversationList(ctx context.Context, req *pbcon
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var unreadTotal int64
|
||||||
conversation_unreadCount := make(map[string]int64)
|
conversation_unreadCount := make(map[string]int64)
|
||||||
for conversationID, maxSeq := range maxSeqs {
|
for conversationID, maxSeq := range maxSeqs {
|
||||||
conversation_unreadCount[conversationID] = maxSeq - hasReadSeqs[conversationID]
|
unreadCount := maxSeq - hasReadSeqs[conversationID]
|
||||||
|
conversation_unreadCount[conversationID] = unreadCount
|
||||||
|
unreadTotal += unreadCount
|
||||||
}
|
}
|
||||||
|
|
||||||
conversation_isPinkTime := make(map[int64]string)
|
conversation_isPinTime := make(map[int64]string)
|
||||||
conversation_notPinkTime := make(map[int64]string)
|
conversation_notPinTime := make(map[int64]string)
|
||||||
for _, v := range conversations {
|
for _, v := range conversations {
|
||||||
conversationID := v.ConversationID
|
conversationID := v.ConversationID
|
||||||
time := conversationMsg[conversationID].MsgInfo.LatestMsgRecvTime
|
time := conversationMsg[conversationID].MsgInfo.LatestMsgRecvTime
|
||||||
conversationMsg[conversationID].RecvMsgOpt = v.RecvMsgOpt
|
conversationMsg[conversationID].RecvMsgOpt = v.RecvMsgOpt
|
||||||
if v.IsPinned {
|
if v.IsPinned {
|
||||||
conversationMsg[conversationID].IsPinned = v.IsPinned
|
conversationMsg[conversationID].IsPinned = v.IsPinned
|
||||||
conversation_isPinkTime[time] = conversationID
|
conversation_isPinTime[time] = conversationID
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
conversation_notPinkTime[time] = conversationID
|
conversation_notPinTime[time] = conversationID
|
||||||
}
|
}
|
||||||
resp = &pbconversation.GetConversationListResp{
|
resp = &pbconversation.GetSortedConversationListResp{
|
||||||
|
ConversationTotal: int64(len(chatLogs)),
|
||||||
ConversationElems: []*pbconversation.ConversationElem{},
|
ConversationElems: []*pbconversation.ConversationElem{},
|
||||||
|
UnreadTotal: unreadTotal,
|
||||||
}
|
}
|
||||||
|
|
||||||
m.conversationSort(conversation_isPinkTime, resp, conversation_unreadCount, conversationMsg)
|
m.conversationSort(conversation_isPinTime, resp, conversation_unreadCount, conversationMsg)
|
||||||
m.conversationSort(conversation_notPinkTime, resp, conversation_unreadCount, conversationMsg)
|
m.conversationSort(conversation_notPinTime, resp, conversation_unreadCount, conversationMsg)
|
||||||
|
|
||||||
|
resp.ConversationElems = utils.Paginate(resp.ConversationElems, int(req.Pagination.GetPageNumber()), int(req.Pagination.GetShowNumber()))
|
||||||
return resp, nil
|
return resp, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -425,7 +432,7 @@ func (c *conversationServer) GetConversationOfflinePushUserIDs(
|
|||||||
|
|
||||||
func (c *conversationServer) conversationSort(
|
func (c *conversationServer) conversationSort(
|
||||||
conversations map[int64]string,
|
conversations map[int64]string,
|
||||||
resp *pbconversation.GetConversationListResp,
|
resp *pbconversation.GetSortedConversationListResp,
|
||||||
conversation_unreadCount map[string]int64,
|
conversation_unreadCount map[string]int64,
|
||||||
conversationMsg map[string]*pbconversation.ConversationElem,
|
conversationMsg map[string]*pbconversation.ConversationElem,
|
||||||
) {
|
) {
|
||||||
|
@ -452,22 +452,19 @@ func (s *friendServer) UpdateFriends(
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, friendID := range req.FriendUserIDs {
|
val := make(map[string]any)
|
||||||
if req.IsPinned != nil {
|
|
||||||
if err = s.friendDatabase.UpdateFriendPinStatus(ctx, req.OwnerUserID, friendID, req.IsPinned.Value); err != nil {
|
if req.IsPinned != nil {
|
||||||
return nil, err
|
val["is_pinned"] = req.IsPinned.Value
|
||||||
}
|
}
|
||||||
}
|
if req.Remark != nil {
|
||||||
if req.Remark != nil {
|
val["remark"] = req.Remark.Value
|
||||||
if err = s.friendDatabase.UpdateFriendRemark(ctx, req.OwnerUserID, friendID, req.Remark.Value); err != nil {
|
}
|
||||||
return nil, err
|
if req.Ex != nil {
|
||||||
}
|
val["ex"] = req.Ex.Value
|
||||||
}
|
}
|
||||||
if req.Ex != nil {
|
if err = s.friendDatabase.UpdateFriends(ctx, req.OwnerUserID, req.FriendUserIDs, val); err != nil {
|
||||||
if err = s.friendDatabase.UpdateFriendEx(ctx, req.OwnerUserID, friendID, req.Ex.Value); err != nil {
|
return nil, err
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
resp := &pbfriend.UpdateFriendsResp{}
|
resp := &pbfriend.UpdateFriendsResp{}
|
||||||
|
@ -279,20 +279,20 @@ func CallbackApplyJoinGroupBefore(ctx context.Context, req *callbackstruct.Callb
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func CallbackTransferGroupOwnerAfter(ctx context.Context, req *pbgroup.TransferGroupOwnerReq) (err error) {
|
func CallbackAfterTransferGroupOwner(ctx context.Context, req *pbgroup.TransferGroupOwnerReq) (err error) {
|
||||||
if !config.Config.Callback.CallbackTransferGroupOwnerAfter.Enable {
|
if !config.Config.Callback.CallbackAfterTransferGroupOwner.Enable {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
cbReq := &callbackstruct.CallbackTransferGroupOwnerReq{
|
cbReq := &callbackstruct.CallbackTransferGroupOwnerReq{
|
||||||
CallbackCommand: callbackstruct.CallbackTransferGroupOwnerAfter,
|
CallbackCommand: callbackstruct.CallbackAfterTransferGroupOwner,
|
||||||
GroupID: req.GroupID,
|
GroupID: req.GroupID,
|
||||||
OldOwnerUserID: req.OldOwnerUserID,
|
OldOwnerUserID: req.OldOwnerUserID,
|
||||||
NewOwnerUserID: req.NewOwnerUserID,
|
NewOwnerUserID: req.NewOwnerUserID,
|
||||||
}
|
}
|
||||||
|
|
||||||
resp := &callbackstruct.CallbackTransferGroupOwnerResp{}
|
resp := &callbackstruct.CallbackTransferGroupOwnerResp{}
|
||||||
if err = http.CallBackPostReturn(ctx, config.Config.Callback.CallbackUrl, cbReq, resp, config.Config.Callback.CallbackBeforeJoinGroup); err != nil {
|
if err = http.CallBackPostReturn(ctx, config.Config.Callback.CallbackUrl, cbReq, resp, config.Config.Callback.CallbackAfterTransferGroupOwner); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
@ -1061,7 +1061,7 @@ func (s *groupServer) TransferGroupOwner(ctx context.Context, req *pbgroup.Trans
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := CallbackTransferGroupOwnerAfter(ctx, req); err != nil {
|
if err := CallbackAfterTransferGroupOwner(ctx, req); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
s.Notification.GroupOwnerTransferredNotification(ctx, req)
|
s.Notification.GroupOwnerTransferredNotification(ctx, req)
|
||||||
|
@ -70,7 +70,7 @@ func GetContent(msg *sdkws.MsgData) string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func callbackBeforeSendSingleMsg(ctx context.Context, msg *pbchat.SendMsgReq) error {
|
func callbackBeforeSendSingleMsg(ctx context.Context, msg *pbchat.SendMsgReq) error {
|
||||||
if !config.Config.Callback.CallbackBeforeSendSingleMsg.Enable {
|
if !config.Config.Callback.CallbackBeforeSendSingleMsg.Enable || msg.MsgData.ContentType == constant.Typing {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
req := &cbapi.CallbackBeforeSendSingleMsgReq{
|
req := &cbapi.CallbackBeforeSendSingleMsgReq{
|
||||||
@ -85,7 +85,7 @@ func callbackBeforeSendSingleMsg(ctx context.Context, msg *pbchat.SendMsgReq) er
|
|||||||
}
|
}
|
||||||
|
|
||||||
func callbackAfterSendSingleMsg(ctx context.Context, msg *pbchat.SendMsgReq) error {
|
func callbackAfterSendSingleMsg(ctx context.Context, msg *pbchat.SendMsgReq) error {
|
||||||
if !config.Config.Callback.CallbackAfterSendSingleMsg.Enable {
|
if !config.Config.Callback.CallbackAfterSendSingleMsg.Enable || msg.MsgData.ContentType == constant.Typing {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
req := &cbapi.CallbackAfterSendSingleMsgReq{
|
req := &cbapi.CallbackAfterSendSingleMsgReq{
|
||||||
@ -100,7 +100,7 @@ func callbackAfterSendSingleMsg(ctx context.Context, msg *pbchat.SendMsgReq) err
|
|||||||
}
|
}
|
||||||
|
|
||||||
func callbackBeforeSendGroupMsg(ctx context.Context, msg *pbchat.SendMsgReq) error {
|
func callbackBeforeSendGroupMsg(ctx context.Context, msg *pbchat.SendMsgReq) error {
|
||||||
if !config.Config.Callback.CallbackBeforeSendGroupMsg.Enable {
|
if !config.Config.Callback.CallbackBeforeSendGroupMsg.Enable || msg.MsgData.ContentType == constant.Typing {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
req := &cbapi.CallbackBeforeSendGroupMsgReq{
|
req := &cbapi.CallbackBeforeSendGroupMsgReq{
|
||||||
@ -115,7 +115,7 @@ func callbackBeforeSendGroupMsg(ctx context.Context, msg *pbchat.SendMsgReq) err
|
|||||||
}
|
}
|
||||||
|
|
||||||
func callbackAfterSendGroupMsg(ctx context.Context, msg *pbchat.SendMsgReq) error {
|
func callbackAfterSendGroupMsg(ctx context.Context, msg *pbchat.SendMsgReq) error {
|
||||||
if !config.Config.Callback.CallbackAfterSendGroupMsg.Enable {
|
if !config.Config.Callback.CallbackAfterSendGroupMsg.Enable || msg.MsgData.ContentType == constant.Typing {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
req := &cbapi.CallbackAfterSendGroupMsgReq{
|
req := &cbapi.CallbackAfterSendGroupMsgReq{
|
||||||
|
@ -65,6 +65,7 @@ func (m *msgServer) sendMsgSuperGroupChat(
|
|||||||
if err = callbackBeforeSendGroupMsg(ctx, req); err != nil {
|
if err = callbackBeforeSendGroupMsg(ctx, req); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := callbackMsgModify(ctx, req); err != nil {
|
if err := callbackMsgModify(ctx, req); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -167,6 +168,7 @@ func (m *msgServer) sendMsgSingleChat(ctx context.Context, req *pbmsg.SendMsgReq
|
|||||||
if err = callbackBeforeSendSingleMsg(ctx, req); err != nil {
|
if err = callbackBeforeSendSingleMsg(ctx, req); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := callbackMsgModify(ctx, req); err != nil {
|
if err := callbackMsgModify(ctx, req); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -17,6 +17,7 @@ package user
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
|
"github.com/OpenIMSDK/tools/pagination"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation"
|
||||||
"math/rand"
|
"math/rand"
|
||||||
"strings"
|
"strings"
|
||||||
@ -228,7 +229,7 @@ func (s *userServer) AccountCheck(ctx context.Context, req *pbuser.AccountCheckR
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *userServer) GetPaginationUsers(ctx context.Context, req *pbuser.GetPaginationUsersReq) (resp *pbuser.GetPaginationUsersResp, err error) {
|
func (s *userServer) GetPaginationUsers(ctx context.Context, req *pbuser.GetPaginationUsersReq) (resp *pbuser.GetPaginationUsersResp, err error) {
|
||||||
total, users, err := s.Page(ctx, req.Pagination)
|
total, users, err := s.PageFindUser(ctx, constant.IMOrdinaryUser, req.Pagination)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -379,38 +380,94 @@ func (s *userServer) GetSubscribeUsersStatus(ctx context.Context,
|
|||||||
|
|
||||||
// ProcessUserCommandAdd user general function add
|
// ProcessUserCommandAdd user general function add
|
||||||
func (s *userServer) ProcessUserCommandAdd(ctx context.Context, req *pbuser.ProcessUserCommandAddReq) (*pbuser.ProcessUserCommandAddResp, error) {
|
func (s *userServer) ProcessUserCommandAdd(ctx context.Context, req *pbuser.ProcessUserCommandAddReq) (*pbuser.ProcessUserCommandAddResp, error) {
|
||||||
// Assuming you have a method in s.UserDatabase to add a user command
|
err := authverify.CheckAccessV3(ctx, req.UserID)
|
||||||
err := s.UserDatabase.AddUserCommand(ctx, req.UserID, req.Type, req.Uuid, req.Value)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var value string
|
||||||
|
if req.Value != nil {
|
||||||
|
value = req.Value.Value
|
||||||
|
}
|
||||||
|
var ex string
|
||||||
|
if req.Ex != nil {
|
||||||
|
value = req.Ex.Value
|
||||||
|
}
|
||||||
|
// Assuming you have a method in s.UserDatabase to add a user command
|
||||||
|
err = s.UserDatabase.AddUserCommand(ctx, req.UserID, req.Type, req.Uuid, value, ex)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
tips := &sdkws.UserCommandAddTips{
|
||||||
|
FromUserID: req.UserID,
|
||||||
|
ToUserID: req.UserID,
|
||||||
|
}
|
||||||
|
err = s.userNotificationSender.UserCommandAddNotification(ctx, tips)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
return &pbuser.ProcessUserCommandAddResp{}, nil
|
return &pbuser.ProcessUserCommandAddResp{}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// ProcessUserCommandDelete user general function delete
|
// ProcessUserCommandDelete user general function delete
|
||||||
func (s *userServer) ProcessUserCommandDelete(ctx context.Context, req *pbuser.ProcessUserCommandDeleteReq) (*pbuser.ProcessUserCommandDeleteResp, error) {
|
func (s *userServer) ProcessUserCommandDelete(ctx context.Context, req *pbuser.ProcessUserCommandDeleteReq) (*pbuser.ProcessUserCommandDeleteResp, error) {
|
||||||
// Assuming you have a method in s.UserDatabase to delete a user command
|
err := authverify.CheckAccessV3(ctx, req.UserID)
|
||||||
err := s.UserDatabase.DeleteUserCommand(ctx, req.UserID, req.Type, req.Uuid)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
err = s.UserDatabase.DeleteUserCommand(ctx, req.UserID, req.Type, req.Uuid)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
tips := &sdkws.UserCommandDeleteTips{
|
||||||
|
FromUserID: req.UserID,
|
||||||
|
ToUserID: req.UserID,
|
||||||
|
}
|
||||||
|
err = s.userNotificationSender.UserCommandDeleteNotification(ctx, tips)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
return &pbuser.ProcessUserCommandDeleteResp{}, nil
|
return &pbuser.ProcessUserCommandDeleteResp{}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// ProcessUserCommandUpdate user general function update
|
// ProcessUserCommandUpdate user general function update
|
||||||
func (s *userServer) ProcessUserCommandUpdate(ctx context.Context, req *pbuser.ProcessUserCommandUpdateReq) (*pbuser.ProcessUserCommandUpdateResp, error) {
|
func (s *userServer) ProcessUserCommandUpdate(ctx context.Context, req *pbuser.ProcessUserCommandUpdateReq) (*pbuser.ProcessUserCommandUpdateResp, error) {
|
||||||
// Assuming you have a method in s.UserDatabase to update a user command
|
err := authverify.CheckAccessV3(ctx, req.UserID)
|
||||||
err := s.UserDatabase.UpdateUserCommand(ctx, req.UserID, req.Type, req.Uuid, req.Value)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
val := make(map[string]any)
|
||||||
|
|
||||||
|
// Map fields from eax to val
|
||||||
|
if req.Value != nil {
|
||||||
|
val["value"] = req.Value.Value
|
||||||
|
}
|
||||||
|
if req.Ex != nil {
|
||||||
|
val["ex"] = req.Ex.Value
|
||||||
|
}
|
||||||
|
|
||||||
|
// Assuming you have a method in s.UserDatabase to update a user command
|
||||||
|
err = s.UserDatabase.UpdateUserCommand(ctx, req.UserID, req.Type, req.Uuid, val)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
tips := &sdkws.UserCommandUpdateTips{
|
||||||
|
FromUserID: req.UserID,
|
||||||
|
ToUserID: req.UserID,
|
||||||
|
}
|
||||||
|
err = s.userNotificationSender.UserCommandUpdateNotification(ctx, tips)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
return &pbuser.ProcessUserCommandUpdateResp{}, nil
|
return &pbuser.ProcessUserCommandUpdateResp{}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *userServer) ProcessUserCommandGet(ctx context.Context, req *pbuser.ProcessUserCommandGetReq) (*pbuser.ProcessUserCommandGetResp, error) {
|
func (s *userServer) ProcessUserCommandGet(ctx context.Context, req *pbuser.ProcessUserCommandGetReq) (*pbuser.ProcessUserCommandGetResp, error) {
|
||||||
|
err := authverify.CheckAccessV3(ctx, req.UserID)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
// Fetch user commands from the database
|
// Fetch user commands from the database
|
||||||
commands, err := s.UserDatabase.GetUserCommands(ctx, req.UserID, req.Type)
|
commands, err := s.UserDatabase.GetUserCommands(ctx, req.UserID, req.Type)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -423,14 +480,45 @@ func (s *userServer) ProcessUserCommandGet(ctx context.Context, req *pbuser.Proc
|
|||||||
for _, command := range commands {
|
for _, command := range commands {
|
||||||
// No need to use index since command is already a pointer
|
// No need to use index since command is already a pointer
|
||||||
commandInfoSlice = append(commandInfoSlice, &pbuser.CommandInfoResp{
|
commandInfoSlice = append(commandInfoSlice, &pbuser.CommandInfoResp{
|
||||||
|
Type: command.Type,
|
||||||
Uuid: command.Uuid,
|
Uuid: command.Uuid,
|
||||||
Value: command.Value,
|
Value: command.Value,
|
||||||
CreateTime: command.CreateTime,
|
CreateTime: command.CreateTime,
|
||||||
|
Ex: command.Ex,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return the response with the slice
|
// Return the response with the slice
|
||||||
return &pbuser.ProcessUserCommandGetResp{KVArray: commandInfoSlice}, nil
|
return &pbuser.ProcessUserCommandGetResp{CommandResp: commandInfoSlice}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *userServer) ProcessUserCommandGetAll(ctx context.Context, req *pbuser.ProcessUserCommandGetAllReq) (*pbuser.ProcessUserCommandGetAllResp, error) {
|
||||||
|
err := authverify.CheckAccessV3(ctx, req.UserID)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
// Fetch user commands from the database
|
||||||
|
commands, err := s.UserDatabase.GetAllUserCommands(ctx, req.UserID)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initialize commandInfoSlice as an empty slice
|
||||||
|
commandInfoSlice := make([]*pbuser.AllCommandInfoResp, 0, len(commands))
|
||||||
|
|
||||||
|
for _, command := range commands {
|
||||||
|
// No need to use index since command is already a pointer
|
||||||
|
commandInfoSlice = append(commandInfoSlice, &pbuser.AllCommandInfoResp{
|
||||||
|
Type: command.Type,
|
||||||
|
Uuid: command.Uuid,
|
||||||
|
Value: command.Value,
|
||||||
|
CreateTime: command.CreateTime,
|
||||||
|
Ex: command.Ex,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return the response with the slice
|
||||||
|
return &pbuser.ProcessUserCommandGetAllResp{CommandResp: commandInfoSlice}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *userServer) AddNotificationAccount(ctx context.Context, req *pbuser.AddNotificationAccountReq) (*pbuser.AddNotificationAccountResp, error) {
|
func (s *userServer) AddNotificationAccount(ctx context.Context, req *pbuser.AddNotificationAccountReq) (*pbuser.AddNotificationAccountResp, error) {
|
||||||
@ -438,22 +526,28 @@ func (s *userServer) AddNotificationAccount(ctx context.Context, req *pbuser.Add
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
var userID string
|
if req.UserID == "" {
|
||||||
for i := 0; i < 20; i++ {
|
for i := 0; i < 20; i++ {
|
||||||
userId := s.genUserID()
|
userId := s.genUserID()
|
||||||
_, err := s.UserDatabase.FindWithError(ctx, []string{userId})
|
_, err := s.UserDatabase.FindWithError(ctx, []string{userId})
|
||||||
if err == nil {
|
if err == nil {
|
||||||
continue
|
continue
|
||||||
|
}
|
||||||
|
req.UserID = userId
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if req.UserID == "" {
|
||||||
|
return nil, errs.ErrInternalServer.Wrap("gen user id failed")
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
_, err := s.UserDatabase.FindWithError(ctx, []string{req.UserID})
|
||||||
|
if err == nil {
|
||||||
|
return nil, errs.ErrArgs.Wrap("userID is used")
|
||||||
}
|
}
|
||||||
userID = userId
|
|
||||||
break
|
|
||||||
}
|
|
||||||
if userID == "" {
|
|
||||||
return nil, errs.ErrInternalServer.Wrap("gen user id failed")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
user := &tablerelation.UserModel{
|
user := &tablerelation.UserModel{
|
||||||
UserID: userID,
|
UserID: req.UserID,
|
||||||
Nickname: req.NickName,
|
Nickname: req.NickName,
|
||||||
FaceURL: req.FaceURL,
|
FaceURL: req.FaceURL,
|
||||||
CreateTime: time.Now(),
|
CreateTime: time.Now(),
|
||||||
@ -463,7 +557,11 @@ func (s *userServer) AddNotificationAccount(ctx context.Context, req *pbuser.Add
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return &pbuser.AddNotificationAccountResp{}, nil
|
return &pbuser.AddNotificationAccountResp{
|
||||||
|
UserID: req.UserID,
|
||||||
|
NickName: req.NickName,
|
||||||
|
FaceURL: req.FaceURL,
|
||||||
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *userServer) UpdateNotificationAccountInfo(ctx context.Context, req *pbuser.UpdateNotificationAccountInfoReq) (*pbuser.UpdateNotificationAccountInfoResp, error) {
|
func (s *userServer) UpdateNotificationAccountInfo(ctx context.Context, req *pbuser.UpdateNotificationAccountInfoReq) (*pbuser.UpdateNotificationAccountInfoResp, error) {
|
||||||
@ -497,30 +595,33 @@ func (s *userServer) SearchNotificationAccount(ctx context.Context, req *pbuser.
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if req.NickName != "" {
|
var users []*relation.UserModel
|
||||||
users, err := s.UserDatabase.FindByNickname(ctx, req.NickName)
|
var err error
|
||||||
|
if req.Keyword != "" {
|
||||||
|
users, err = s.UserDatabase.Find(ctx, []string{req.Keyword})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
resp := s.userModelToResp(users)
|
resp := s.userModelToResp(users, req.Pagination)
|
||||||
return resp, nil
|
if resp.Total != 0 {
|
||||||
}
|
return resp, nil
|
||||||
|
}
|
||||||
if req.UserID != "" {
|
users, err = s.UserDatabase.FindByNickname(ctx, req.Keyword)
|
||||||
users, err := s.UserDatabase.Find(ctx, []string{req.UserID})
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
resp := s.userModelToResp(users)
|
resp = s.userModelToResp(users, req.Pagination)
|
||||||
|
return resp, nil
|
||||||
|
|
||||||
return resp, nil
|
return resp, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
users, err := s.UserDatabase.FindNotification(ctx, constant.AppNotificationAdmin)
|
users, err = s.UserDatabase.FindNotification(ctx, constant.AppNotificationAdmin)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
resp := s.userModelToResp(users)
|
resp := s.userModelToResp(users, req.Pagination)
|
||||||
return resp, nil
|
return resp, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -554,7 +655,7 @@ func (s *userServer) genUserID() string {
|
|||||||
return string(data)
|
return string(data)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *userServer) userModelToResp(users []*relation.UserModel) *pbuser.SearchNotificationAccountResp {
|
func (s *userServer) userModelToResp(users []*relation.UserModel, pagination pagination.Pagination) *pbuser.SearchNotificationAccountResp {
|
||||||
accounts := make([]*pbuser.NotificationAccountInfo, 0)
|
accounts := make([]*pbuser.NotificationAccountInfo, 0)
|
||||||
var total int64
|
var total int64
|
||||||
for _, v := range users {
|
for _, v := range users {
|
||||||
@ -568,5 +669,8 @@ func (s *userServer) userModelToResp(users []*relation.UserModel) *pbuser.Search
|
|||||||
total += 1
|
total += 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return &pbuser.SearchNotificationAccountResp{Total: total, NotificationAccounts: accounts}
|
|
||||||
|
notificationAccounts := utils.Paginate(accounts, int(pagination.GetPageNumber()), int(pagination.GetShowNumber()))
|
||||||
|
|
||||||
|
return &pbuser.SearchNotificationAccountResp{Total: total, NotificationAccounts: notificationAccounts}
|
||||||
}
|
}
|
||||||
|
@ -41,7 +41,7 @@ const (
|
|||||||
CallbackBeforeUpdateUserInfoExCommand = "callbackBeforeUpdateUserInfoExCommand"
|
CallbackBeforeUpdateUserInfoExCommand = "callbackBeforeUpdateUserInfoExCommand"
|
||||||
CallbackBeforeUserRegisterCommand = "callbackBeforeUserRegisterCommand"
|
CallbackBeforeUserRegisterCommand = "callbackBeforeUserRegisterCommand"
|
||||||
CallbackAfterUserRegisterCommand = "callbackAfterUserRegisterCommand"
|
CallbackAfterUserRegisterCommand = "callbackAfterUserRegisterCommand"
|
||||||
CallbackTransferGroupOwnerAfter = "callbackTransferGroupOwnerAfter"
|
CallbackAfterTransferGroupOwner = "callbackAfterTransferGroupOwner"
|
||||||
CallbackBeforeSetFriendRemark = "callbackBeforeSetFriendRemark"
|
CallbackBeforeSetFriendRemark = "callbackBeforeSetFriendRemark"
|
||||||
CallbackAfterSetFriendRemark = "callbackAfterSetFriendRemark"
|
CallbackAfterSetFriendRemark = "callbackAfterSetFriendRemark"
|
||||||
CallbackSingleMsgRead = "callbackSingleMsgRead"
|
CallbackSingleMsgRead = "callbackSingleMsgRead"
|
||||||
|
@ -296,7 +296,7 @@ type configStruct struct {
|
|||||||
CallbackKillGroupMember CallBackConfig `yaml:"killGroupMember"`
|
CallbackKillGroupMember CallBackConfig `yaml:"killGroupMember"`
|
||||||
CallbackDismissGroup CallBackConfig `yaml:"dismissGroup"`
|
CallbackDismissGroup CallBackConfig `yaml:"dismissGroup"`
|
||||||
CallbackBeforeJoinGroup CallBackConfig `yaml:"joinGroup"`
|
CallbackBeforeJoinGroup CallBackConfig `yaml:"joinGroup"`
|
||||||
CallbackTransferGroupOwnerAfter CallBackConfig `yaml:"transferGroupOwner"`
|
CallbackAfterTransferGroupOwner CallBackConfig `yaml:"transferGroupOwner"`
|
||||||
CallbackBeforeInviteUserToGroup CallBackConfig `yaml:"beforeInviteUserToGroup"`
|
CallbackBeforeInviteUserToGroup CallBackConfig `yaml:"beforeInviteUserToGroup"`
|
||||||
CallbackAfterJoinGroup CallBackConfig `yaml:"joinGroupAfter"`
|
CallbackAfterJoinGroup CallBackConfig `yaml:"joinGroupAfter"`
|
||||||
CallbackAfterSetGroupInfo CallBackConfig `yaml:"setGroupInfoAfter"`
|
CallbackAfterSetGroupInfo CallBackConfig `yaml:"setGroupInfoAfter"`
|
||||||
|
14
pkg/common/db/cache/friend.go
vendored
14
pkg/common/db/cache/friend.go
vendored
@ -44,6 +44,8 @@ type FriendCache interface {
|
|||||||
GetFriend(ctx context.Context, ownerUserID, friendUserID string) (friend *relationtb.FriendModel, err error)
|
GetFriend(ctx context.Context, ownerUserID, friendUserID string) (friend *relationtb.FriendModel, err error)
|
||||||
// Delete friend when friend info changed
|
// Delete friend when friend info changed
|
||||||
DelFriend(ownerUserID, friendUserID string) FriendCache
|
DelFriend(ownerUserID, friendUserID string) FriendCache
|
||||||
|
// Delete friends when friends' info changed
|
||||||
|
DelFriends(ownerUserID string, friendUserIDs []string) FriendCache
|
||||||
}
|
}
|
||||||
|
|
||||||
// FriendCacheRedis is an implementation of the FriendCache interface using Redis.
|
// FriendCacheRedis is an implementation of the FriendCache interface using Redis.
|
||||||
@ -152,3 +154,15 @@ func (f *FriendCacheRedis) DelFriend(ownerUserID, friendUserID string) FriendCac
|
|||||||
|
|
||||||
return newFriendCache
|
return newFriendCache
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DelFriends deletes multiple friend infos from the cache.
|
||||||
|
func (f *FriendCacheRedis) DelFriends(ownerUserID string, friendUserIDs []string) FriendCache {
|
||||||
|
newFriendCache := f.NewCache()
|
||||||
|
|
||||||
|
for _, friendUserID := range friendUserIDs {
|
||||||
|
key := f.getFriendKey(ownerUserID, friendUserID)
|
||||||
|
newFriendCache.AddKeys(key) // Assuming AddKeys marks the keys for deletion
|
||||||
|
}
|
||||||
|
|
||||||
|
return newFriendCache
|
||||||
|
}
|
||||||
|
@ -279,7 +279,7 @@ func (c *conversationDatabase) CreateGroupChatConversation(ctx context.Context,
|
|||||||
for _, v := range existConversationUserIDs {
|
for _, v := range existConversationUserIDs {
|
||||||
cache = cache.DelConversations(v, conversationID)
|
cache = cache.DelConversations(v, conversationID)
|
||||||
}
|
}
|
||||||
return c.cache.ExecDel(ctx)
|
return cache.ExecDel(ctx)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -74,15 +74,8 @@ type FriendDatabase interface {
|
|||||||
// FindBothFriendRequests finds friend requests sent and received
|
// FindBothFriendRequests finds friend requests sent and received
|
||||||
FindBothFriendRequests(ctx context.Context, fromUserID, toUserID string) (friends []*relation.FriendRequestModel, err error)
|
FindBothFriendRequests(ctx context.Context, fromUserID, toUserID string) (friends []*relation.FriendRequestModel, err error)
|
||||||
|
|
||||||
// UpdateFriendPinStatus updates the pinned status of a friend
|
// UpdateFriends updates fields for friends
|
||||||
UpdateFriendPinStatus(ctx context.Context, ownerUserID string, friendUserID string, isPinned bool) (err error)
|
UpdateFriends(ctx context.Context, ownerUserID string, friendUserIDs []string, val map[string]any) (err error)
|
||||||
|
|
||||||
// UpdateFriendRemark updates the remark for a friend
|
|
||||||
UpdateFriendRemark(ctx context.Context, ownerUserID string, friendUserID string, remark string) (err error)
|
|
||||||
|
|
||||||
// UpdateFriendEx updates the 'ex' field for a friend
|
|
||||||
UpdateFriendEx(ctx context.Context, ownerUserID string, friendUserID string, ex string) (err error)
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type friendDatabase struct {
|
type friendDatabase struct {
|
||||||
@ -323,21 +316,12 @@ func (f *friendDatabase) FindFriendUserIDs(ctx context.Context, ownerUserID stri
|
|||||||
func (f *friendDatabase) FindBothFriendRequests(ctx context.Context, fromUserID, toUserID string) (friends []*relation.FriendRequestModel, err error) {
|
func (f *friendDatabase) FindBothFriendRequests(ctx context.Context, fromUserID, toUserID string) (friends []*relation.FriendRequestModel, err error) {
|
||||||
return f.friendRequest.FindBothFriendRequests(ctx, fromUserID, toUserID)
|
return f.friendRequest.FindBothFriendRequests(ctx, fromUserID, toUserID)
|
||||||
}
|
}
|
||||||
func (f *friendDatabase) UpdateFriendPinStatus(ctx context.Context, ownerUserID string, friendUserID string, isPinned bool) (err error) {
|
func (f *friendDatabase) UpdateFriends(ctx context.Context, ownerUserID string, friendUserIDs []string, val map[string]any) (err error) {
|
||||||
if err := f.friend.UpdatePinStatus(ctx, ownerUserID, friendUserID, isPinned); err != nil {
|
if len(val) == 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
if err := f.friend.UpdateFriends(ctx, ownerUserID, friendUserIDs, val); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return f.cache.DelFriend(ownerUserID, friendUserID).ExecDel(ctx)
|
return f.cache.DelFriends(ownerUserID, friendUserIDs).ExecDel(ctx)
|
||||||
}
|
|
||||||
func (f *friendDatabase) UpdateFriendRemark(ctx context.Context, ownerUserID string, friendUserID string, remark string) (err error) {
|
|
||||||
if err := f.friend.UpdateFriendRemark(ctx, ownerUserID, friendUserID, remark); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return f.cache.DelFriend(ownerUserID, friendUserID).ExecDel(ctx)
|
|
||||||
}
|
|
||||||
func (f *friendDatabase) UpdateFriendEx(ctx context.Context, ownerUserID string, friendUserID string, ex string) (err error) {
|
|
||||||
if err := f.friend.UpdateFriendEx(ctx, ownerUserID, friendUserID, ex); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return f.cache.DelFriend(ownerUserID, friendUserID).ExecDel(ctx)
|
|
||||||
}
|
}
|
||||||
|
@ -50,6 +50,8 @@ type UserDatabase interface {
|
|||||||
UpdateByMap(ctx context.Context, userID string, args map[string]any) (err error)
|
UpdateByMap(ctx context.Context, userID string, args map[string]any) (err error)
|
||||||
// Page If not found, no error is returned
|
// Page If not found, no error is returned
|
||||||
Page(ctx context.Context, pagination pagination.Pagination) (count int64, users []*relation.UserModel, err error)
|
Page(ctx context.Context, pagination pagination.Pagination) (count int64, users []*relation.UserModel, err error)
|
||||||
|
// FindUser
|
||||||
|
PageFindUser(ctx context.Context, level int64, pagination pagination.Pagination) (count int64, users []*relation.UserModel, err error)
|
||||||
// IsExist true as long as one exists
|
// IsExist true as long as one exists
|
||||||
IsExist(ctx context.Context, userIDs []string) (exist bool, err error)
|
IsExist(ctx context.Context, userIDs []string) (exist bool, err error)
|
||||||
// GetAllUserID Get all user IDs
|
// GetAllUserID Get all user IDs
|
||||||
@ -76,10 +78,11 @@ type UserDatabase interface {
|
|||||||
SetUserStatus(ctx context.Context, userID string, status, platformID int32) error
|
SetUserStatus(ctx context.Context, userID string, status, platformID int32) error
|
||||||
|
|
||||||
//CRUD user command
|
//CRUD user command
|
||||||
AddUserCommand(ctx context.Context, userID string, Type int32, UUID string, value string) error
|
AddUserCommand(ctx context.Context, userID string, Type int32, UUID string, value string, ex string) error
|
||||||
DeleteUserCommand(ctx context.Context, userID string, Type int32, UUID string) error
|
DeleteUserCommand(ctx context.Context, userID string, Type int32, UUID string) error
|
||||||
UpdateUserCommand(ctx context.Context, userID string, Type int32, UUID string, value string) error
|
UpdateUserCommand(ctx context.Context, userID string, Type int32, UUID string, val map[string]any) error
|
||||||
GetUserCommands(ctx context.Context, userID string, Type int32) ([]*user.CommandInfoResp, error)
|
GetUserCommands(ctx context.Context, userID string, Type int32) ([]*user.CommandInfoResp, error)
|
||||||
|
GetAllUserCommands(ctx context.Context, userID string) ([]*user.AllCommandInfoResp, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
type userDatabase struct {
|
type userDatabase struct {
|
||||||
@ -182,6 +185,10 @@ func (u *userDatabase) Page(ctx context.Context, pagination pagination.Paginatio
|
|||||||
return u.userDB.Page(ctx, pagination)
|
return u.userDB.Page(ctx, pagination)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (u *userDatabase) PageFindUser(ctx context.Context, level int64, pagination pagination.Pagination) (count int64, users []*relation.UserModel, err error) {
|
||||||
|
return u.userDB.PageFindUser(ctx, level, pagination)
|
||||||
|
}
|
||||||
|
|
||||||
// IsExist Does userIDs exist? As long as there is one, it will be true.
|
// IsExist Does userIDs exist? As long as there is one, it will be true.
|
||||||
func (u *userDatabase) IsExist(ctx context.Context, userIDs []string) (exist bool, err error) {
|
func (u *userDatabase) IsExist(ctx context.Context, userIDs []string) (exist bool, err error) {
|
||||||
users, err := u.userDB.Find(ctx, userIDs)
|
users, err := u.userDB.Find(ctx, userIDs)
|
||||||
@ -253,16 +260,20 @@ func (u *userDatabase) GetUserStatus(ctx context.Context, userIDs []string) ([]*
|
|||||||
func (u *userDatabase) SetUserStatus(ctx context.Context, userID string, status, platformID int32) error {
|
func (u *userDatabase) SetUserStatus(ctx context.Context, userID string, status, platformID int32) error {
|
||||||
return u.cache.SetUserStatus(ctx, userID, status, platformID)
|
return u.cache.SetUserStatus(ctx, userID, status, platformID)
|
||||||
}
|
}
|
||||||
func (u *userDatabase) AddUserCommand(ctx context.Context, userID string, Type int32, UUID string, value string) error {
|
func (u *userDatabase) AddUserCommand(ctx context.Context, userID string, Type int32, UUID string, value string, ex string) error {
|
||||||
return u.userDB.AddUserCommand(ctx, userID, Type, UUID, value)
|
return u.userDB.AddUserCommand(ctx, userID, Type, UUID, value, ex)
|
||||||
}
|
}
|
||||||
func (u *userDatabase) DeleteUserCommand(ctx context.Context, userID string, Type int32, UUID string) error {
|
func (u *userDatabase) DeleteUserCommand(ctx context.Context, userID string, Type int32, UUID string) error {
|
||||||
return u.userDB.DeleteUserCommand(ctx, userID, Type, UUID)
|
return u.userDB.DeleteUserCommand(ctx, userID, Type, UUID)
|
||||||
}
|
}
|
||||||
func (u *userDatabase) UpdateUserCommand(ctx context.Context, userID string, Type int32, UUID string, value string) error {
|
func (u *userDatabase) UpdateUserCommand(ctx context.Context, userID string, Type int32, UUID string, val map[string]any) error {
|
||||||
return u.userDB.UpdateUserCommand(ctx, userID, Type, UUID, value)
|
return u.userDB.UpdateUserCommand(ctx, userID, Type, UUID, val)
|
||||||
}
|
}
|
||||||
func (u *userDatabase) GetUserCommands(ctx context.Context, userID string, Type int32) ([]*user.CommandInfoResp, error) {
|
func (u *userDatabase) GetUserCommands(ctx context.Context, userID string, Type int32) ([]*user.CommandInfoResp, error) {
|
||||||
commands, err := u.userDB.GetUserCommand(ctx, userID, Type)
|
commands, err := u.userDB.GetUserCommand(ctx, userID, Type)
|
||||||
return commands, err
|
return commands, err
|
||||||
}
|
}
|
||||||
|
func (u *userDatabase) GetAllUserCommands(ctx context.Context, userID string) ([]*user.AllCommandInfoResp, error) {
|
||||||
|
commands, err := u.userDB.GetAllUserCommand(ctx, userID)
|
||||||
|
return commands, err
|
||||||
|
}
|
||||||
|
@ -16,7 +16,6 @@ package mgo
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"github.com/OpenIMSDK/tools/errs"
|
|
||||||
"github.com/OpenIMSDK/tools/mgoutil"
|
"github.com/OpenIMSDK/tools/mgoutil"
|
||||||
"github.com/OpenIMSDK/tools/pagination"
|
"github.com/OpenIMSDK/tools/pagination"
|
||||||
"go.mongodb.org/mongo-driver/mongo/options"
|
"go.mongodb.org/mongo-driver/mongo/options"
|
||||||
@ -144,49 +143,22 @@ func (f *FriendMgo) FindFriendUserIDs(ctx context.Context, ownerUserID string) (
|
|||||||
return mgoutil.Find[string](ctx, f.coll, filter, options.Find().SetProjection(bson.M{"_id": 0, "friend_user_id": 1}))
|
return mgoutil.Find[string](ctx, f.coll, filter, options.Find().SetProjection(bson.M{"_id": 0, "friend_user_id": 1}))
|
||||||
}
|
}
|
||||||
|
|
||||||
// UpdatePinStatus update friend's pin status
|
func (f *FriendMgo) UpdateFriends(ctx context.Context, ownerUserID string, friendUserIDs []string, val map[string]any) error {
|
||||||
func (f *FriendMgo) UpdatePinStatus(ctx context.Context, ownerUserID string, friendUserID string, isPinned bool) (err error) {
|
// Ensure there are IDs to update
|
||||||
|
if len(friendUserIDs) == 0 {
|
||||||
filter := bson.M{"owner_user_id": ownerUserID, "friend_user_id": friendUserID}
|
return nil // Or return an error if you expect there to always be IDs
|
||||||
// Create an update operation to set the "is_pinned" field to isPinned for all documents.
|
|
||||||
update := bson.M{"$set": bson.M{"is_pinned": isPinned}}
|
|
||||||
|
|
||||||
// Perform the update operation for all documents in the collection.
|
|
||||||
_, err = f.coll.UpdateMany(ctx, filter, update)
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
return errs.Wrap(err, "update pin error")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
// Create a filter to match documents with the specified ownerUserID and any of the friendUserIDs
|
||||||
}
|
filter := bson.M{
|
||||||
func (f *FriendMgo) UpdateFriendRemark(ctx context.Context, ownerUserID string, friendUserID string, remark string) (err error) {
|
"owner_user_id": ownerUserID,
|
||||||
|
"friend_user_id": bson.M{"$in": friendUserIDs},
|
||||||
filter := bson.M{"owner_user_id": ownerUserID, "friend_user_id": friendUserID}
|
|
||||||
// Create an update operation to set the "is_pinned" field to isPinned for all documents.
|
|
||||||
update := bson.M{"$set": bson.M{"remark": remark}}
|
|
||||||
|
|
||||||
// Perform the update operation for all documents in the collection.
|
|
||||||
_, err = f.coll.UpdateMany(ctx, filter, update)
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
return errs.Wrap(err, "update remark error")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
// Create an update document
|
||||||
}
|
update := bson.M{"$set": val}
|
||||||
func (f *FriendMgo) UpdateFriendEx(ctx context.Context, ownerUserID string, friendUserID string, ex string) (err error) {
|
|
||||||
|
// Perform the update operation for all matching documents
|
||||||
filter := bson.M{"owner_user_id": ownerUserID, "friend_user_id": friendUserID}
|
_, err := mgoutil.UpdateMany(ctx, f.coll, filter, update)
|
||||||
// Create an update operation to set the "is_pinned" field to isPinned for all documents.
|
return err
|
||||||
update := bson.M{"$set": bson.M{"ex": ex}}
|
|
||||||
|
|
||||||
// Perform the update operation for all documents in the collection.
|
|
||||||
_, err = f.coll.UpdateMany(ctx, filter, update)
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
return errs.Wrap(err, "update ex error")
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
@ -17,6 +17,7 @@ package mgo
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"github.com/OpenIMSDK/protocol/user"
|
"github.com/OpenIMSDK/protocol/user"
|
||||||
|
"github.com/OpenIMSDK/tools/errs"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/OpenIMSDK/tools/mgoutil"
|
"github.com/OpenIMSDK/tools/mgoutil"
|
||||||
@ -77,6 +78,10 @@ func (u *UserMgo) Page(ctx context.Context, pagination pagination.Pagination) (c
|
|||||||
return mgoutil.FindPage[*relation.UserModel](ctx, u.coll, bson.M{}, pagination)
|
return mgoutil.FindPage[*relation.UserModel](ctx, u.coll, bson.M{}, pagination)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (u *UserMgo) PageFindUser(ctx context.Context, level int64, pagination pagination.Pagination) (count int64, users []*relation.UserModel, err error) {
|
||||||
|
return mgoutil.FindPage[*relation.UserModel](ctx, u.coll, bson.M{"app_manger_level": level}, pagination)
|
||||||
|
}
|
||||||
|
|
||||||
func (u *UserMgo) GetAllUserID(ctx context.Context, pagination pagination.Pagination) (int64, []string, error) {
|
func (u *UserMgo) GetAllUserID(ctx context.Context, pagination pagination.Pagination) (int64, []string, error) {
|
||||||
return mgoutil.FindPage[string](ctx, u.coll, bson.M{}, pagination, options.Find().SetProjection(bson.M{"user_id": 1}))
|
return mgoutil.FindPage[string](ctx, u.coll, bson.M{}, pagination, options.Find().SetProjection(bson.M{"user_id": 1}))
|
||||||
}
|
}
|
||||||
@ -96,7 +101,7 @@ func (u *UserMgo) CountTotal(ctx context.Context, before *time.Time) (count int6
|
|||||||
return mgoutil.Count(ctx, u.coll, bson.M{"create_time": bson.M{"$lt": before}})
|
return mgoutil.Count(ctx, u.coll, bson.M{"create_time": bson.M{"$lt": before}})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (u *UserMgo) AddUserCommand(ctx context.Context, userID string, Type int32, UUID string, value string) error {
|
func (u *UserMgo) AddUserCommand(ctx context.Context, userID string, Type int32, UUID string, value string, ex string) error {
|
||||||
collection := u.coll.Database().Collection("userCommands")
|
collection := u.coll.Database().Collection("userCommands")
|
||||||
|
|
||||||
// Create a new document instead of updating an existing one
|
// Create a new document instead of updating an existing one
|
||||||
@ -106,28 +111,48 @@ func (u *UserMgo) AddUserCommand(ctx context.Context, userID string, Type int32,
|
|||||||
"uuid": UUID,
|
"uuid": UUID,
|
||||||
"createTime": time.Now().Unix(), // assuming you want the creation time in Unix timestamp
|
"createTime": time.Now().Unix(), // assuming you want the creation time in Unix timestamp
|
||||||
"value": value,
|
"value": value,
|
||||||
|
"ex": ex,
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err := collection.InsertOne(ctx, doc)
|
_, err := collection.InsertOne(ctx, doc)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (u *UserMgo) DeleteUserCommand(ctx context.Context, userID string, Type int32, UUID string) error {
|
func (u *UserMgo) DeleteUserCommand(ctx context.Context, userID string, Type int32, UUID string) error {
|
||||||
collection := u.coll.Database().Collection("userCommands")
|
collection := u.coll.Database().Collection("userCommands")
|
||||||
|
|
||||||
filter := bson.M{"userID": userID, "type": Type, "uuid": UUID}
|
filter := bson.M{"userID": userID, "type": Type, "uuid": UUID}
|
||||||
|
|
||||||
_, err := collection.DeleteOne(ctx, filter)
|
result, err := collection.DeleteOne(ctx, filter)
|
||||||
|
if result.DeletedCount == 0 {
|
||||||
|
// No records found to update
|
||||||
|
return errs.Wrap(errs.ErrRecordNotFound)
|
||||||
|
}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
func (u *UserMgo) UpdateUserCommand(ctx context.Context, userID string, Type int32, UUID string, value string) error {
|
func (u *UserMgo) UpdateUserCommand(ctx context.Context, userID string, Type int32, UUID string, val map[string]any) error {
|
||||||
|
if len(val) == 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
collection := u.coll.Database().Collection("userCommands")
|
collection := u.coll.Database().Collection("userCommands")
|
||||||
|
|
||||||
filter := bson.M{"userID": userID, "type": Type, "uuid": UUID}
|
filter := bson.M{"userID": userID, "type": Type, "uuid": UUID}
|
||||||
update := bson.M{"$set": bson.M{"value": value}}
|
update := bson.M{"$set": val}
|
||||||
|
|
||||||
_, err := collection.UpdateOne(ctx, filter, update)
|
result, err := collection.UpdateOne(ctx, filter, update)
|
||||||
return err
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if result.MatchedCount == 0 {
|
||||||
|
// No records found to update
|
||||||
|
return errs.Wrap(errs.ErrRecordNotFound)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (u *UserMgo) GetUserCommand(ctx context.Context, userID string, Type int32) ([]*user.CommandInfoResp, error) {
|
func (u *UserMgo) GetUserCommand(ctx context.Context, userID string, Type int32) ([]*user.CommandInfoResp, error) {
|
||||||
collection := u.coll.Database().Collection("userCommands")
|
collection := u.coll.Database().Collection("userCommands")
|
||||||
filter := bson.M{"userID": userID, "type": Type}
|
filter := bson.M{"userID": userID, "type": Type}
|
||||||
@ -143,19 +168,23 @@ func (u *UserMgo) GetUserCommand(ctx context.Context, userID string, Type int32)
|
|||||||
|
|
||||||
for cursor.Next(ctx) {
|
for cursor.Next(ctx) {
|
||||||
var document struct {
|
var document struct {
|
||||||
|
Type int32 `bson:"type"`
|
||||||
UUID string `bson:"uuid"`
|
UUID string `bson:"uuid"`
|
||||||
Value string `bson:"value"`
|
Value string `bson:"value"`
|
||||||
CreateTime int64 `bson:"createTime"`
|
CreateTime int64 `bson:"createTime"`
|
||||||
|
Ex string `bson:"ex"`
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := cursor.Decode(&document); err != nil {
|
if err := cursor.Decode(&document); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
commandInfo := &user.CommandInfoResp{ // Change here: use a pointer to the struct
|
commandInfo := &user.CommandInfoResp{
|
||||||
|
Type: document.Type,
|
||||||
Uuid: document.UUID,
|
Uuid: document.UUID,
|
||||||
Value: document.Value,
|
Value: document.Value,
|
||||||
CreateTime: document.CreateTime,
|
CreateTime: document.CreateTime,
|
||||||
|
Ex: document.Ex,
|
||||||
}
|
}
|
||||||
|
|
||||||
commands = append(commands, commandInfo)
|
commands = append(commands, commandInfo)
|
||||||
@ -167,7 +196,48 @@ func (u *UserMgo) GetUserCommand(ctx context.Context, userID string, Type int32)
|
|||||||
|
|
||||||
return commands, nil
|
return commands, nil
|
||||||
}
|
}
|
||||||
|
func (u *UserMgo) GetAllUserCommand(ctx context.Context, userID string) ([]*user.AllCommandInfoResp, error) {
|
||||||
|
collection := u.coll.Database().Collection("userCommands")
|
||||||
|
filter := bson.M{"userID": userID}
|
||||||
|
|
||||||
|
cursor, err := collection.Find(ctx, filter)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer cursor.Close(ctx)
|
||||||
|
|
||||||
|
// Initialize commands as a slice of pointers
|
||||||
|
commands := []*user.AllCommandInfoResp{}
|
||||||
|
|
||||||
|
for cursor.Next(ctx) {
|
||||||
|
var document struct {
|
||||||
|
Type int32 `bson:"type"`
|
||||||
|
UUID string `bson:"uuid"`
|
||||||
|
Value string `bson:"value"`
|
||||||
|
CreateTime int64 `bson:"createTime"`
|
||||||
|
Ex string `bson:"ex"`
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := cursor.Decode(&document); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
commandInfo := &user.AllCommandInfoResp{
|
||||||
|
Type: document.Type,
|
||||||
|
Uuid: document.UUID,
|
||||||
|
Value: document.Value,
|
||||||
|
CreateTime: document.CreateTime,
|
||||||
|
Ex: document.Ex,
|
||||||
|
}
|
||||||
|
|
||||||
|
commands = append(commands, commandInfo)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := cursor.Err(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return commands, nil
|
||||||
|
}
|
||||||
func (u *UserMgo) CountRangeEverydayTotal(ctx context.Context, start time.Time, end time.Time) (map[string]int64, error) {
|
func (u *UserMgo) CountRangeEverydayTotal(ctx context.Context, start time.Time, end time.Time) (map[string]int64, error) {
|
||||||
pipeline := bson.A{
|
pipeline := bson.A{
|
||||||
bson.M{
|
bson.M{
|
||||||
|
@ -57,10 +57,6 @@ type FriendModelInterface interface {
|
|||||||
FindInWhoseFriends(ctx context.Context, friendUserID string, pagination pagination.Pagination) (total int64, friends []*FriendModel, err error)
|
FindInWhoseFriends(ctx context.Context, friendUserID string, pagination pagination.Pagination) (total int64, friends []*FriendModel, err error)
|
||||||
// FindFriendUserIDs retrieves a list of friend user IDs for a given owner.
|
// FindFriendUserIDs retrieves a list of friend user IDs for a given owner.
|
||||||
FindFriendUserIDs(ctx context.Context, ownerUserID string) (friendUserIDs []string, err error)
|
FindFriendUserIDs(ctx context.Context, ownerUserID string) (friendUserIDs []string, err error)
|
||||||
// UpdatePinStatus update friend's pin status
|
// UpdateFriends update friends' fields
|
||||||
UpdatePinStatus(ctx context.Context, ownerUserID string, friendUserID string, isPinned bool) (err error)
|
UpdateFriends(ctx context.Context, ownerUserID string, friendUserIDs []string, val map[string]any) (err error)
|
||||||
// UpdateFriendRemark update friend's remark
|
|
||||||
UpdateFriendRemark(ctx context.Context, ownerUserID string, friendUserID string, remark string) (err error)
|
|
||||||
// UpdateFriendEx update friend's ex
|
|
||||||
UpdateFriendEx(ctx context.Context, ownerUserID string, friendUserID string, ex string) (err error)
|
|
||||||
}
|
}
|
||||||
|
@ -56,6 +56,7 @@ type UserModelInterface interface {
|
|||||||
TakeNotification(ctx context.Context, level int64) (user []*UserModel, err error)
|
TakeNotification(ctx context.Context, level int64) (user []*UserModel, err error)
|
||||||
TakeByNickname(ctx context.Context, nickname string) (user []*UserModel, err error)
|
TakeByNickname(ctx context.Context, nickname string) (user []*UserModel, err error)
|
||||||
Page(ctx context.Context, pagination pagination.Pagination) (count int64, users []*UserModel, err error)
|
Page(ctx context.Context, pagination pagination.Pagination) (count int64, users []*UserModel, err error)
|
||||||
|
PageFindUser(ctx context.Context, level int64, pagination pagination.Pagination) (count int64, users []*UserModel, err error)
|
||||||
Exist(ctx context.Context, userID string) (exist bool, err error)
|
Exist(ctx context.Context, userID string) (exist bool, err error)
|
||||||
GetAllUserID(ctx context.Context, pagination pagination.Pagination) (count int64, userIDs []string, err error)
|
GetAllUserID(ctx context.Context, pagination pagination.Pagination) (count int64, userIDs []string, err error)
|
||||||
GetUserGlobalRecvMsgOpt(ctx context.Context, userID string) (opt int, err error)
|
GetUserGlobalRecvMsgOpt(ctx context.Context, userID string) (opt int, err error)
|
||||||
@ -64,8 +65,9 @@ type UserModelInterface interface {
|
|||||||
// 获取范围内用户增量
|
// 获取范围内用户增量
|
||||||
CountRangeEverydayTotal(ctx context.Context, start time.Time, end time.Time) (map[string]int64, error)
|
CountRangeEverydayTotal(ctx context.Context, start time.Time, end time.Time) (map[string]int64, error)
|
||||||
//CRUD user command
|
//CRUD user command
|
||||||
AddUserCommand(ctx context.Context, userID string, Type int32, UUID string, value string) error
|
AddUserCommand(ctx context.Context, userID string, Type int32, UUID string, value string, ex string) error
|
||||||
DeleteUserCommand(ctx context.Context, userID string, Type int32, UUID string) error
|
DeleteUserCommand(ctx context.Context, userID string, Type int32, UUID string) error
|
||||||
UpdateUserCommand(ctx context.Context, userID string, Type int32, UUID string, value string) error
|
UpdateUserCommand(ctx context.Context, userID string, Type int32, UUID string, val map[string]any) error
|
||||||
GetUserCommand(ctx context.Context, userID string, Type int32) ([]*user.CommandInfoResp, error)
|
GetUserCommand(ctx context.Context, userID string, Type int32) ([]*user.CommandInfoResp, error)
|
||||||
|
GetAllUserCommand(ctx context.Context, userID string) ([]*user.AllCommandInfoResp, error)
|
||||||
}
|
}
|
||||||
|
@ -197,7 +197,7 @@ func (f *FriendNotificationSender) FriendRemarkSetNotification(ctx context.Conte
|
|||||||
return f.Notification(ctx, fromUserID, toUserID, constant.FriendRemarkSetNotification, &tips)
|
return f.Notification(ctx, fromUserID, toUserID, constant.FriendRemarkSetNotification, &tips)
|
||||||
}
|
}
|
||||||
func (f *FriendNotificationSender) FriendsInfoUpdateNotification(ctx context.Context, toUserID string, friendIDs []string) error {
|
func (f *FriendNotificationSender) FriendsInfoUpdateNotification(ctx context.Context, toUserID string, friendIDs []string) error {
|
||||||
tips := sdkws.FriendsInfoUpdateTips{}
|
tips := sdkws.FriendsInfoUpdateTips{FromToUserID: &sdkws.FromToUserID{}}
|
||||||
tips.FromToUserID.ToUserID = toUserID
|
tips.FromToUserID.ToUserID = toUserID
|
||||||
tips.FriendIDs = friendIDs
|
tips.FriendIDs = friendIDs
|
||||||
return f.Notification(ctx, toUserID, toUserID, constant.FriendsInfoUpdateNotification, &tips)
|
return f.Notification(ctx, toUserID, toUserID, constant.FriendsInfoUpdateNotification, &tips)
|
||||||
|
@ -103,3 +103,21 @@ func (u *UserNotificationSender) UserStatusChangeNotification(
|
|||||||
) error {
|
) error {
|
||||||
return u.Notification(ctx, tips.FromUserID, tips.ToUserID, constant.UserStatusChangeNotification, tips)
|
return u.Notification(ctx, tips.FromUserID, tips.ToUserID, constant.UserStatusChangeNotification, tips)
|
||||||
}
|
}
|
||||||
|
func (u *UserNotificationSender) UserCommandUpdateNotification(
|
||||||
|
ctx context.Context,
|
||||||
|
tips *sdkws.UserCommandUpdateTips,
|
||||||
|
) error {
|
||||||
|
return u.Notification(ctx, tips.FromUserID, tips.ToUserID, constant.UserCommandUpdateNotification, tips)
|
||||||
|
}
|
||||||
|
func (u *UserNotificationSender) UserCommandAddNotification(
|
||||||
|
ctx context.Context,
|
||||||
|
tips *sdkws.UserCommandAddTips,
|
||||||
|
) error {
|
||||||
|
return u.Notification(ctx, tips.FromUserID, tips.ToUserID, constant.UserCommandAddNotification, tips)
|
||||||
|
}
|
||||||
|
func (u *UserNotificationSender) UserCommandDeleteNotification(
|
||||||
|
ctx context.Context,
|
||||||
|
tips *sdkws.UserCommandDeleteTips,
|
||||||
|
) error {
|
||||||
|
return u.Notification(ctx, tips.FromUserID, tips.ToUserID, constant.UserCommandDeleteNotification, tips)
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user