Merge remote-tracking branch 'origin/main' into localcache
This commit is contained in:
commit
18ad656087
|
@ -161,7 +161,8 @@ jobs:
|
|||
```
|
||||
${{ env.containers }}
|
||||
```
|
||||
GITHUB_TOKEN: ${{ secrets.BOT_GITHUB_TOKEN }}
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
continue-on-error: true
|
||||
|
||||
execute-scripts:
|
||||
name: Execute OpenIM Script On ${{ matrix.os }}
|
||||
|
@ -285,4 +286,4 @@ jobs:
|
|||
id: docker_processes
|
||||
run: |
|
||||
sudo docker images
|
||||
sudo docker ps
|
||||
sudo docker ps
|
||||
|
|
|
@ -35,52 +35,62 @@
|
|||
|
||||
## Ⓜ️ 关于 OpenIM
|
||||
|
||||
OpenIM 不仅仅是一个开源的即时消息组件,它是你的应用程序生态系统的一个不可或缺的部分。查看下面的图表,了解 AppServer、AppClient、OpenIMServer 和 OpenIMSDK 是如何交互的。
|
||||
OpenIM 是一个专门设计用于在应用程序中集成聊天、音视频通话、通知以及AI聊天机器人等通信功能的服务平台。它通过提供一系列强大的API和Webhooks,使开发者可以轻松地在他们的应用中加入这些交互特性。OpenIM 本身并不是一个独立运行的聊天应用,而是作为一个平台,为其他应用提供支持,实现丰富的通信功能。下图展示 AppServer、AppClient、OpenIMServer 和 OpenIMSDK 之间的交互关系来具体说明。
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
![App-OpenIM 关系](./docs/images/oepnim-design.png)
|
||||
|
||||
## 🚀 关于 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)**
|
||||
|
||||
## 🌐 关于 OpenIMServer
|
||||
|
||||
精心用 Golang 开发的 **OpenIMServer** 通过多重方式确保了卓越的即时消息服务器能力:
|
||||
|
||||
+ **模块组成**:它由多个模块组成,例如网关和多个 RPC 服务,提供一个多功能的消息环境。
|
||||
+ **微服务架构**:支持集群模式,确保出色的性能和可伸缩性,以有效管理各个实例间的通信。
|
||||
+ **多样的部署选项**:适应你的操作偏好,通过源代码、Kubernetes 或 Docker 提供部署选项。
|
||||
+ **OpenIMServer** 具有以下特点:
|
||||
- 🌐 微服务架构:支持集群模式,包括网关(gateway)和多个rpc服务。
|
||||
- 🚀 部署方式多样:支持源代码、kubernetes或docker部署。
|
||||
- 海量用户支持:十万超级大群,千万用户,及百亿消息
|
||||
|
||||
### 增强的业务功能:
|
||||
|
||||
+ **REST API**:OpenIMServer 为业务系统提供 REST API,旨在通过后端接口为您的操作提供附加功能,如群组创建和消息推送。
|
||||
+ **回调**:为了扩展其在各种业务形式中的实用性,OpenIMServer 提供了回调能力。即,在事件发生之前或之后,它向业务服务器发送请求,比如发送消息,丰富通信过程中的交互和数据交换流。
|
||||
+ **REST API**:OpenIMServer 提供了REST API供业务系统使用,旨在赋予业务更多功能,例如通过后台接口建立群组、发送推送消息等。
|
||||
+ **Webhooks**:OpenIMServer提供了回调能力以扩展更多的业务形态,所谓回调,即OpenIMServer会在某一事件发生之前或者之后,向业务服务器发送请求,如发送消息之前或之后的回调。
|
||||
|
||||
👉 **[了解更多](https://doc.rentsoft.cn/guides/introduction/product)**
|
||||
👉 **[了解更多](https://docs.openim.io/guides/introduction/product)**
|
||||
|
||||
## :rocket: 快速开始
|
||||
|
||||
你只需要一个简单的命令,就可以快速学习 OpenIM 的工程解决方案:
|
||||
在线体验iOS/Android/H5/PC/Web:
|
||||
|
||||
```
|
||||
bashCopy code
|
||||
$ make demo
|
||||
```
|
||||
👉 **[OpenIM online demo](https://www.openim.io/zh/commercial)**
|
||||
|
||||
🤲 为了方便用户体验,我们提供了多种部署解决方案,您可以根据下面的列表选择自己的部署方法:
|
||||
|
||||
+ **[源代码部署指南](https://doc.rentsoft.cn/guides/gettingStarted/imSourceCodeDeployment)**
|
||||
+ **[Docker 部署指南](https://doc.rentsoft.cn/guides/gettingStarted/dockerCompose)**
|
||||
+ **[Kubernetes 部署指南](https://github.com/openimsdk/open-im-server/tree/main/deployments)**
|
||||
+ **[源代码部署指南](https://docs.openim.io/guides/gettingStarted/imSourceCodeDeployment)**
|
||||
+ **[Docker 部署指南](https://docs.openim.io/guides/gettingStarted/dockerCompose)**
|
||||
+ **[Kubernetes 部署指南](https://docs.openim.io/guides/gettingStarted/k8s-deployment)**
|
||||
|
||||
## :hammer_and_wrench: 开始开发 OpenIM
|
||||
|
||||
|
|
176
README.md
176
README.md
|
@ -25,178 +25,56 @@
|
|||
|
||||
</p>
|
||||
|
||||
|
||||
## Ⓜ️ 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.
|
||||
|
||||
![App-OpenIM Relationship](./docs/images/oepnim-design.png)
|
||||
|
||||
## 🚀 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.
|
||||
+ **Listener Callbacks**: Ensuring real-time message interactivity.
|
||||
+ **API Encapsulation**: Streamlining development processes.
|
||||
+ **Connection Management**: Guaranteeing reliable message delivery.
|
||||
+ 🌟 Main Features:
|
||||
|
||||
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)**
|
||||
|
||||
## 🌐 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.
|
||||
+ **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 Functionality:
|
||||
|
||||
### Enhanced Business Functionalities:
|
||||
|
||||
+ **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 🚀💼 |
|
||||
| :----------------------------------------------------------: | :---------------------------------------------------------: |
|
||||
| ![multiple-message](./assets/demo/multi-terminal-synchronization.png) | ![efficient-meetings](./assets/demo/efficient-meetings.png) |
|
||||
| 📲🔄 **One-to-one and Group Chats** 👥🗣️ | 🎁💻 **Special Features - Custom Messages** ✉️🎨|
|
||||
| ![group-chat](./assets/demo/group-chat.png) | ![special-function](./assets/demo/special-function.png) |
|
||||
|
||||
</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.
|
||||
|
||||
-->
|
||||
+ **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.
|
||||
|
||||
👉 **[Learn more](https://docs.openim.io/guides/introduction/product)**
|
||||
|
||||
## :rocket: Quick Start
|
||||
|
||||
We support many platforms. Here are the addresses for quick experience on the web side:
|
||||
|
||||
👉 **[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>
|
||||
-->
|
||||
🤲 To facilitate user experience, we offer various deployment solutions. You can choose your deployment method from the list below:
|
||||
|
||||
+ **[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)**
|
||||
+ **[Kubernetes Deployment Guide](https://github.com/openimsdk/open-im-server/tree/main/deployments)**
|
||||
|
||||
<!--
|
||||
## :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.
|
||||
|
||||
![App-OpenIM Relationship](./docs/images/oepnim-design.png)
|
||||
|
||||
## :building_construction: Overall Architecture
|
||||
|
||||
Delve into the heart of Open-IM-Server's functionality with our architecture diagram.
|
||||
|
||||
![Overall Architecture](./docs/images/Architecture.jpg) -->
|
||||
+ **[Kubernetes Deployment Guide](https://docs.openim.io/guides/gettingStarted/k8s-deployment)**
|
||||
|
||||
## :hammer_and_wrench: To start developing OpenIM
|
||||
|
||||
|
|
|
@ -320,6 +320,14 @@ callback:
|
|||
enable: ${CALLBACK_ENABLE}
|
||||
timeout: ${CALLBACK_TIMEOUT}
|
||||
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:
|
||||
enable: ${CALLBACK_ENABLE}
|
||||
timeout: ${CALLBACK_TIMEOUT}
|
||||
|
|
4
go.mod
4
go.mod
|
@ -4,8 +4,8 @@ go 1.19
|
|||
|
||||
require (
|
||||
firebase.google.com/go v3.13.0+incompatible
|
||||
github.com/OpenIMSDK/protocol v0.0.44
|
||||
github.com/OpenIMSDK/tools v0.0.21
|
||||
github.com/OpenIMSDK/protocol v0.0.47
|
||||
github.com/OpenIMSDK/tools v0.0.23
|
||||
github.com/bwmarrin/snowflake v0.3.0 // indirect
|
||||
github.com/dtm-labs/rockscache v0.1.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/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/OpenIMSDK/protocol v0.0.44 h1:P+9gJ9EW3y+VmzrjPludzn/5r1fjubaC19mKYJ7Oiew=
|
||||
github.com/OpenIMSDK/protocol v0.0.44/go.mod h1:F25dFrwrIx3lkNoiuf6FkCfxuwf8L4Z8UIsdTHP/r0Y=
|
||||
github.com/OpenIMSDK/tools v0.0.21 h1:iTapc2mIEVH/xl5Nd6jfwPub11Pgp44tVcE1rjB3a48=
|
||||
github.com/OpenIMSDK/tools v0.0.21/go.mod h1:eg+q4A34Qmu73xkY0mt37FHGMCMfC6CtmOnm0kFEGFI=
|
||||
github.com/OpenIMSDK/protocol v0.0.47 h1:DTJMFSONzqT0i/wa4Q1CtDT/jVATVudIRHcpY1zSWYE=
|
||||
github.com/OpenIMSDK/protocol v0.0.47/go.mod h1:F25dFrwrIx3lkNoiuf6FkCfxuwf8L4Z8UIsdTHP/r0Y=
|
||||
github.com/OpenIMSDK/tools v0.0.23 h1:xozfrGzhbpNPlDTap5DLVPk+JfgZ/ZyIj4Cuu3/bm9w=
|
||||
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/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=
|
||||
|
|
|
@ -33,8 +33,8 @@ func (o *ConversationApi) GetAllConversations(c *gin.Context) {
|
|||
a2r.Call(conversation.ConversationClient.GetAllConversations, o.Client, c)
|
||||
}
|
||||
|
||||
func (o *ConversationApi) GetConversationsList(c *gin.Context) {
|
||||
a2r.Call(conversation.ConversationClient.GetConversationList, o.Client, c)
|
||||
func (o *ConversationApi) GetSortedConversationList(c *gin.Context) {
|
||||
a2r.Call(conversation.ConversationClient.GetSortedConversationList, o.Client, c)
|
||||
}
|
||||
|
||||
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{}
|
||||
case constant.File:
|
||||
data = apistruct.FileElem{}
|
||||
case constant.AtText:
|
||||
data = apistruct.AtElem{}
|
||||
case constant.Custom:
|
||||
data = apistruct.CustomElem{}
|
||||
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 {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
default:
|
||||
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_update", ParseToken, u.ProcessUserCommandUpdate)
|
||||
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("/update_notification_account", ParseToken, u.UpdateNotificationAccountInfo)
|
||||
|
@ -204,7 +205,7 @@ func NewGinRouter(discov discoveryregistry.SvcDiscoveryRegistry, rdb redis.Unive
|
|||
conversationGroup := r.Group("/conversation", ParseToken)
|
||||
{
|
||||
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_conversation", c.GetConversation)
|
||||
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)
|
||||
}
|
||||
|
||||
// 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) {
|
||||
a2r.Call(user.UserClient.AddNotificationAccount, u.Client, c)
|
||||
}
|
||||
|
|
|
@ -37,7 +37,7 @@ func callbackOfflinePush(
|
|||
msg *sdkws.MsgData,
|
||||
offlinePushUserIDs *[]string,
|
||||
) error {
|
||||
if !config.Config.Callback.CallbackOfflinePush.Enable {
|
||||
if !config.Config.Callback.CallbackOfflinePush.Enable || msg.ContentType == constant.Typing {
|
||||
return nil
|
||||
}
|
||||
req := &callbackstruct.CallbackBeforePushReq{
|
||||
|
@ -73,7 +73,7 @@ func callbackOfflinePush(
|
|||
}
|
||||
|
||||
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
|
||||
}
|
||||
req := callbackstruct.CallbackBeforePushReq{
|
||||
|
@ -107,7 +107,7 @@ func callbackBeforeSuperGroupOnlinePush(
|
|||
msg *sdkws.MsgData,
|
||||
pushToUserIDs *[]string,
|
||||
) error {
|
||||
if !config.Config.Callback.CallbackBeforeSuperGroupOnlinePush.Enable {
|
||||
if !config.Config.Callback.CallbackBeforeSuperGroupOnlinePush.Enable || msg.ContentType == constant.Typing {
|
||||
return nil
|
||||
}
|
||||
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 {
|
||||
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 {
|
||||
return err
|
||||
}
|
||||
|
||||
// push
|
||||
wsResults, err := p.GetConnsAndOnlinePush(ctx, msg, userIDs)
|
||||
if err != nil {
|
||||
|
@ -120,7 +118,7 @@ func (p *Pusher) Push2User(ctx context.Context, userIDs []string, msg *sdkws.Msg
|
|||
}
|
||||
|
||||
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 {
|
||||
return err
|
||||
}
|
||||
|
@ -130,6 +128,7 @@ func (p *Pusher) Push2User(ctx context.Context, userIDs []string, msg *sdkws.Msg
|
|||
return err
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -89,8 +89,8 @@ func (c *conversationServer) GetConversation(ctx context.Context, req *pbconvers
|
|||
return resp, nil
|
||||
}
|
||||
|
||||
func (m *conversationServer) GetConversationList(ctx context.Context, req *pbconversation.GetConversationListReq) (resp *pbconversation.GetConversationListResp, err error) {
|
||||
log.ZDebug(ctx, "GetConversationList", "seqs", req, "userID", req.UserID)
|
||||
func (m *conversationServer) GetSortedConversationList(ctx context.Context, req *pbconversation.GetSortedConversationListReq) (resp *pbconversation.GetSortedConversationListResp, err error) {
|
||||
log.ZDebug(ctx, "GetSortedConversationList", "seqs", req, "userID", req.UserID)
|
||||
var conversationIDs []string
|
||||
if len(req.ConversationIDs) == 0 {
|
||||
conversationIDs, err = m.conversationDatabase.GetConversationIDs(ctx, req.UserID)
|
||||
|
@ -129,30 +129,37 @@ func (m *conversationServer) GetConversationList(ctx context.Context, req *pbcon
|
|||
return nil, err
|
||||
}
|
||||
|
||||
var unreadTotal int64
|
||||
conversation_unreadCount := make(map[string]int64)
|
||||
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_notPinkTime := make(map[int64]string)
|
||||
conversation_isPinTime := make(map[int64]string)
|
||||
conversation_notPinTime := make(map[int64]string)
|
||||
for _, v := range conversations {
|
||||
conversationID := v.ConversationID
|
||||
time := conversationMsg[conversationID].MsgInfo.LatestMsgRecvTime
|
||||
conversationMsg[conversationID].RecvMsgOpt = v.RecvMsgOpt
|
||||
if v.IsPinned {
|
||||
conversationMsg[conversationID].IsPinned = v.IsPinned
|
||||
conversation_isPinkTime[time] = conversationID
|
||||
conversation_isPinTime[time] = conversationID
|
||||
continue
|
||||
}
|
||||
conversation_notPinkTime[time] = conversationID
|
||||
conversation_notPinTime[time] = conversationID
|
||||
}
|
||||
resp = &pbconversation.GetConversationListResp{
|
||||
resp = &pbconversation.GetSortedConversationListResp{
|
||||
ConversationTotal: int64(len(chatLogs)),
|
||||
ConversationElems: []*pbconversation.ConversationElem{},
|
||||
UnreadTotal: unreadTotal,
|
||||
}
|
||||
|
||||
m.conversationSort(conversation_isPinkTime, resp, conversation_unreadCount, conversationMsg)
|
||||
m.conversationSort(conversation_notPinkTime, resp, conversation_unreadCount, conversationMsg)
|
||||
m.conversationSort(conversation_isPinTime, 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
|
||||
}
|
||||
|
||||
|
@ -425,7 +432,7 @@ func (c *conversationServer) GetConversationOfflinePushUserIDs(
|
|||
|
||||
func (c *conversationServer) conversationSort(
|
||||
conversations map[int64]string,
|
||||
resp *pbconversation.GetConversationListResp,
|
||||
resp *pbconversation.GetSortedConversationListResp,
|
||||
conversation_unreadCount map[string]int64,
|
||||
conversationMsg map[string]*pbconversation.ConversationElem,
|
||||
) {
|
||||
|
|
|
@ -452,22 +452,19 @@ func (s *friendServer) UpdateFriends(
|
|||
return nil, err
|
||||
}
|
||||
|
||||
for _, friendID := range req.FriendUserIDs {
|
||||
if req.IsPinned != nil {
|
||||
if err = s.friendDatabase.UpdateFriendPinStatus(ctx, req.OwnerUserID, friendID, req.IsPinned.Value); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
if req.Remark != nil {
|
||||
if err = s.friendDatabase.UpdateFriendRemark(ctx, req.OwnerUserID, friendID, req.Remark.Value); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
if req.Ex != nil {
|
||||
if err = s.friendDatabase.UpdateFriendEx(ctx, req.OwnerUserID, friendID, req.Ex.Value); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
val := make(map[string]any)
|
||||
|
||||
if req.IsPinned != nil {
|
||||
val["is_pinned"] = req.IsPinned.Value
|
||||
}
|
||||
if req.Remark != nil {
|
||||
val["remark"] = req.Remark.Value
|
||||
}
|
||||
if req.Ex != nil {
|
||||
val["ex"] = req.Ex.Value
|
||||
}
|
||||
if err = s.friendDatabase.UpdateFriends(ctx, req.OwnerUserID, req.FriendUserIDs, val); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
resp := &pbfriend.UpdateFriendsResp{}
|
||||
|
|
|
@ -279,20 +279,20 @@ func CallbackApplyJoinGroupBefore(ctx context.Context, req *callbackstruct.Callb
|
|||
return nil
|
||||
}
|
||||
|
||||
func CallbackTransferGroupOwnerAfter(ctx context.Context, req *pbgroup.TransferGroupOwnerReq) (err error) {
|
||||
if !config.Config.Callback.CallbackTransferGroupOwnerAfter.Enable {
|
||||
func CallbackAfterTransferGroupOwner(ctx context.Context, req *pbgroup.TransferGroupOwnerReq) (err error) {
|
||||
if !config.Config.Callback.CallbackAfterTransferGroupOwner.Enable {
|
||||
return nil
|
||||
}
|
||||
|
||||
cbReq := &callbackstruct.CallbackTransferGroupOwnerReq{
|
||||
CallbackCommand: callbackstruct.CallbackTransferGroupOwnerAfter,
|
||||
CallbackCommand: callbackstruct.CallbackAfterTransferGroupOwner,
|
||||
GroupID: req.GroupID,
|
||||
OldOwnerUserID: req.OldOwnerUserID,
|
||||
NewOwnerUserID: req.NewOwnerUserID,
|
||||
}
|
||||
|
||||
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 nil
|
||||
|
|
|
@ -1061,7 +1061,7 @@ func (s *groupServer) TransferGroupOwner(ctx context.Context, req *pbgroup.Trans
|
|||
return nil, err
|
||||
}
|
||||
|
||||
if err := CallbackTransferGroupOwnerAfter(ctx, req); err != nil {
|
||||
if err := CallbackAfterTransferGroupOwner(ctx, req); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
s.Notification.GroupOwnerTransferredNotification(ctx, req)
|
||||
|
|
|
@ -70,7 +70,7 @@ func GetContent(msg *sdkws.MsgData) string {
|
|||
}
|
||||
|
||||
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
|
||||
}
|
||||
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 {
|
||||
if !config.Config.Callback.CallbackAfterSendSingleMsg.Enable {
|
||||
if !config.Config.Callback.CallbackAfterSendSingleMsg.Enable || msg.MsgData.ContentType == constant.Typing {
|
||||
return nil
|
||||
}
|
||||
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 {
|
||||
if !config.Config.Callback.CallbackBeforeSendGroupMsg.Enable {
|
||||
if !config.Config.Callback.CallbackBeforeSendGroupMsg.Enable || msg.MsgData.ContentType == constant.Typing {
|
||||
return nil
|
||||
}
|
||||
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 {
|
||||
if !config.Config.Callback.CallbackAfterSendGroupMsg.Enable {
|
||||
if !config.Config.Callback.CallbackAfterSendGroupMsg.Enable || msg.MsgData.ContentType == constant.Typing {
|
||||
return nil
|
||||
}
|
||||
req := &cbapi.CallbackAfterSendGroupMsgReq{
|
||||
|
|
|
@ -65,6 +65,7 @@ func (m *msgServer) sendMsgSuperGroupChat(
|
|||
if err = callbackBeforeSendGroupMsg(ctx, req); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err := callbackMsgModify(ctx, req); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -167,6 +168,7 @@ func (m *msgServer) sendMsgSingleChat(ctx context.Context, req *pbmsg.SendMsgReq
|
|||
if err = callbackBeforeSendSingleMsg(ctx, req); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err := callbackMsgModify(ctx, req); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
|
@ -17,6 +17,7 @@ package user
|
|||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"github.com/OpenIMSDK/tools/pagination"
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation"
|
||||
"math/rand"
|
||||
"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) {
|
||||
total, users, err := s.Page(ctx, req.Pagination)
|
||||
total, users, err := s.PageFindUser(ctx, constant.IMOrdinaryUser, req.Pagination)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -379,38 +380,94 @@ func (s *userServer) GetSubscribeUsersStatus(ctx context.Context,
|
|||
|
||||
// ProcessUserCommandAdd user general function add
|
||||
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 := s.UserDatabase.AddUserCommand(ctx, req.UserID, req.Type, req.Uuid, req.Value)
|
||||
err := authverify.CheckAccessV3(ctx, req.UserID)
|
||||
if err != nil {
|
||||
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
|
||||
}
|
||||
|
||||
// ProcessUserCommandDelete user general function delete
|
||||
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 := s.UserDatabase.DeleteUserCommand(ctx, req.UserID, req.Type, req.Uuid)
|
||||
err := authverify.CheckAccessV3(ctx, req.UserID)
|
||||
if err != nil {
|
||||
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
|
||||
}
|
||||
|
||||
// ProcessUserCommandUpdate user general function update
|
||||
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 := s.UserDatabase.UpdateUserCommand(ctx, req.UserID, req.Type, req.Uuid, req.Value)
|
||||
err := authverify.CheckAccessV3(ctx, req.UserID)
|
||||
if err != nil {
|
||||
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
|
||||
}
|
||||
|
||||
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
|
||||
commands, err := s.UserDatabase.GetUserCommands(ctx, req.UserID, req.Type)
|
||||
if err != nil {
|
||||
|
@ -423,14 +480,45 @@ func (s *userServer) ProcessUserCommandGet(ctx context.Context, req *pbuser.Proc
|
|||
for _, command := range commands {
|
||||
// No need to use index since command is already a pointer
|
||||
commandInfoSlice = append(commandInfoSlice, &pbuser.CommandInfoResp{
|
||||
Type: command.Type,
|
||||
Uuid: command.Uuid,
|
||||
Value: command.Value,
|
||||
CreateTime: command.CreateTime,
|
||||
Ex: command.Ex,
|
||||
})
|
||||
}
|
||||
|
||||
// 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) {
|
||||
|
@ -438,22 +526,28 @@ func (s *userServer) AddNotificationAccount(ctx context.Context, req *pbuser.Add
|
|||
return nil, err
|
||||
}
|
||||
|
||||
var userID string
|
||||
for i := 0; i < 20; i++ {
|
||||
userId := s.genUserID()
|
||||
_, err := s.UserDatabase.FindWithError(ctx, []string{userId})
|
||||
if err == nil {
|
||||
continue
|
||||
if req.UserID == "" {
|
||||
for i := 0; i < 20; i++ {
|
||||
userId := s.genUserID()
|
||||
_, err := s.UserDatabase.FindWithError(ctx, []string{userId})
|
||||
if err == nil {
|
||||
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{
|
||||
UserID: userID,
|
||||
UserID: req.UserID,
|
||||
Nickname: req.NickName,
|
||||
FaceURL: req.FaceURL,
|
||||
CreateTime: time.Now(),
|
||||
|
@ -463,7 +557,11 @@ func (s *userServer) AddNotificationAccount(ctx context.Context, req *pbuser.Add
|
|||
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) {
|
||||
|
@ -497,30 +595,33 @@ func (s *userServer) SearchNotificationAccount(ctx context.Context, req *pbuser.
|
|||
return nil, err
|
||||
}
|
||||
|
||||
if req.NickName != "" {
|
||||
users, err := s.UserDatabase.FindByNickname(ctx, req.NickName)
|
||||
var users []*relation.UserModel
|
||||
var err error
|
||||
if req.Keyword != "" {
|
||||
users, err = s.UserDatabase.Find(ctx, []string{req.Keyword})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
resp := s.userModelToResp(users)
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
if req.UserID != "" {
|
||||
users, err := s.UserDatabase.Find(ctx, []string{req.UserID})
|
||||
resp := s.userModelToResp(users, req.Pagination)
|
||||
if resp.Total != 0 {
|
||||
return resp, nil
|
||||
}
|
||||
users, err = s.UserDatabase.FindByNickname(ctx, req.Keyword)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
resp := s.userModelToResp(users)
|
||||
resp = s.userModelToResp(users, req.Pagination)
|
||||
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 {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
resp := s.userModelToResp(users)
|
||||
resp := s.userModelToResp(users, req.Pagination)
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
|
@ -554,7 +655,7 @@ func (s *userServer) genUserID() string {
|
|||
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)
|
||||
var total int64
|
||||
for _, v := range users {
|
||||
|
@ -568,5 +669,8 @@ func (s *userServer) userModelToResp(users []*relation.UserModel) *pbuser.Search
|
|||
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"
|
||||
CallbackBeforeUserRegisterCommand = "callbackBeforeUserRegisterCommand"
|
||||
CallbackAfterUserRegisterCommand = "callbackAfterUserRegisterCommand"
|
||||
CallbackTransferGroupOwnerAfter = "callbackTransferGroupOwnerAfter"
|
||||
CallbackAfterTransferGroupOwner = "callbackAfterTransferGroupOwner"
|
||||
CallbackBeforeSetFriendRemark = "callbackBeforeSetFriendRemark"
|
||||
CallbackAfterSetFriendRemark = "callbackAfterSetFriendRemark"
|
||||
CallbackSingleMsgRead = "callbackSingleMsgRead"
|
||||
|
|
|
@ -298,7 +298,7 @@ type configStruct struct {
|
|||
CallbackKillGroupMember CallBackConfig `yaml:"killGroupMember"`
|
||||
CallbackDismissGroup CallBackConfig `yaml:"dismissGroup"`
|
||||
CallbackBeforeJoinGroup CallBackConfig `yaml:"joinGroup"`
|
||||
CallbackTransferGroupOwnerAfter CallBackConfig `yaml:"transferGroupOwner"`
|
||||
CallbackAfterTransferGroupOwner CallBackConfig `yaml:"transferGroupOwner"`
|
||||
CallbackBeforeInviteUserToGroup CallBackConfig `yaml:"beforeInviteUserToGroup"`
|
||||
CallbackAfterJoinGroup CallBackConfig `yaml:"joinGroupAfter"`
|
||||
CallbackAfterSetGroupInfo CallBackConfig `yaml:"setGroupInfoAfter"`
|
||||
|
|
|
@ -46,6 +46,8 @@ type FriendCache interface {
|
|||
GetFriend(ctx context.Context, ownerUserID, friendUserID string) (friend *relationtb.FriendModel, err error)
|
||||
// Delete friend when friend info changed
|
||||
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.
|
||||
|
@ -157,3 +159,15 @@ func (f *FriendCacheRedis) DelFriend(ownerUserID, friendUserID string) FriendCac
|
|||
|
||||
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 {
|
||||
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(ctx context.Context, fromUserID, toUserID string) (friends []*relation.FriendRequestModel, err error)
|
||||
|
||||
// UpdateFriendPinStatus updates the pinned status of a friend
|
||||
UpdateFriendPinStatus(ctx context.Context, ownerUserID string, friendUserID string, isPinned bool) (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)
|
||||
|
||||
// UpdateFriends updates fields for friends
|
||||
UpdateFriends(ctx context.Context, ownerUserID string, friendUserIDs []string, val map[string]any) (err error)
|
||||
}
|
||||
|
||||
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) {
|
||||
return f.friendRequest.FindBothFriendRequests(ctx, fromUserID, toUserID)
|
||||
}
|
||||
func (f *friendDatabase) UpdateFriendPinStatus(ctx context.Context, ownerUserID string, friendUserID string, isPinned bool) (err error) {
|
||||
if err := f.friend.UpdatePinStatus(ctx, ownerUserID, friendUserID, isPinned); err != nil {
|
||||
func (f *friendDatabase) UpdateFriends(ctx context.Context, ownerUserID string, friendUserIDs []string, val map[string]any) (err error) {
|
||||
if len(val) == 0 {
|
||||
return nil
|
||||
}
|
||||
if err := f.friend.UpdateFriends(ctx, ownerUserID, friendUserIDs, val); err != nil {
|
||||
return err
|
||||
}
|
||||
return f.cache.DelFriend(ownerUserID, friendUserID).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)
|
||||
return f.cache.DelFriends(ownerUserID, friendUserIDs).ExecDel(ctx)
|
||||
}
|
||||
|
|
|
@ -50,6 +50,8 @@ type UserDatabase interface {
|
|||
UpdateByMap(ctx context.Context, userID string, args map[string]any) (err error)
|
||||
// Page If not found, no error is returned
|
||||
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(ctx context.Context, userIDs []string) (exist bool, err error)
|
||||
// GetAllUserID Get all user IDs
|
||||
|
@ -76,10 +78,11 @@ type UserDatabase interface {
|
|||
SetUserStatus(ctx context.Context, userID string, status, platformID int32) error
|
||||
|
||||
//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
|
||||
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)
|
||||
GetAllUserCommands(ctx context.Context, userID string) ([]*user.AllCommandInfoResp, error)
|
||||
}
|
||||
|
||||
type userDatabase struct {
|
||||
|
@ -182,6 +185,10 @@ func (u *userDatabase) Page(ctx context.Context, pagination pagination.Paginatio
|
|||
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.
|
||||
func (u *userDatabase) IsExist(ctx context.Context, userIDs []string) (exist bool, err error) {
|
||||
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 {
|
||||
return u.cache.SetUserStatus(ctx, userID, status, platformID)
|
||||
}
|
||||
func (u *userDatabase) AddUserCommand(ctx context.Context, userID string, Type int32, UUID string, value string) error {
|
||||
return u.userDB.AddUserCommand(ctx, userID, Type, UUID, value)
|
||||
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, ex)
|
||||
}
|
||||
func (u *userDatabase) DeleteUserCommand(ctx context.Context, userID string, Type int32, UUID string) error {
|
||||
return u.userDB.DeleteUserCommand(ctx, userID, Type, UUID)
|
||||
}
|
||||
func (u *userDatabase) UpdateUserCommand(ctx context.Context, userID string, Type int32, UUID string, value string) error {
|
||||
return u.userDB.UpdateUserCommand(ctx, userID, Type, UUID, value)
|
||||
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, val)
|
||||
}
|
||||
func (u *userDatabase) GetUserCommands(ctx context.Context, userID string, Type int32) ([]*user.CommandInfoResp, error) {
|
||||
commands, err := u.userDB.GetUserCommand(ctx, userID, Type)
|
||||
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 (
|
||||
"context"
|
||||
"github.com/OpenIMSDK/tools/errs"
|
||||
"github.com/OpenIMSDK/tools/mgoutil"
|
||||
"github.com/OpenIMSDK/tools/pagination"
|
||||
"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}))
|
||||
}
|
||||
|
||||
// UpdatePinStatus update friend's pin status
|
||||
func (f *FriendMgo) UpdatePinStatus(ctx context.Context, ownerUserID string, friendUserID string, isPinned bool) (err error) {
|
||||
|
||||
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{"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")
|
||||
func (f *FriendMgo) UpdateFriends(ctx context.Context, ownerUserID string, friendUserIDs []string, val map[string]any) error {
|
||||
// Ensure there are IDs to update
|
||||
if len(friendUserIDs) == 0 {
|
||||
return nil // Or return an error if you expect there to always be IDs
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
func (f *FriendMgo) UpdateFriendRemark(ctx context.Context, ownerUserID string, friendUserID string, remark string) (err error) {
|
||||
|
||||
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")
|
||||
// Create a filter to match documents with the specified ownerUserID and any of the friendUserIDs
|
||||
filter := bson.M{
|
||||
"owner_user_id": ownerUserID,
|
||||
"friend_user_id": bson.M{"$in": friendUserIDs},
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
func (f *FriendMgo) UpdateFriendEx(ctx context.Context, ownerUserID string, friendUserID string, ex string) (err error) {
|
||||
|
||||
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{"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
|
||||
// Create an update document
|
||||
update := bson.M{"$set": val}
|
||||
|
||||
// Perform the update operation for all matching documents
|
||||
_, err := mgoutil.UpdateMany(ctx, f.coll, filter, update)
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -17,6 +17,7 @@ package mgo
|
|||
import (
|
||||
"context"
|
||||
"github.com/OpenIMSDK/protocol/user"
|
||||
"github.com/OpenIMSDK/tools/errs"
|
||||
"time"
|
||||
|
||||
"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)
|
||||
}
|
||||
|
||||
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) {
|
||||
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}})
|
||||
}
|
||||
|
||||
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")
|
||||
|
||||
// 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,
|
||||
"createTime": time.Now().Unix(), // assuming you want the creation time in Unix timestamp
|
||||
"value": value,
|
||||
"ex": ex,
|
||||
}
|
||||
|
||||
_, err := collection.InsertOne(ctx, doc)
|
||||
return err
|
||||
}
|
||||
|
||||
func (u *UserMgo) DeleteUserCommand(ctx context.Context, userID string, Type int32, UUID string) error {
|
||||
collection := u.coll.Database().Collection("userCommands")
|
||||
|
||||
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
|
||||
}
|
||||
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")
|
||||
|
||||
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)
|
||||
return err
|
||||
result, err := collection.UpdateOne(ctx, filter, update)
|
||||
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) {
|
||||
collection := u.coll.Database().Collection("userCommands")
|
||||
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) {
|
||||
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.CommandInfoResp{ // Change here: use a pointer to the struct
|
||||
commandInfo := &user.CommandInfoResp{
|
||||
Type: document.Type,
|
||||
Uuid: document.UUID,
|
||||
Value: document.Value,
|
||||
CreateTime: document.CreateTime,
|
||||
Ex: document.Ex,
|
||||
}
|
||||
|
||||
commands = append(commands, commandInfo)
|
||||
|
@ -167,7 +196,48 @@ func (u *UserMgo) GetUserCommand(ctx context.Context, userID string, Type int32)
|
|||
|
||||
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) {
|
||||
pipeline := bson.A{
|
||||
bson.M{
|
||||
|
|
|
@ -57,10 +57,6 @@ type FriendModelInterface interface {
|
|||
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(ctx context.Context, ownerUserID string) (friendUserIDs []string, err error)
|
||||
// UpdatePinStatus update friend's pin status
|
||||
UpdatePinStatus(ctx context.Context, ownerUserID string, friendUserID string, isPinned bool) (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)
|
||||
// UpdateFriends update friends' fields
|
||||
UpdateFriends(ctx context.Context, ownerUserID string, friendUserIDs []string, val map[string]any) (err error)
|
||||
}
|
||||
|
|
|
@ -56,6 +56,7 @@ type UserModelInterface interface {
|
|||
TakeNotification(ctx context.Context, level int64) (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)
|
||||
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)
|
||||
GetAllUserID(ctx context.Context, pagination pagination.Pagination) (count int64, userIDs []string, 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)
|
||||
//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
|
||||
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)
|
||||
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)
|
||||
}
|
||||
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.FriendIDs = friendIDs
|
||||
return f.Notification(ctx, toUserID, toUserID, constant.FriendsInfoUpdateNotification, &tips)
|
||||
|
|
|
@ -103,3 +103,21 @@ func (u *UserNotificationSender) UserStatusChangeNotification(
|
|||
) error {
|
||||
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…
Reference in New Issue