mirror of
https://github.com/openimsdk/open-im-server.git
synced 2026-04-28 22:39:18 +08:00
Compare commits
16 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 856b54e371 | |||
| d61495b047 | |||
| 6271a61c36 | |||
| f875f99dd8 | |||
| af54170cf2 | |||
| bb4463349e | |||
| 6b55cfd0b8 | |||
| bb6462647a | |||
| 60f4f67fb7 | |||
| 4cd2713fd6 | |||
| 119e8dbb2f | |||
| c0194f6ef4 | |||
| 1c1322e3d2 | |||
| 4b192027aa | |||
| be5a3e5a3f | |||
| 5b697d5e95 |
@@ -20,7 +20,6 @@ CHANGELOG/
|
||||
|
||||
# Ignore deployment-related files
|
||||
docker-compose.yaml
|
||||
deployments/
|
||||
|
||||
# Ignore assets
|
||||
assets/
|
||||
|
||||
@@ -22,6 +22,9 @@ on:
|
||||
# run e2e test every 4 hours
|
||||
- cron: 0 */4 * * *
|
||||
|
||||
env:
|
||||
CALLBACK_ENABLE: true
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: Test
|
||||
@@ -70,9 +73,9 @@ jobs:
|
||||
|
||||
- name: Docker Operations
|
||||
run: |
|
||||
curl -o docker-compose.yml https://raw.githubusercontent.com/OpenIMSDK/openim-docker/main/example/basic-openim-server-dependency.yml
|
||||
sudo make init
|
||||
sudo docker compose up -d
|
||||
sudo sleep 60
|
||||
sudo sleep 20
|
||||
|
||||
- name: Module Operations
|
||||
run: |
|
||||
|
||||
@@ -51,4 +51,5 @@ jobs:
|
||||
OCO_EMOJI: false
|
||||
OCO_MODEL: gpt-3.5-turbo-16k
|
||||
OCO_LANGUAGE: en
|
||||
OCO_PROMPT_MODULE: conventional-commit
|
||||
OCO_PROMPT_MODULE: conventional-commit
|
||||
continue-on-error: true
|
||||
@@ -156,9 +156,9 @@ jobs:
|
||||
|
||||
- name: Docker Operations
|
||||
run: |
|
||||
curl -o docker-compose.yml https://raw.githubusercontent.com/OpenIMSDK/openim-docker/main/example/basic-openim-server-dependency.yml
|
||||
sudo make init
|
||||
sudo docker compose up -d
|
||||
sudo sleep 60
|
||||
sudo sleep 20
|
||||
|
||||
- name: Module Operations
|
||||
run: |
|
||||
@@ -195,4 +195,5 @@ jobs:
|
||||
|
||||
- name: Test Docker Build
|
||||
run: |
|
||||
sudo make init
|
||||
sudo make image
|
||||
@@ -391,3 +391,5 @@ Sessionx.vim
|
||||
dist/
|
||||
.env
|
||||
config/config.yaml
|
||||
config/alertmanager.yml
|
||||
config/prometheus.yml
|
||||
+3
-2
@@ -25,7 +25,8 @@ WORKDIR ${SERVER_WORKDIR}
|
||||
|
||||
# Copy scripts and binary files to the production image
|
||||
COPY --from=builder ${OPENIM_SERVER_BINDIR} /openim/openim-server/_output/bin
|
||||
# COPY --from=builder ${OPENIM_SERVER_CMDDIR} /openim/openim-server/scripts
|
||||
# COPY --from=builder ${SERVER_WORKDIR}/config /openim/openim-server/config
|
||||
COPY --from=builder ${OPENIM_SERVER_CMDDIR} /openim/openim-server/scripts
|
||||
COPY --from=builder ${SERVER_WORKDIR}/config /openim/openim-server/config
|
||||
COPY --from=builder ${SERVER_WORKDIR}/deployments /openim/openim-server/deployments
|
||||
|
||||
CMD ["/openim/openim-server/scripts/docker-start-all.sh"]
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
# Examples Directory
|
||||
|
||||
Welcome to the `examples` directory of our project! This directory contains a collection of example files that demonstrate various configurations and setups for our software. These examples are designed to provide you with templates that can be used as a starting point for your own configurations.
|
||||
|
||||
## Overview
|
||||
|
||||
In this directory, you'll find examples for a variety of use cases. Each file is a template with default values and configurations that illustrate best practices and typical scenarios. Whether you're just getting started or looking to implement a complex setup, these examples should help you get on the right track.
|
||||
|
||||
## Structure
|
||||
|
||||
Here's a quick overview of what you'll find in this directory:
|
||||
|
||||
+ `env-example.yaml`: Demonstrates how to set up environment variables.
|
||||
+ `openim-example.yaml`: A sample configuration file for the OpenIM application.
|
||||
+ `prometheus-example.yml`: An example Prometheus configuration for monitoring.
|
||||
+ `alertmanager-example.yml`: A template for setting up Alertmanager configurations.
|
||||
|
||||
## How to Use These Examples
|
||||
|
||||
To use these examples, simply copy the relevant file to your working directory and rename it as needed (e.g., removing the `-example` suffix). Then, modify the file according to your requirements.
|
||||
|
||||
### Tips for Using Example Files:
|
||||
|
||||
1. **Read the Comments**: Each file contains comments that explain various sections and settings. Make sure to read these comments for a better understanding of how to customize the file.
|
||||
2. **Check for Required Changes**: Some examples might require mandatory changes (like setting specific environment variables) before they can be used effectively.
|
||||
3. **Version Compatibility**: Ensure that the example files are compatible with the version of the software you are using.
|
||||
|
||||
## Contributing
|
||||
|
||||
If you have a configuration that you believe would be beneficial to others, please feel free to contribute by opening a pull request with your proposed changes. We appreciate contributions that expand our examples with new scenarios and use cases.
|
||||
|
||||
## Support
|
||||
|
||||
If you encounter any issues or have questions regarding the example files, please open an issue on our repository. Our community is here to help you navigate through any challenges you might face.
|
||||
|
||||
Thank you for exploring our examples, and we hope they will be helpful in setting up and configuring your environment!
|
||||
@@ -19,6 +19,7 @@ templates:
|
||||
- /etc/alertmanager/email.tmpl
|
||||
|
||||
route:
|
||||
group_by: ['alertname']
|
||||
group_wait: 5s
|
||||
group_interval: 5s
|
||||
repeat_interval: 5m
|
||||
@@ -26,7 +27,7 @@ route:
|
||||
receivers:
|
||||
- name: email
|
||||
email_configs:
|
||||
- to: '{EMAIL_TO:-'alert@example.com'}'
|
||||
- to: 'alert@example.com'
|
||||
html: '{{ template "email.to.html" . }}'
|
||||
headers: { Subject: "[OPENIM-SERVER]Alarm" }
|
||||
send_resolved: true
|
||||
@@ -35,26 +35,6 @@ zookeeper:
|
||||
username: ''
|
||||
password: ''
|
||||
|
||||
###################### Mysql ######################
|
||||
# MySQL configuration
|
||||
# Currently, only single machine setup is supported
|
||||
#
|
||||
# Maximum number of open connections
|
||||
# Maximum number of idle connections
|
||||
# Maximum lifetime in seconds a connection can be reused
|
||||
# Log level: 1=slient, 2=error, 3=warn, 4=info
|
||||
# Slow query threshold in milliseconds
|
||||
mysql:
|
||||
address: [ 172.28.0.1:13306 ]
|
||||
username: root
|
||||
password: openIM123
|
||||
database: openIM_v3
|
||||
maxOpenConn: 1000
|
||||
maxIdleConn: 100
|
||||
maxLifeTime: 60
|
||||
logLevel: 4
|
||||
slowThreshold: 500
|
||||
|
||||
###################### Mongo ######################
|
||||
# MongoDB configuration
|
||||
# If uri is not empty, it will be used directly
|
||||
@@ -135,14 +115,14 @@ api:
|
||||
# minio.signEndpoint is minio public network address
|
||||
object:
|
||||
enable: "minio"
|
||||
apiURL: "http://127.0.0.1:10002"
|
||||
apiURL: "http://172.28.0.1:10002"
|
||||
minio:
|
||||
bucket: "openim"
|
||||
endpoint: "http://172.28.0.1:10005"
|
||||
accessKeyID: "root"
|
||||
secretAccessKey: "openIM123"
|
||||
sessionToken: ''
|
||||
signEndpoint: "http://127.0.0.1:10005"
|
||||
signEndpoint: "http://172.28.0.1:10005"
|
||||
publicRead: false
|
||||
cos:
|
||||
bucketURL: https://temp-1252357374.cos.ap-chengdu.myqcloud.com
|
||||
@@ -166,12 +146,13 @@ object:
|
||||
accessKeySecret: ''
|
||||
sessionToken: ''
|
||||
publicRead: false
|
||||
|
||||
###################### RPC Port Configuration ######################
|
||||
# RPC service ports
|
||||
# These ports are passed into the program by the script and are not recommended to modify
|
||||
# For launching multiple programs, just fill in multiple ports separated by commas
|
||||
# For example, [10110, 10111]
|
||||
rpcPort:
|
||||
rpcPort:
|
||||
openImUserPort: [ 10110 ]
|
||||
openImFriendPort: [ 10120 ]
|
||||
openImMessagePort: [ 10130 ]
|
||||
@@ -319,7 +300,7 @@ iosPush:
|
||||
# Timeout in seconds
|
||||
# Whether to continue execution if callback fails
|
||||
callback:
|
||||
url:
|
||||
url: ""
|
||||
beforeSendSingleMsg:
|
||||
enable: false
|
||||
timeout: 5
|
||||
@@ -327,6 +308,7 @@ callback:
|
||||
afterSendSingleMsg:
|
||||
enable: false
|
||||
timeout: 5
|
||||
failedContinue: true
|
||||
beforeSendGroupMsg:
|
||||
enable: false
|
||||
timeout: 5
|
||||
@@ -334,6 +316,7 @@ callback:
|
||||
afterSendGroupMsg:
|
||||
enable: false
|
||||
timeout: 5
|
||||
failedContinue: true
|
||||
msgModify:
|
||||
enable: false
|
||||
timeout: 5
|
||||
@@ -341,12 +324,15 @@ callback:
|
||||
userOnline:
|
||||
enable: false
|
||||
timeout: 5
|
||||
failedContinue: true
|
||||
userOffline:
|
||||
enable: false
|
||||
timeout: 5
|
||||
failedContinue: true
|
||||
userKickOff:
|
||||
enable: false
|
||||
timeout: 5
|
||||
failedContinue: true
|
||||
offlinePush:
|
||||
enable: false
|
||||
timeout: 5
|
||||
@@ -371,15 +357,19 @@ callback:
|
||||
enable: false
|
||||
timeout: 5
|
||||
failedContinue: true
|
||||
afterCreateGroup:
|
||||
enable: false
|
||||
timeout: 5
|
||||
failedContinue: true
|
||||
beforeMemberJoinGroup:
|
||||
enable: false
|
||||
timeout: 5
|
||||
failedContinue: true
|
||||
beforeInviteUserToGroup:
|
||||
enable: true
|
||||
beforeSetGroupMemberInfo:
|
||||
enable: false
|
||||
timeout: 5
|
||||
failedContinue: true
|
||||
beforeSetGroupMemberInfo:
|
||||
afterSetGroupMemberInfo:
|
||||
enable: false
|
||||
timeout: 5
|
||||
failedContinue: true
|
||||
@@ -387,14 +377,121 @@ callback:
|
||||
enable: false
|
||||
timeout: 5
|
||||
failedContinue: true
|
||||
|
||||
quitGroup:
|
||||
enable: false
|
||||
timeout: 5
|
||||
failedContinue: true
|
||||
killGroupMember:
|
||||
enable: false
|
||||
timeout: 5
|
||||
failedContinue: true
|
||||
dismissGroup:
|
||||
enable: false
|
||||
timeout: 5
|
||||
failedContinue: true
|
||||
joinGroup:
|
||||
enable: false
|
||||
timeout: 5
|
||||
failedContinue: true
|
||||
groupMsgRead:
|
||||
enable: false
|
||||
timeout: 5
|
||||
failedContinue: true
|
||||
singleMsgRead:
|
||||
enable: false
|
||||
timeout: 5
|
||||
failedContinue: true
|
||||
updateUserInfo:
|
||||
enable: false
|
||||
timeout: 5
|
||||
failedContinue: true
|
||||
beforeUserRegister:
|
||||
enable: false
|
||||
timeout: 5
|
||||
failedContinue: true
|
||||
afterUserRegister:
|
||||
enable: false
|
||||
timeout: 5
|
||||
failedContinue: true
|
||||
transferGroupOwner:
|
||||
enable: false
|
||||
timeout: 5
|
||||
failedContinue: true
|
||||
beforeSetFriendRemark:
|
||||
enable: false
|
||||
timeout: 5
|
||||
failedContinue: true
|
||||
afterSetFriendRemark:
|
||||
enable: false
|
||||
timeout: 5
|
||||
failedContinue: true
|
||||
afterGroupMsgRead:
|
||||
enable: false
|
||||
timeout: 5
|
||||
failedContinue: true
|
||||
afterGroupMsgRevoke:
|
||||
enable: false
|
||||
timeout: 5
|
||||
failedContinue: true
|
||||
afterJoinGroup:
|
||||
enable: false
|
||||
timeout: 5
|
||||
failedContinue: true
|
||||
beforeInviteUserToGroup:
|
||||
enable: false
|
||||
timeout: 5
|
||||
failedContinue: true
|
||||
joinGroupAfter:
|
||||
enable: false
|
||||
timeout: 5
|
||||
failedContinue: true
|
||||
setGroupInfoAfter:
|
||||
enable: false
|
||||
timeout: 5
|
||||
failedContinue: true
|
||||
setGroupInfoBefore:
|
||||
enable: false
|
||||
timeout: 5
|
||||
failedContinue: true
|
||||
revokeMsgAfter:
|
||||
enable: false
|
||||
timeout: 5
|
||||
failedContinue: true
|
||||
addBlackBefore:
|
||||
enable: false
|
||||
timeout: 5
|
||||
failedContinue: true
|
||||
addFriendAfter:
|
||||
enable: false
|
||||
timeout: 5
|
||||
failedContinue: true
|
||||
addFriendAgreeBefore:
|
||||
enable: false
|
||||
timeout: 5
|
||||
failedContinue: true
|
||||
deleteFriendAfter:
|
||||
enable: false
|
||||
timeout: 5
|
||||
failedContinue: true
|
||||
importFriendsBefore:
|
||||
enable: false
|
||||
timeout: 5
|
||||
failedContinue: true
|
||||
importFriendsAfter:
|
||||
enable: false
|
||||
timeout: 5
|
||||
failedContinue: true
|
||||
removeBlackAfter:
|
||||
enable: false
|
||||
timeout: 5
|
||||
failedContinue: true
|
||||
###################### Prometheus ######################
|
||||
# Prometheus configuration for various services
|
||||
# The number of Prometheus ports per service needs to correspond to rpcPort
|
||||
# The number of ports needs to be consistent with msg_transfer_service_num in script/path_info.sh
|
||||
prometheus:
|
||||
enable: false
|
||||
prometheusUrl: "https://openim.prometheus"
|
||||
prometheusUrl: 172.28.0.1:13000
|
||||
apiPrometheusPort: [20100]
|
||||
userPrometheusPort: [ 20110 ]
|
||||
friendPrometheusPort: [ 20120 ]
|
||||
@@ -1,23 +1,9 @@
|
||||
# Copyright © 2023 OpenIM. All rights reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
# ======================================
|
||||
# ========= Basic Configuration ========
|
||||
# ======================================
|
||||
|
||||
# The user for authentication or system operations.
|
||||
# Default: USER=root
|
||||
# Default: OPENIM_USER=root
|
||||
USER=root
|
||||
|
||||
# Password associated with the specified user for authentication.
|
||||
@@ -55,61 +41,20 @@ DOCKER_BRIDGE_SUBNET=172.28.0.0/16
|
||||
# Default: DOCKER_BRIDGE_GATEWAY=172.28.0.1
|
||||
DOCKER_BRIDGE_GATEWAY=172.28.0.1
|
||||
|
||||
# Address or hostname for the MySQL network.
|
||||
# Default: MYSQL_NETWORK_ADDRESS=172.28.0.2
|
||||
MYSQL_NETWORK_ADDRESS=172.28.0.2
|
||||
|
||||
# Address or hostname for the MongoDB network.
|
||||
# Default: MONGO_NETWORK_ADDRESS=172.28.0.3
|
||||
MONGO_NETWORK_ADDRESS=172.28.0.3
|
||||
|
||||
# Address or hostname for the Redis network.
|
||||
# Default: REDIS_NETWORK_ADDRESS=172.28.0.4
|
||||
REDIS_NETWORK_ADDRESS=172.28.0.4
|
||||
|
||||
# Address or hostname for the Kafka network.
|
||||
# Default: KAFKA_NETWORK_ADDRESS=172.28.0.5
|
||||
KAFKA_NETWORK_ADDRESS=172.28.0.5
|
||||
|
||||
# Address or hostname for the ZooKeeper network.
|
||||
# Default: ZOOKEEPER_NETWORK_ADDRESS=172.28.0.6
|
||||
ZOOKEEPER_NETWORK_ADDRESS=172.28.0.6
|
||||
|
||||
# Address or hostname for the MinIO network.
|
||||
# Default: MINIO_NETWORK_ADDRESS=172.28.0.7
|
||||
MINIO_NETWORK_ADDRESS=172.28.0.7
|
||||
|
||||
# Address or hostname for the OpenIM web network.
|
||||
# Default: OPENIM_WEB_NETWORK_ADDRESS=172.28.0.8
|
||||
OPENIM_WEB_NETWORK_ADDRESS=172.28.0.8
|
||||
|
||||
# Address or hostname for the OpenIM server network.
|
||||
# Default: OPENIM_SERVER_NETWORK_ADDRESS=172.28.0.9
|
||||
OPENIM_SERVER_NETWORK_ADDRESS=172.28.0.9
|
||||
|
||||
# Address or hostname for the OpenIM chat network.
|
||||
# Default: OPENIM_CHAT_NETWORK_ADDRESS=172.28.0.10
|
||||
OPENIM_CHAT_NETWORK_ADDRESS=172.28.0.10
|
||||
|
||||
# Address or hostname for the Prometheus network.
|
||||
# Default: PROMETHEUS_NETWORK_ADDRESS=172.28.0.11
|
||||
PROMETHEUS_NETWORK_ADDRESS=172.28.0.11
|
||||
|
||||
# Address or hostname for the Grafana network.
|
||||
# Default: GRAFANA_NETWORK_ADDRESS=172.28.0.12
|
||||
GRAFANA_NETWORK_ADDRESS=172.28.0.12
|
||||
|
||||
# Address or hostname for the node_exporter network.
|
||||
# Default: NODE_EXPORTER_NETWORK_ADDRESS=172.28.0.13
|
||||
NODE_EXPORTER_NETWORK_ADDRESS=172.28.0.13
|
||||
|
||||
# Address or hostname for the OpenIM admin network.
|
||||
# Default: OPENIM_ADMIN_NETWORK_ADDRESS=172.28.0.14
|
||||
OPENIM_ADMIN_FRONT_NETWORK_ADDRESS=172.28.0.14
|
||||
|
||||
# Address or hostname for the alertmanager network.
|
||||
# Default: ALERT_MANAGER_NETWORK_ADDRESS=172.28.0.14
|
||||
MONGO_NETWORK_ADDRESS=172.28.0.2
|
||||
REDIS_NETWORK_ADDRESS=172.28.0.3
|
||||
KAFKA_NETWORK_ADDRESS=172.28.0.4
|
||||
ZOOKEEPER_NETWORK_ADDRESS=172.28.0.5
|
||||
MINIO_NETWORK_ADDRESS=172.28.0.6
|
||||
OPENIM_WEB_NETWORK_ADDRESS=172.28.0.7
|
||||
OPENIM_SERVER_NETWORK_ADDRESS=172.28.0.8
|
||||
OPENIM_CHAT_NETWORK_ADDRESS=172.28.0.9
|
||||
PROMETHEUS_NETWORK_ADDRESS=172.28.0.10
|
||||
GRAFANA_NETWORK_ADDRESS=172.28.0.11
|
||||
NODE_EXPORTER_NETWORK_ADDRESS=172.28.0.12
|
||||
OPENIM_ADMIN_FRONT_NETWORK_ADDRESS=172.28.0.13
|
||||
ALERT_MANAGER_NETWORK_ADDRESS=172.28.0.14
|
||||
|
||||
# ===============================================
|
||||
# = Component Extension Configuration =
|
||||
# ===============================================
|
||||
@@ -118,38 +63,24 @@ ALERT_MANAGER_NETWORK_ADDRESS=172.28.0.14
|
||||
# ----- ZooKeeper Configuration -----
|
||||
# Address or hostname for the ZooKeeper service.
|
||||
# Default: ZOOKEEPER_ADDRESS=172.28.0.1
|
||||
ZOOKEEPER_ADDRESS=172.28.0.6
|
||||
ZOOKEEPER_ADDRESS=172.28.0.5
|
||||
|
||||
# Port for ZooKeeper service.
|
||||
# Default: ZOOKEEPER_PORT=12181
|
||||
ZOOKEEPER_PORT=12181
|
||||
|
||||
# ----- MySQL Configuration -----
|
||||
|
||||
# Address or hostname for the MySQL service.
|
||||
# Default: MYSQL_ADDRESS=172.28.0.1
|
||||
MYSQL_ADDRESS=172.28.0.2
|
||||
|
||||
# Port on which MySQL database service is running.
|
||||
# Default: MYSQL_PORT=13306
|
||||
MYSQL_PORT=13306
|
||||
|
||||
# Password to authenticate with the MySQL database service.
|
||||
# Default: MYSQL_PASSWORD=openIM123
|
||||
MYSQL_PASSWORD=openIM123
|
||||
|
||||
# ----- MongoDB Configuration -----
|
||||
# Address or hostname for the MongoDB service.
|
||||
# Default: MONGO_ADDRESS=172.28.0.1
|
||||
MONGO_ADDRESS=172.28.0.3
|
||||
MONGO_ADDRESS=172.28.0.2
|
||||
|
||||
# Port on which MongoDB service is running.
|
||||
# Default: MONGO_PORT=37017
|
||||
MONGO_PORT=37017
|
||||
# MONGO_PORT=37017
|
||||
|
||||
# Username to authenticate with the MongoDB service.
|
||||
# Default: MONGO_USERNAME=root
|
||||
MONGO_USERNAME=root
|
||||
# MONGO_USERNAME=root
|
||||
|
||||
# Password to authenticate with the MongoDB service.
|
||||
# Default: MONGO_PASSWORD=openIM123
|
||||
@@ -162,7 +93,7 @@ MONGO_DATABASE=openIM_v3
|
||||
# ----- Redis Configuration -----
|
||||
# Address or hostname for the Redis service.
|
||||
# Default: REDIS_ADDRESS=172.28.0.1
|
||||
REDIS_ADDRESS=172.28.0.4
|
||||
REDIS_ADDRESS=172.28.0.3
|
||||
|
||||
# Port on which Redis in-memory data structure store is running.
|
||||
# Default: REDIS_PORT=16379
|
||||
@@ -175,7 +106,10 @@ REDIS_PASSWORD=openIM123
|
||||
# ----- Kafka Configuration -----
|
||||
# Address or hostname for the Kafka service.
|
||||
# Default: KAFKA_ADDRESS=172.28.0.1
|
||||
KAFKA_ADDRESS=172.28.0.5
|
||||
KAFKA_ADDRESS=172.28.0.4
|
||||
|
||||
# Kakfa username to authenticate with the Kafka service.
|
||||
# KAFKA_USERNAME=''
|
||||
|
||||
# Port on which Kafka distributed streaming platform is running.
|
||||
# Default: KAFKA_PORT=19092
|
||||
@@ -196,7 +130,7 @@ KAFKA_OFFLINEMSG_MONGO_TOPIC=offlineMsgToMongoMysql
|
||||
# ----- MinIO Configuration ----
|
||||
# Address or hostname for the MinIO object storage service.
|
||||
# Default: MINIO_ADDRESS=172.28.0.1
|
||||
MINIO_ADDRESS=172.28.0.7
|
||||
MINIO_ADDRESS=172.28.0.6
|
||||
|
||||
# Port on which MinIO object storage service is running.
|
||||
# Default: MINIO_PORT=10005
|
||||
@@ -204,7 +138,7 @@ MINIO_PORT=10005
|
||||
|
||||
# Access key to authenticate with the MinIO service.
|
||||
# Default: MINIO_ACCESS_KEY=root
|
||||
MINIO_ACCESS_KEY=root
|
||||
# MINIO_ACCESS_KEY=root
|
||||
|
||||
# Secret key corresponding to the access key for MinIO authentication.
|
||||
# Default: MINIO_SECRET_KEY=openIM123
|
||||
@@ -213,7 +147,7 @@ MINIO_SECRET_KEY=openIM123
|
||||
# ----- Prometheus Configuration -----
|
||||
# Address or hostname for the Prometheus service.
|
||||
# Default: PROMETHEUS_ADDRESS=172.28.0.1
|
||||
PROMETHEUS_ADDRESS=172.28.0.11
|
||||
PROMETHEUS_ADDRESS=172.28.0.10
|
||||
|
||||
# Port on which Prometheus service is running.
|
||||
# Default: PROMETHEUS_PORT=19090
|
||||
@@ -222,11 +156,11 @@ PROMETHEUS_PORT=19090
|
||||
# ----- Grafana Configuration -----
|
||||
# Address or hostname for the Grafana service.
|
||||
# Default: GRAFANA_ADDRESS=172.28.0.1
|
||||
GRAFANA_ADDRESS=172.28.0.12
|
||||
GRAFANA_ADDRESS=172.28.0.11
|
||||
|
||||
# Port on which Grafana service is running.
|
||||
# Default: GRAFANA_PORT=3000
|
||||
GRAFANA_PORT=3000
|
||||
# Default: GRAFANA_PORT=13000
|
||||
GRAFANA_PORT=13000
|
||||
|
||||
# ======================================
|
||||
# ============ OpenIM Web ===============
|
||||
@@ -242,7 +176,7 @@ OPENIM_WEB_PORT=11001
|
||||
|
||||
# Address or hostname for the OpenIM web service.
|
||||
# Default: OPENIM_WEB_ADDRESS=172.28.0.1
|
||||
OPENIM_WEB_ADDRESS=172.28.0.8
|
||||
OPENIM_WEB_ADDRESS=172.28.0.7
|
||||
|
||||
# ======================================
|
||||
# ========= OpenIM Server ==============
|
||||
@@ -250,7 +184,7 @@ OPENIM_WEB_ADDRESS=172.28.0.8
|
||||
|
||||
# Address or hostname for the OpenIM server.
|
||||
# Default: OPENIM_SERVER_ADDRESS=172.28.0.1
|
||||
OPENIM_SERVER_ADDRESS=172.28.0.9
|
||||
OPENIM_SERVER_ADDRESS=172.28.0.8
|
||||
|
||||
# Port for the OpenIM WebSockets.
|
||||
# Default: OPENIM_WS_PORT=10001
|
||||
@@ -271,7 +205,7 @@ CHAT_BRANCH=main
|
||||
|
||||
# Address or hostname for the OpenIM chat service.
|
||||
# Default: OPENIM_CHAT_ADDRESS=172.28.0.1
|
||||
OPENIM_CHAT_ADDRESS=172.28.0.10
|
||||
OPENIM_CHAT_ADDRESS=172.28.0.9
|
||||
|
||||
# Port for the OpenIM chat API.
|
||||
# Default: OPENIM_CHAT_API_PORT=10008
|
||||
@@ -303,8 +237,8 @@ NODE_EXPORTER_PORT=19100
|
||||
PROMETHEUS_PORT=19090
|
||||
|
||||
# Port for the grafana.
|
||||
# Default: GRAFANA_PORT=3000
|
||||
GRAFANA_PORT=3000
|
||||
# Default: GRAFANA_PORT=13000
|
||||
GRAFANA_PORT=13000
|
||||
|
||||
# Port for the admin front.
|
||||
# Default: OPENIM_ADMIN_FRONT_PORT=11002
|
||||
@@ -154,8 +154,6 @@ GO111MODULE=on go get github.com/roboll/helmfile@latest
|
||||
```
|
||||
|
||||
```bash
|
||||
export MYSQL_ADDRESS=im-mysql
|
||||
export MYSQL_PORT=3306
|
||||
export MONGO_ADDRESS=im-mongo
|
||||
export MONGO_PORT=27017
|
||||
export REDIS_ADDRESS=im-redis-master
|
||||
|
||||
@@ -53,19 +53,6 @@ rpcRegisterName:
|
||||
openImAdminName: ${OPENIM_ADMIN_NAME}
|
||||
openImChatName: ${OPENIM_CHAT_NAME}
|
||||
|
||||
###################### MySQL ######################
|
||||
mysql:
|
||||
# address: [ 127.0.0.1:13306 ] #目前仅支持单机
|
||||
# username: root #用户名
|
||||
# password: openIM123 #密码
|
||||
# database: openIM_v2 #不建议修改
|
||||
# maxOpenConn: 1000 #最大连接数
|
||||
# maxIdleConn: 100 #最大空闲连接数
|
||||
# maxLifeTime: 60 #连接可以重复使用的最长时间(秒)
|
||||
# logLevel: 4 #日志级别 1=slient 2=error 3=warn 4=info
|
||||
# slowThreshold: 500 #慢语句阈值 (毫秒)
|
||||
database: openim_enterprise
|
||||
|
||||
###################### Log ######################
|
||||
log:
|
||||
storageLocation: ../logs/ #存放目录
|
||||
|
||||
@@ -1,24 +1,10 @@
|
||||
# Copyright © 2023 OpenIM. All rights reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
# ======================================
|
||||
# ========= Basic Configuration ========
|
||||
# ======================================
|
||||
|
||||
# The user for authentication or system operations.
|
||||
# Default: USER=root
|
||||
USER=${USER}
|
||||
# Default: OPENIM_USER=root
|
||||
USER=${OPENIM_USER}
|
||||
|
||||
# Password associated with the specified user for authentication.
|
||||
# Default: PASSWORD=openIM123
|
||||
@@ -55,61 +41,20 @@ DOCKER_BRIDGE_SUBNET=${DOCKER_BRIDGE_SUBNET}
|
||||
# Default: DOCKER_BRIDGE_GATEWAY=172.28.0.1
|
||||
DOCKER_BRIDGE_GATEWAY=${DOCKER_BRIDGE_GATEWAY}
|
||||
|
||||
# Address or hostname for the MySQL network.
|
||||
# Default: MYSQL_NETWORK_ADDRESS=172.28.0.2
|
||||
MYSQL_NETWORK_ADDRESS=${MYSQL_NETWORK_ADDRESS}
|
||||
|
||||
# Address or hostname for the MongoDB network.
|
||||
# Default: MONGO_NETWORK_ADDRESS=172.28.0.3
|
||||
MONGO_NETWORK_ADDRESS=${MONGO_NETWORK_ADDRESS}
|
||||
|
||||
# Address or hostname for the Redis network.
|
||||
# Default: REDIS_NETWORK_ADDRESS=172.28.0.4
|
||||
REDIS_NETWORK_ADDRESS=${REDIS_NETWORK_ADDRESS}
|
||||
|
||||
# Address or hostname for the Kafka network.
|
||||
# Default: KAFKA_NETWORK_ADDRESS=172.28.0.5
|
||||
KAFKA_NETWORK_ADDRESS=${KAFKA_NETWORK_ADDRESS}
|
||||
|
||||
# Address or hostname for the ZooKeeper network.
|
||||
# Default: ZOOKEEPER_NETWORK_ADDRESS=172.28.0.6
|
||||
ZOOKEEPER_NETWORK_ADDRESS=${ZOOKEEPER_NETWORK_ADDRESS}
|
||||
|
||||
# Address or hostname for the MinIO network.
|
||||
# Default: MINIO_NETWORK_ADDRESS=172.28.0.7
|
||||
MINIO_NETWORK_ADDRESS=${MINIO_NETWORK_ADDRESS}
|
||||
|
||||
# Address or hostname for the OpenIM web network.
|
||||
# Default: OPENIM_WEB_NETWORK_ADDRESS=172.28.0.8
|
||||
OPENIM_WEB_NETWORK_ADDRESS=${OPENIM_WEB_NETWORK_ADDRESS}
|
||||
|
||||
# Address or hostname for the OpenIM server network.
|
||||
# Default: OPENIM_SERVER_NETWORK_ADDRESS=172.28.0.9
|
||||
OPENIM_SERVER_NETWORK_ADDRESS=${OPENIM_SERVER_NETWORK_ADDRESS}
|
||||
|
||||
# Address or hostname for the OpenIM chat network.
|
||||
# Default: OPENIM_CHAT_NETWORK_ADDRESS=172.28.0.10
|
||||
OPENIM_CHAT_NETWORK_ADDRESS=${OPENIM_CHAT_NETWORK_ADDRESS}
|
||||
|
||||
# Address or hostname for the Prometheus network.
|
||||
# Default: PROMETHEUS_NETWORK_ADDRESS=172.28.0.11
|
||||
PROMETHEUS_NETWORK_ADDRESS=${PROMETHEUS_NETWORK_ADDRESS}
|
||||
|
||||
# Address or hostname for the Grafana network.
|
||||
# Default: GRAFANA_NETWORK_ADDRESS=172.28.0.12
|
||||
GRAFANA_NETWORK_ADDRESS=${GRAFANA_NETWORK_ADDRESS}
|
||||
|
||||
# Address or hostname for the node_exporter network.
|
||||
# Default: NODE_EXPORTER_NETWORK_ADDRESS=172.28.0.13
|
||||
NODE_EXPORTER_NETWORK_ADDRESS=${NODE_EXPORTER_NETWORK_ADDRESS}
|
||||
|
||||
# Address or hostname for the OpenIM admin network.
|
||||
# Default: OPENIM_ADMIN_NETWORK_ADDRESS=172.28.0.14
|
||||
OPENIM_ADMIN_FRONT_NETWORK_ADDRESS=${OPENIM_ADMIN_FRONT_NETWORK_ADDRESS}
|
||||
|
||||
# Address or hostname for the alertmanager network.
|
||||
# Default: ALERT_MANAGER_NETWORK_ADDRESS=172.28.0.15
|
||||
ALERT_MANAGER_NETWORK_ADDRESS=${ALERT_MANAGER_NETWORK_ADDRESS}
|
||||
|
||||
# ===============================================
|
||||
# = Component Extension Configuration =
|
||||
# ===============================================
|
||||
@@ -124,20 +69,6 @@ ZOOKEEPER_ADDRESS=${ZOOKEEPER_NETWORK_ADDRESS}
|
||||
# Default: ZOOKEEPER_PORT=12181
|
||||
ZOOKEEPER_PORT=${ZOOKEEPER_PORT}
|
||||
|
||||
# ----- MySQL Configuration -----
|
||||
|
||||
# Address or hostname for the MySQL service.
|
||||
# Default: MYSQL_ADDRESS=172.28.0.1
|
||||
MYSQL_ADDRESS=${MYSQL_NETWORK_ADDRESS}
|
||||
|
||||
# Port on which MySQL database service is running.
|
||||
# Default: MYSQL_PORT=13306
|
||||
MYSQL_PORT=${MYSQL_PORT}
|
||||
|
||||
# Password to authenticate with the MySQL database service.
|
||||
# Default: MYSQL_PASSWORD=openIM123
|
||||
MYSQL_PASSWORD=${MYSQL_PASSWORD}
|
||||
|
||||
# ----- MongoDB Configuration -----
|
||||
# Address or hostname for the MongoDB service.
|
||||
# Default: MONGO_ADDRESS=172.28.0.1
|
||||
@@ -145,11 +76,11 @@ MONGO_ADDRESS=${MONGO_NETWORK_ADDRESS}
|
||||
|
||||
# Port on which MongoDB service is running.
|
||||
# Default: MONGO_PORT=37017
|
||||
MONGO_PORT=${MONGO_PORT}
|
||||
# MONGO_PORT=${MONGO_PORT}
|
||||
|
||||
# Username to authenticate with the MongoDB service.
|
||||
# Default: MONGO_USERNAME=root
|
||||
MONGO_USERNAME=${MONGO_USERNAME}
|
||||
# MONGO_USERNAME=${MONGO_USERNAME}
|
||||
|
||||
# Password to authenticate with the MongoDB service.
|
||||
# Default: MONGO_PASSWORD=openIM123
|
||||
@@ -177,6 +108,9 @@ REDIS_PASSWORD=${REDIS_PASSWORD}
|
||||
# Default: KAFKA_ADDRESS=172.28.0.1
|
||||
KAFKA_ADDRESS=${KAFKA_NETWORK_ADDRESS}
|
||||
|
||||
# Kakfa username to authenticate with the Kafka service.
|
||||
# KAFKA_USERNAME=${KAFKA_USERNAME}
|
||||
|
||||
# Port on which Kafka distributed streaming platform is running.
|
||||
# Default: KAFKA_PORT=19092
|
||||
KAFKA_PORT=${KAFKA_PORT}
|
||||
@@ -204,7 +138,7 @@ MINIO_PORT=${MINIO_PORT}
|
||||
|
||||
# Access key to authenticate with the MinIO service.
|
||||
# Default: MINIO_ACCESS_KEY=root
|
||||
MINIO_ACCESS_KEY=${MINIO_ACCESS_KEY}
|
||||
# MINIO_ACCESS_KEY=${MINIO_ACCESS_KEY}
|
||||
|
||||
# Secret key corresponding to the access key for MinIO authentication.
|
||||
# Default: MINIO_SECRET_KEY=openIM123
|
||||
@@ -35,35 +35,22 @@ zookeeper:
|
||||
username: ${ZOOKEEPER_USERNAME}
|
||||
password: ${ZOOKEEPER_PASSWORD}
|
||||
|
||||
###################### Mysql ######################
|
||||
# MySQL configuration
|
||||
# Currently, only single machine setup is supported
|
||||
#
|
||||
# Maximum number of open connections
|
||||
# Maximum number of idle connections
|
||||
# Maximum lifetime in seconds a connection can be reused
|
||||
# Log level: 1=slient, 2=error, 3=warn, 4=info
|
||||
# Slow query threshold in milliseconds
|
||||
mysql:
|
||||
address: [ ${MYSQL_ADDRESS}:${MYSQL_PORT} ]
|
||||
username: ${MYSQL_USERNAME}
|
||||
password: ${MYSQL_PASSWORD}
|
||||
database: ${MYSQL_DATABASE}
|
||||
maxOpenConn: ${MYSQL_MAX_OPEN_CONN}
|
||||
maxIdleConn: ${MYSQL_MAX_IDLE_CONN}
|
||||
maxLifeTime: ${MYSQL_MAX_LIFETIME}
|
||||
logLevel: ${MYSQL_LOG_LEVEL}
|
||||
slowThreshold: ${MYSQL_SLOW_THRESHOLD}
|
||||
|
||||
###################### Mongo ######################
|
||||
# MongoDB configuration
|
||||
# If uri is not empty, it will be used directly
|
||||
#
|
||||
# MongoDB address for standalone setup, Mongos address for sharded cluster setup
|
||||
# Default MongoDB database name
|
||||
# Maximum connection pool size
|
||||
|
||||
# If uri is not empty, it will be used directly for the MongoDB connection.
|
||||
# This is a complete MongoDB URI string.
|
||||
# Example: mongodb://user:password@host1:port1,host2:port2/dbname?options
|
||||
mongo:
|
||||
uri: ${MONGO_URI}
|
||||
|
||||
# List of MongoDB server addresses.
|
||||
# Used for constructing the MongoDB URI if 'uri' above is empty.
|
||||
# For a standalone setup, specify the address of the single server.
|
||||
# For a sharded cluster, specify the addresses of the Mongos servers.
|
||||
# Example: [ '172.28.0.1:37017', '172.28.0.2:37017' ]
|
||||
# Default MongoDB database name
|
||||
# Maximum connection pool size
|
||||
address: [ ${MONGO_ADDRESS}:${MONGO_PORT} ]
|
||||
database: ${MONGO_DATABASE}
|
||||
username: ${MONGO_USERNAME}
|
||||
|
||||
+99
-121
@@ -7,70 +7,55 @@ networks:
|
||||
ipam:
|
||||
driver: default
|
||||
config:
|
||||
- subnet: '${DOCKER_BRIDGE_SUBNET}'
|
||||
gateway: '${DOCKER_BRIDGE_GATEWAY}'
|
||||
- subnet: '${DOCKER_BRIDGE_SUBNET:-172.28.0.0/16}'
|
||||
gateway: '${DOCKER_BRIDGE_GATEWAY:-172.28.0.1}'
|
||||
|
||||
services:
|
||||
mysql:
|
||||
image: mysql:5.7
|
||||
ports:
|
||||
- "${MYSQL_PORT}:3306"
|
||||
container_name: mysql
|
||||
volumes:
|
||||
- "${DATA_DIR}/components/mysql/data:/var/lib/mysql"
|
||||
- "/etc/localtime:/etc/localtime"
|
||||
environment:
|
||||
MYSQL_ROOT_PASSWORD: "${MYSQL_PASSWORD}"
|
||||
restart: always
|
||||
networks:
|
||||
server:
|
||||
ipv4_address: ${MYSQL_NETWORK_ADDRESS}
|
||||
|
||||
mongodb:
|
||||
image: mongo:6.0.2
|
||||
image: mongo:${MONGODB_IMAGE_VERSION-6.0.2}
|
||||
ports:
|
||||
- "${MONGO_PORT}:27017"
|
||||
- "${MONGO_PORT:-37017}:27017"
|
||||
container_name: mongo
|
||||
command: --wiredTigerCacheSizeGB 1 --auth
|
||||
volumes:
|
||||
- "${DATA_DIR}/components/mongodb/data/db:/data/db"
|
||||
- "${DATA_DIR}/components/mongodb/data/logs:/data/logs"
|
||||
- "${DATA_DIR}/components/mongodb/data/conf:/etc/mongo"
|
||||
- ./scripts/mongo-init.sh:/docker-entrypoint-initdb.d/mongo-init.sh:ro"
|
||||
- "${DATA_DIR:-./}/components/mongodb/data/db:/data/db"
|
||||
- "${DATA_DIR:-./}/components/mongodb/data/logs:/data/logs"
|
||||
- "${DATA_DIR:-./}/components/mongodb/data/conf:/etc/mongo"
|
||||
- ./scripts/mongo-init.sh:/docker-entrypoint-initdb.d/mongo-init.sh:ro
|
||||
environment:
|
||||
- TZ=Asia/Shanghai
|
||||
- wiredTigerCacheSizeGB=1
|
||||
- MONGO_INITDB_ROOT_USERNAME=${MONGO_USERNAME}
|
||||
- MONGO_INITDB_ROOT_PASSWORD=${MONGO_PASSWORD}
|
||||
- MONGO_INITDB_DATABASE=${MONGO_DATABASE}
|
||||
- MONGO_INITDB_ROOT_USERNAME=${MONGO_USERNAME:-root}
|
||||
- MONGO_INITDB_ROOT_PASSWORD=${MONGO_PASSWORD:-openIM123}
|
||||
- MONGO_INITDB_DATABASE=${MONGO_DATABASE:-openIM_v3}
|
||||
restart: always
|
||||
networks:
|
||||
server:
|
||||
ipv4_address: ${MONGO_NETWORK_ADDRESS}
|
||||
ipv4_address: ${MONGO_NETWORK_ADDRESS:-172.28.0.2}
|
||||
|
||||
redis:
|
||||
image: redis:7.0.0
|
||||
image: redis:${REDIS_IMAGE_VERSION:-7.0.0}
|
||||
container_name: redis
|
||||
ports:
|
||||
- "${REDIS_PORT}:6379"
|
||||
- "${REDIS_PORT:-16379}:6379"
|
||||
volumes:
|
||||
- "${DATA_DIR}/components/redis/data:/data"
|
||||
- "${DATA_DIR}/components/redis/config/redis.conf:/usr/local/redis/config/redis.conf"
|
||||
- "${DATA_DIR:-./}/components/redis/data:/data"
|
||||
- "${DATA_DIR:-./}/components/redis/config/redis.conf:/usr/local/redis/config/redis.conf"
|
||||
environment:
|
||||
TZ: Asia/Shanghai
|
||||
restart: always
|
||||
sysctls:
|
||||
net.core.somaxconn: 1024
|
||||
command: redis-server --requirepass ${REDIS_PASSWORD} --appendonly yes
|
||||
command: redis-server --requirepass ${REDIS_PASSWORD:-openIM123} --appendonly yes
|
||||
networks:
|
||||
server:
|
||||
ipv4_address: ${REDIS_NETWORK_ADDRESS}
|
||||
ipv4_address: ${REDIS_NETWORK_ADDRESS:-172.28.0.3}
|
||||
|
||||
zookeeper:
|
||||
image: bitnami/zookeeper:3.8
|
||||
image: bitnami/zookeeper:${ZOOKEEPER_IMAGE_VERSION:-3.8}
|
||||
container_name: zookeeper
|
||||
ports:
|
||||
- "${ZOOKEEPER_PORT}:2181"
|
||||
- "${ZOOKEEPER_PORT:-12181}:2181"
|
||||
volumes:
|
||||
- "/etc/localtime:/etc/localtime"
|
||||
environment:
|
||||
@@ -79,131 +64,124 @@ services:
|
||||
restart: always
|
||||
networks:
|
||||
server:
|
||||
ipv4_address: ${ZOOKEEPER_NETWORK_ADDRESS}
|
||||
ipv4_address: ${ZOOKEEPER_NETWORK_ADDRESS:-172.28.0.5}
|
||||
|
||||
kafka:
|
||||
image: 'bitnami/kafka:3.5.1'
|
||||
image: 'bitnami/kafka:${KAFKA_IMAGE_VERSION:-3.5.1}'
|
||||
container_name: kafka
|
||||
user: root
|
||||
restart: always
|
||||
user: ${KAFKA_USER:-root}
|
||||
ports:
|
||||
- "${KAFKA_PORT}:9094"
|
||||
- "${KAFKA_PORT:-19094}:9094"
|
||||
volumes:
|
||||
- ./scripts/create-topic.sh:/opt/bitnami/kafka/create-topic.sh
|
||||
- ${DATA_DIR}/components/kafka:/bitnami/kafka
|
||||
- "${DATA_DIR:-./}/components/kafka:/bitnami/kafka"
|
||||
command: >
|
||||
bash -c "
|
||||
/opt/bitnami/scripts/kafka/run.sh & sleep 5; /opt/bitnami/kafka/create-topic.sh; wait
|
||||
"
|
||||
bash -c "/opt/bitnami/scripts/kafka/run.sh & sleep 5; /opt/bitnami/kafka/create-topic.sh; wait"
|
||||
environment:
|
||||
- TZ=Asia/Shanghai
|
||||
- KAFKA_CFG_NODE_ID=0
|
||||
- KAFKA_CFG_PROCESS_ROLES=controller,broker
|
||||
- KAFKA_CFG_CONTROLLER_QUORUM_VOTERS=0@<your_host>:9093
|
||||
- KAFKA_CFG_LISTENERS=PLAINTEXT://:9092,CONTROLLER://:9093,EXTERNAL://:9094
|
||||
- KAFKA_CFG_ADVERTISED_LISTENERS=PLAINTEXT://kafka:9092,EXTERNAL://${DOCKER_BRIDGE_GATEWAY}:${KAFKA_PORT}
|
||||
- KAFKA_CFG_ADVERTISED_LISTENERS=PLAINTEXT://kafka:9092,EXTERNAL://${DOCKER_BRIDGE_GATEWAY:-172.28.0.1}:${KAFKA_PORT:-19094}
|
||||
- KAFKA_CFG_LISTENER_SECURITY_PROTOCOL_MAP=CONTROLLER:PLAINTEXT,EXTERNAL:PLAINTEXT,PLAINTEXT:PLAINTEXT
|
||||
- KAFKA_CFG_CONTROLLER_LISTENER_NAMES=CONTROLLER
|
||||
networks:
|
||||
server:
|
||||
ipv4_address: ${KAFKA_NETWORK_ADDRESS}
|
||||
ipv4_address: ${KAFKA_NETWORK_ADDRESS:-172.28.0.4}
|
||||
|
||||
minio:
|
||||
image: minio/minio
|
||||
image: minio/minio:${MINIO_IMAGE_VERSION:-latest}
|
||||
ports:
|
||||
- "${MINIO_PORT}:9000"
|
||||
- "${MINIO_PORT:-10005}:9000"
|
||||
- "9090:9090"
|
||||
container_name: minio
|
||||
volumes:
|
||||
- "${DATA_DIR}/components/mnt/data:/data"
|
||||
- "${DATA_DIR}/components/mnt/config:/root/.minio"
|
||||
- "${DATA_DIR:-./}/components/mnt/data:/data"
|
||||
- "${DATA_DIR:-./}/components/mnt/config:/root/.minio"
|
||||
environment:
|
||||
MINIO_ROOT_USER: "${MINIO_ACCESS_KEY}"
|
||||
MINIO_ROOT_PASSWORD: "${MINIO_SECRET_KEY}"
|
||||
MINIO_ROOT_USER: "${MINIO_ACCESS_KEY:-root}"
|
||||
MINIO_ROOT_PASSWORD: "${MINIO_SECRET_KEY:-openIM123}"
|
||||
restart: always
|
||||
command: minio server /data --console-address ':9090'
|
||||
networks:
|
||||
server:
|
||||
ipv4_address: ${MINIO_NETWORK_ADDRESS}
|
||||
ipv4_address: ${MINIO_NETWORK_ADDRESS:-172.28.0.6}
|
||||
|
||||
openim-web:
|
||||
# image: ghcr.io/openimsdk/openim-web:latest
|
||||
# image: registry.cn-hangzhou.aliyuncs.com/openimsdk/openim-web:latest
|
||||
# image: openim/openim-web:latest
|
||||
image: ${IMAGE_REGISTRY}/openim-web:latest
|
||||
image: ${IMAGE_REGISTRY:-ghcr.io/openimsdk}/openim-web:${OPENIM_WEB_IMAGE_VERSION:-latest}
|
||||
container_name: openim-web
|
||||
environment:
|
||||
- OPENIM_WEB_DIST_PATH=${OPENIM_WEB_DIST_PATH}
|
||||
- OPENIM_WEB_PORT=${OPENIM_WEB_PORT}
|
||||
- OPENIM_WEB_DIST_PATH=${OPENIM_WEB_DIST_PATH:-/app/dist}
|
||||
- OPENIM_WEB_PORT=${OPENIM_WEB_PORT:-11001}
|
||||
restart: always
|
||||
ports:
|
||||
- "${OPENIM_WEB_PORT}:11001"
|
||||
- "${OPENIM_WEB_PORT:-11001}:11001"
|
||||
networks:
|
||||
server:
|
||||
ipv4_address: ${OPENIM_WEB_NETWORK_ADDRESS}
|
||||
ipv4_address: ${OPENIM_WEB_NETWORK_ADDRESS:-172.28.0.7}
|
||||
|
||||
openim-admin:
|
||||
image: ${IMAGE_REGISTRY}/openim-admin-front:v3.4.0
|
||||
# image: ghcr.io/openimsdk/openim-admin-front:v3.4.0
|
||||
# image: registry.cn-hangzhou.aliyuncs.com/openimsdk/openim-admin-front:v3.4.0
|
||||
# image: openim/openim-admin-front:v3.4.0
|
||||
container_name: openim-admin
|
||||
restart: always
|
||||
ports:
|
||||
- "${OPENIM_ADMIN_FRONT_PORT}:80"
|
||||
networks:
|
||||
server:
|
||||
ipv4_address: ${OPENIM_ADMIN_FRONT_NETWORK_ADDRESS}
|
||||
# Uncomment and configure the following services as needed
|
||||
# openim-admin:
|
||||
# image: ${IMAGE_REGISTRY:-ghcr.io/openimsdk}/openim-admin-front:v3.4.0
|
||||
# container_name: openim-admin
|
||||
# restart: always
|
||||
# ports:
|
||||
# - "${OPENIM_ADMIN_FRONT_PORT:-11002}:80"
|
||||
# networks:
|
||||
# server:
|
||||
# ipv4_address: ${OPENIM_ADMIN_FRONT_NETWORK_ADDRESS:-172.28.0.13}
|
||||
|
||||
prometheus:
|
||||
image: prom/prometheus
|
||||
container_name: prometheus
|
||||
hostname: prometheus
|
||||
restart: always
|
||||
volumes:
|
||||
- ./config/prometheus.yml:/etc/prometheus/prometheus.yml
|
||||
- ./config/instance-down-rules.yml:/etc/prometheus/instance-down-rules.yml
|
||||
ports:
|
||||
- "${PROMETHEUS_PORT}:9090"
|
||||
networks:
|
||||
server:
|
||||
ipv4_address: ${PROMETHEUS_NETWORK_ADDRESS}
|
||||
# prometheus:
|
||||
# image: prom/prometheus
|
||||
# container_name: prometheus
|
||||
# hostname: prometheus
|
||||
# restart: always
|
||||
# volumes:
|
||||
# - ./config/prometheus.yml:/etc/prometheus/prometheus.yml
|
||||
# - ./config/instance-down-rules.yml:/etc/prometheus/instance-down-rules.yml
|
||||
# ports:
|
||||
# - "${PROMETHEUS_PORT:-19090}:9090"
|
||||
# networks:
|
||||
# server:
|
||||
# ipv4_address: ${PROMETHEUS_NETWORK_ADDRESS:-172.28.0.10}
|
||||
|
||||
alertmanager:
|
||||
image: prom/alertmanager
|
||||
container_name: alertmanager
|
||||
hostname: alertmanager
|
||||
restart: always
|
||||
volumes:
|
||||
- ./config/alertmanager.yml:/etc/alertmanager/alertmanager.yml
|
||||
- ./config/email.tmpl:/etc/alertmanager/email.tmpl
|
||||
ports:
|
||||
- "${ALERT_MANAGER_PORT}:9093"
|
||||
networks:
|
||||
server:
|
||||
ipv4_address: ${ALERT_MANAGER_NETWORK_ADDRESS}
|
||||
# alertmanager:
|
||||
# image: prom/alertmanager
|
||||
# container_name: alertmanager
|
||||
# hostname: alertmanager
|
||||
# restart: always
|
||||
# volumes:
|
||||
# - ./config/alertmanager.yml:/etc/alertmanager/alertmanager.yml
|
||||
# - ./config/email.tmpl:/etc/alertmanager/email.tmpl
|
||||
# ports:
|
||||
# - "${ALERT_MANAGER_PORT:-19093}:9093"
|
||||
# networks:
|
||||
# server:
|
||||
# ipv4_address: ${ALERT_MANAGER_NETWORK_ADDRESS:-172.28.0.14}
|
||||
|
||||
grafana:
|
||||
image: grafana/grafana
|
||||
container_name: grafana
|
||||
hostname: grafana
|
||||
user: root
|
||||
restart: always
|
||||
ports:
|
||||
- "${GRAFANA_PORT}:3000"
|
||||
volumes:
|
||||
- ${DATA_DIR}/components/grafana:/var/lib/grafana
|
||||
networks:
|
||||
server:
|
||||
ipv4_address: ${GRAFANA_NETWORK_ADDRESS}
|
||||
# grafana:
|
||||
# image: grafana/grafana
|
||||
# container_name: grafana
|
||||
# hostname: grafana
|
||||
# user: root
|
||||
# restart: always
|
||||
# ports:
|
||||
# - "${GRAFANA_PORT:-13000}:3000"
|
||||
# volumes:
|
||||
# - ${DATA_DIR:-./}/components/grafana:/var/lib/grafana
|
||||
# networks:
|
||||
# server:
|
||||
# ipv4_address: ${GRAFANA_NETWORK_ADDRESS:-172.28.0.11}
|
||||
|
||||
node-exporter:
|
||||
image: quay.io/prometheus/node-exporter
|
||||
container_name: node-exporter
|
||||
hostname: node-exporter
|
||||
restart: always
|
||||
ports:
|
||||
- "${NODE_EXPORTER_PORT}:9100"
|
||||
networks:
|
||||
server:
|
||||
ipv4_address: ${NODE_EXPORTER_NETWORK_ADDRESS}
|
||||
# node-exporter:
|
||||
# image: quay.io/prometheus/node-exporter
|
||||
# container_name: node-exporter
|
||||
# hostname: node-exporter
|
||||
# restart: always
|
||||
# ports:
|
||||
# - "${NODE_EXPORTER_PORT:-19100}:9100"
|
||||
# networks:
|
||||
# server:
|
||||
# ipv4_address: ${NODE_EXPORTER_NETWORK_ADDRESS:-172.28.0.12}
|
||||
|
||||
+7
-7
@@ -2,28 +2,28 @@
|
||||
# Each line is a file pattern followed by one or more owners.
|
||||
|
||||
# README files
|
||||
README.md @openimsdk/openim @cubxxw @openimsdk/bot @Bloomingg @FGadvancer @skiffer-git @wangchuxiao-dev @withchao
|
||||
README.md @openimsdk/openim @cubxxw @openimsdk/bot @Bloomingg @FGadvancer @skiffer-git @rfyiamcool @withchao
|
||||
|
||||
# Contributing guidelines
|
||||
CONTRIBUTING.md @cubxxw @openimsdk/bot @Bloomingg @FGadvancer @skiffer-git @wangchuxiao-dev @withchao
|
||||
CONTRIBUTING.md @cubxxw @openimsdk/bot @Bloomingg @FGadvancer @skiffer-git @rfyiamcool @withchao
|
||||
|
||||
# License files
|
||||
LICENSE @cubxxw @openimsdk/bot @Bloomingg @FGadvancer @skiffer-git @wangchuxiao-dev @withchao
|
||||
LICENSE @cubxxw @openimsdk/bot @Bloomingg @FGadvancer @skiffer-git @rfyiamcool @withchao
|
||||
|
||||
# Makefile
|
||||
Makefile @cubxxw @openimsdk/bot @Bloomingg @FGadvancer @skiffer-git @wangchuxiao-dev @withchao
|
||||
Makefile @cubxxw @openimsdk/bot @Bloomingg @FGadvancer @skiffer-git @rfyiamcool @withchao
|
||||
|
||||
# These owners will be the default owners for everything in
|
||||
# the repo. Unless a later match takes precedence,
|
||||
# @cubxxw and @openimsdk/bot will be requested for
|
||||
# review when someone opens a pull request.
|
||||
* @openimsdk/openim @cubxxw @openimsdk/bot @Bloomingg @FGadvancer @skiffer-git @wangchuxiao-dev @withchao
|
||||
* @openimsdk/openim @cubxxw @openimsdk/bot @Bloomingg @FGadvancer @skiffer-git @rfyiamcool @withchao
|
||||
|
||||
# Order is important; the last matching pattern takes the most
|
||||
# precedence. When someone opens a pull request that only
|
||||
# modifies JS files, only @js-owner and not the global
|
||||
# owner(s) will be requested for a review.
|
||||
*.js @cubxxw @openimsdk/bot @Bloomingg @FGadvancer @skiffer-git @wangchuxiao-dev @withchao
|
||||
*.js @cubxxw @openimsdk/bot @Bloomingg @FGadvancer @skiffer-git @rfyiamcool @withchao
|
||||
|
||||
# You can also use email addresses if you prefer. They'll be
|
||||
# used to look up users just like we do for commit author
|
||||
@@ -35,7 +35,7 @@ Makefile @cubxxw @openimsdk/bot @Bloomingg @FGadvancer @skiffer-git @wangch
|
||||
# be identified in the format @org/team-name. Teams must have
|
||||
# explicit write access to the repository. In this example,
|
||||
# the OpenIMSDK team in the github organization owns all .txt files.
|
||||
*.txt @cubxxw @openimsdk/bot @Bloomingg @FGadvancer @skiffer-git @wangchuxiao-dev @withchao
|
||||
*.txt @cubxxw @openimsdk/bot @Bloomingg @FGadvancer @skiffer-git @rfyiamcool @withchao
|
||||
|
||||
# The `docs/*` pattern will match files like
|
||||
# `docs/getting-started.md` but not further nested files like
|
||||
|
||||
@@ -11,7 +11,7 @@ OpenIM, an intricate project, requires a robust logging mechanism to diagnose is
|
||||
1. **Initialization**: The system begins by determining the verbosity level through the `OPENIM_VERBOSE` variable. If it's not set, a default value of 5 is assigned. This verbosity level dictates the depth of the log details.
|
||||
2. **Log File Setup**: Logs are stored in the directory specified by `OPENIM_OUTPUT`. If this variable isn't explicitly set, it defaults to the `_output` directory relative to the script location. Each log file is named based on the date to facilitate easy identification.
|
||||
3. **Logging Function**: The `echo_log()` function plays a pivotal role by writing messages to both the console (stdout) and the log file.
|
||||
4. **Logging to a file**: The `echo_log()` function writes to the log file by appending the message to the file. It also adds a timestamp to the message. path: `_output/logs/*`, Enable logging by default. Set to false to disable. If you wish to turn off output to log files set `ENABLE_LOGGING=flase`.
|
||||
4. **Logging to a file**: The `echo_log()` function writes to the log file by appending the message to the file. It also adds a timestamp to the message. path: `_output/logs/*`, Enable logging by default. Set to false to disable. If you wish to turn off output to log files set `export ENABLE_LOGGING=flase`.
|
||||
|
||||
### Key Functions & Their Usages
|
||||
|
||||
|
||||
@@ -296,19 +296,6 @@ Feel free to explore the MinIO documentation for more advanced configurations an
|
||||
| `ZOOKEEPER_USERNAME` | `""` | Username for Zookeeper. |
|
||||
| `ZOOKEEPER_PASSWORD` | `""` | Password for Zookeeper. |
|
||||
|
||||
### 2.6. <a name='MySQLConfiguration'></a>MySQL Configuration
|
||||
|
||||
**Description**: Configuration for MySQL, including port, address, and credentials.
|
||||
|
||||
| Parameter | Example Value | Description |
|
||||
| ---------------- | ------------------------ | ------------------- |
|
||||
| `MYSQL_PORT` | `"13306"` | Port for MySQL. |
|
||||
| `MYSQL_ADDRESS` | Docker Bridge Gateway IP | Address for MySQL. |
|
||||
| `MYSQL_USERNAME` | User-defined | Username for MySQL. |
|
||||
| `MYSQL_PASSWORD` | User-defined | Password for MySQL. |
|
||||
|
||||
Note: The configurations for other services (e.g., MONGO, REDIS, KAFKA, etc.) follow a similar pattern to MySQL and can be documented in a similar manner.
|
||||
|
||||
### 2.7. <a name='MongoDBConfiguration'></a>MongoDB Configuration
|
||||
|
||||
This section involves setting up MongoDB, including its port, address, and credentials.
|
||||
|
||||
@@ -30,7 +30,7 @@ Executing `make tools` ensures verification and installation of the default tool
|
||||
- go-junit-report
|
||||
- go-gitlint
|
||||
|
||||
The installation path is situated at `/root/workspaces/openim/Open-IM-Server/_output/tools/`.
|
||||
The installation path is situated at `./_output/tools/`.
|
||||
|
||||
## Toolset Categories
|
||||
|
||||
|
||||
@@ -4,16 +4,16 @@ go 1.19
|
||||
|
||||
require (
|
||||
firebase.google.com/go v3.13.0+incompatible
|
||||
github.com/OpenIMSDK/protocol v0.0.31
|
||||
github.com/OpenIMSDK/tools v0.0.20
|
||||
github.com/bwmarrin/snowflake v0.3.0 // indirect
|
||||
github.com/dtm-labs/rockscache v0.1.1
|
||||
github.com/gin-gonic/gin v1.9.1
|
||||
github.com/go-playground/validator/v10 v10.15.5
|
||||
github.com/gogo/protobuf v1.3.2
|
||||
github.com/golang-jwt/jwt/v4 v4.5.0
|
||||
github.com/golang/protobuf v1.5.3
|
||||
github.com/gorilla/websocket v1.5.0
|
||||
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0
|
||||
github.com/jinzhu/copier v0.4.0
|
||||
github.com/lestrrat-go/file-rotatelogs v2.4.0+incompatible // indirect
|
||||
github.com/minio/minio-go/v7 v7.0.63
|
||||
github.com/mitchellh/mapstructure v1.5.0
|
||||
@@ -29,19 +29,14 @@ require (
|
||||
google.golang.org/grpc v1.59.0
|
||||
google.golang.org/protobuf v1.31.0
|
||||
gopkg.in/yaml.v3 v3.0.1
|
||||
gorm.io/driver/mysql v1.5.2
|
||||
gorm.io/gorm v1.25.5
|
||||
)
|
||||
|
||||
require github.com/google/uuid v1.3.1
|
||||
|
||||
require (
|
||||
github.com/IBM/sarama v1.41.3
|
||||
github.com/OpenIMSDK/protocol v0.0.31
|
||||
github.com/OpenIMSDK/tools v0.0.17
|
||||
github.com/aliyun/aliyun-oss-go-sdk v2.2.9+incompatible
|
||||
github.com/go-redis/redis v6.15.9+incompatible
|
||||
github.com/go-sql-driver/mysql v1.7.1
|
||||
github.com/redis/go-redis/v9 v9.2.1
|
||||
github.com/tencentyun/cos-go-sdk-v5 v0.7.45
|
||||
go.uber.org/automaxprocs v1.5.3
|
||||
@@ -58,24 +53,6 @@ require (
|
||||
cloud.google.com/go/iam v1.1.2 // indirect
|
||||
cloud.google.com/go/longrunning v0.5.1 // indirect
|
||||
cloud.google.com/go/storage v1.30.1 // indirect
|
||||
github.com/aws/aws-sdk-go-v2 v1.23.1 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.5.1 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/config v1.25.4 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/credentials v1.16.3 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.14.5 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/internal/configsources v1.2.4 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.5.4 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/internal/ini v1.7.1 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/internal/v4a v1.2.4 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.10.1 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.2.4 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.10.4 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.16.4 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/s3 v1.43.1 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/sso v1.17.3 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.20.1 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/sts v1.25.4 // indirect
|
||||
github.com/aws/smithy-go v1.17.0 // indirect
|
||||
github.com/beorn7/perks v1.0.1 // indirect
|
||||
github.com/bytedance/sonic v1.9.1 // indirect
|
||||
github.com/cespare/xxhash/v2 v2.2.0 // indirect
|
||||
@@ -93,6 +70,7 @@ require (
|
||||
github.com/go-playground/universal-translator v0.18.1 // indirect
|
||||
github.com/go-zookeeper/zk v1.0.3 // indirect
|
||||
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
|
||||
github.com/golang/protobuf v1.5.3 // indirect
|
||||
github.com/golang/snappy v0.0.4 // indirect
|
||||
github.com/google/go-cmp v0.6.0 // indirect
|
||||
github.com/google/go-querystring v1.1.0 // indirect
|
||||
@@ -109,6 +87,7 @@ require (
|
||||
github.com/jcmturner/gofork v1.7.6 // indirect
|
||||
github.com/jcmturner/gokrb5/v8 v8.4.4 // indirect
|
||||
github.com/jcmturner/rpc/v2 v2.0.3 // indirect
|
||||
github.com/jinzhu/copier v0.3.5 // indirect
|
||||
github.com/jinzhu/inflection v1.0.0 // indirect
|
||||
github.com/jinzhu/now v1.1.5 // indirect
|
||||
github.com/json-iterator/go v1.1.12 // indirect
|
||||
@@ -133,7 +112,6 @@ require (
|
||||
github.com/prometheus/client_model v0.4.1-0.20230718164431-9a2bf3000d16 // indirect
|
||||
github.com/prometheus/common v0.44.0 // indirect
|
||||
github.com/prometheus/procfs v0.11.1 // indirect
|
||||
github.com/qiniu/go-sdk/v7 v7.18.2 // indirect
|
||||
github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 // indirect
|
||||
github.com/rs/xid v1.5.0 // indirect
|
||||
github.com/sergi/go-diff v1.0.0 // indirect
|
||||
@@ -152,7 +130,7 @@ require (
|
||||
golang.org/x/arch v0.3.0 // indirect
|
||||
golang.org/x/net v0.17.0 // indirect
|
||||
golang.org/x/oauth2 v0.13.0 // indirect
|
||||
golang.org/x/sys v0.13.0 // indirect
|
||||
golang.org/x/sys v0.14.0 // indirect
|
||||
golang.org/x/text v0.13.0 // indirect
|
||||
golang.org/x/time v0.3.0 // indirect
|
||||
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect
|
||||
@@ -162,6 +140,7 @@ require (
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20231012201019-e917dd12ba7a // indirect
|
||||
gopkg.in/src-d/go-billy.v4 v4.3.2 // indirect
|
||||
gopkg.in/warnings.v0 v0.1.2 // indirect
|
||||
gorm.io/gorm v1.23.8 // indirect
|
||||
)
|
||||
|
||||
require (
|
||||
|
||||
@@ -20,8 +20,8 @@ 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.31 h1:ax43x9aqA6EKNXNukS5MT5BSTqkUmwO4uTvbJLtzCgE=
|
||||
github.com/OpenIMSDK/protocol v0.0.31/go.mod h1:F25dFrwrIx3lkNoiuf6FkCfxuwf8L4Z8UIsdTHP/r0Y=
|
||||
github.com/OpenIMSDK/tools v0.0.17 h1:1E1HUOL2W09YUHBb4wBwrXoTSZm5ONVwLxlEX1GhlKw=
|
||||
github.com/OpenIMSDK/tools v0.0.17/go.mod h1:eg+q4A34Qmu73xkY0mt37FHGMCMfC6CtmOnm0kFEGFI=
|
||||
github.com/OpenIMSDK/tools v0.0.20 h1:zBTjQZRJ5lR1FIzP9mtWyAvh5dKsmJXQugi4p8X/97k=
|
||||
github.com/OpenIMSDK/tools v0.0.20/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=
|
||||
@@ -31,42 +31,6 @@ github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239 h1:kFOfPq6dUM1hTo
|
||||
github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c=
|
||||
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio=
|
||||
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs=
|
||||
github.com/aws/aws-sdk-go-v2 v1.23.1 h1:qXaFsOOMA+HsZtX8WoCa+gJnbyW7qyFFBlPqvTSzbaI=
|
||||
github.com/aws/aws-sdk-go-v2 v1.23.1/go.mod h1:i1XDttT4rnf6vxc9AuskLc6s7XBee8rlLilKlc03uAA=
|
||||
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.5.1 h1:ZY3108YtBNq96jNZTICHxN1gSBSbnvIdYwwqnvCV4Mc=
|
||||
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.5.1/go.mod h1:t8PYl/6LzdAqsU4/9tz28V/kU+asFePvpOMkdul0gEQ=
|
||||
github.com/aws/aws-sdk-go-v2/config v1.25.4 h1:r+X1x8QI6FEPdJDWCNBDZHyAcyFwSjHN8q8uuus+Axs=
|
||||
github.com/aws/aws-sdk-go-v2/config v1.25.4/go.mod h1:8GTjImECskr7D88P/Nn9uM4M4rLY9i77hLJZgkZEWV8=
|
||||
github.com/aws/aws-sdk-go-v2/credentials v1.16.3 h1:8PeI2krzzjDJ5etmgaMiD1JswsrLrWvKKu/uBUtNy1g=
|
||||
github.com/aws/aws-sdk-go-v2/credentials v1.16.3/go.mod h1:Kdh/okh+//vQ/AjEt81CjvkTo64+/zIE4OewP7RpfXk=
|
||||
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.14.5 h1:KehRNiVzIfAcj6gw98zotVbb/K67taJE0fkfgM6vzqU=
|
||||
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.14.5/go.mod h1:VhnExhw6uXy9QzetvpXDolo1/hjhx4u9qukBGkuUwjs=
|
||||
github.com/aws/aws-sdk-go-v2/internal/configsources v1.2.4 h1:LAm3Ycm9HJfbSCd5I+wqC2S9Ej7FPrgr5CQoOljJZcE=
|
||||
github.com/aws/aws-sdk-go-v2/internal/configsources v1.2.4/go.mod h1:xEhvbJcyUf/31yfGSQBe01fukXwXJ0gxDp7rLfymWE0=
|
||||
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.5.4 h1:4GV0kKZzUxiWxSVpn/9gwR0g21NF1Jsyduzo9rHgC/Q=
|
||||
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.5.4/go.mod h1:dYvTNAggxDZy6y1AF7YDwXsPuHFy/VNEpEI/2dWK9IU=
|
||||
github.com/aws/aws-sdk-go-v2/internal/ini v1.7.1 h1:uR9lXYjdPX0xY+NhvaJ4dD8rpSRz5VY81ccIIoNG+lw=
|
||||
github.com/aws/aws-sdk-go-v2/internal/ini v1.7.1/go.mod h1:6fQQgfuGmw8Al/3M2IgIllycxV7ZW7WCdVSqfBeUiCY=
|
||||
github.com/aws/aws-sdk-go-v2/internal/v4a v1.2.4 h1:40Q4X5ebZruRtknEZH/bg91sT5pR853F7/1X9QRbI54=
|
||||
github.com/aws/aws-sdk-go-v2/internal/v4a v1.2.4/go.mod h1:u77N7eEECzUv7F0xl2gcfK/vzc8wcjWobpy+DcrLJ5E=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.10.1 h1:rpkF4n0CyFcrJUG/rNNohoTmhtWlFTRI4BsZOh9PvLs=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.10.1/go.mod h1:l9ymW25HOqymeU2m1gbUQ3rUIsTwKs8gYHXkqDQUhiI=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.2.4 h1:6DRKQc+9cChgzL5gplRGusI5dBGeiEod4m/pmGbcX48=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.2.4/go.mod h1:s8ORvrW4g4v7IvYKIAoBg17w3GQ+XuwXDXYrQ5SkzU0=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.10.4 h1:rdovz3rEu0vZKbzoMYPTehp0E8veoE9AyfzqCr5Eeao=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.10.4/go.mod h1:aYCGNjyUCUelhofxlZyj63srdxWUSsBSGg5l6MCuXuE=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.16.4 h1:o3DcfCxGDIT20pTbVKVhp3vWXOj/VvgazNJvumWeYW0=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.16.4/go.mod h1:Uy0KVOxuTK2ne+/PKQ+VvEeWmjMMksE17k/2RK/r5oM=
|
||||
github.com/aws/aws-sdk-go-v2/service/s3 v1.43.1 h1:1w11lfXOa8HoHoSlNtt4mqv/N3HmDOa+OnUH3Y9DHm8=
|
||||
github.com/aws/aws-sdk-go-v2/service/s3 v1.43.1/go.mod h1:dqJ5JBL0clzgHriH35Amx3LRFY6wNIPUX7QO/BerSBo=
|
||||
github.com/aws/aws-sdk-go-v2/service/sso v1.17.3 h1:CdsSOGlFF3Pn+koXOIpTtvX7st0IuGsZ8kJqcWMlX54=
|
||||
github.com/aws/aws-sdk-go-v2/service/sso v1.17.3/go.mod h1:oA6VjNsLll2eVuUoF2D+CMyORgNzPEW/3PyUdq6WQjI=
|
||||
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.20.1 h1:cbRqFTVnJV+KRpwFl76GJdIZJKKCdTPnjUZ7uWh3pIU=
|
||||
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.20.1/go.mod h1:hHL974p5auvXlZPIjJTblXJpbkfK4klBczlsEaMCGVY=
|
||||
github.com/aws/aws-sdk-go-v2/service/sts v1.25.4 h1:yEvZ4neOQ/KpUqyR+X0ycUTW/kVRNR4nDZ38wStHGAA=
|
||||
github.com/aws/aws-sdk-go-v2/service/sts v1.25.4/go.mod h1:feTnm2Tk/pJxdX+eooEsxvlvTWBvDm6CasRZ+JOs2IY=
|
||||
github.com/aws/smithy-go v1.17.0 h1:wWJD7LX6PBV6etBUwO0zElG0nWN9rUhp0WdYeHSHAaI=
|
||||
github.com/aws/smithy-go v1.17.0/go.mod h1:NukqUGpCZIILqqiV0NIjeFh24kd/FAa4beRb6nbIUPE=
|
||||
github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8=
|
||||
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
|
||||
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
|
||||
@@ -92,7 +56,6 @@ github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDk
|
||||
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
|
||||
github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY=
|
||||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
@@ -128,24 +91,15 @@ github.com/gin-gonic/gin v1.9.1 h1:4idEAncQnU5cB7BeOkPtxjfCSye0AAm1R0RVIqJ+Jmg=
|
||||
github.com/gin-gonic/gin v1.9.1/go.mod h1:hPrL7YrpYKXt5YId3A/Tnip5kqbEAP+KLuI3SUcPTeU=
|
||||
github.com/gliderlabs/ssh v0.2.2 h1:6zsha5zo/TWhRhwqCD3+EarCAgZ2yN28ipRnGPnwkI0=
|
||||
github.com/gliderlabs/ssh v0.2.2/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0=
|
||||
github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
|
||||
github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s=
|
||||
github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8=
|
||||
github.com/go-playground/locales v0.14.0/go.mod h1:sawfccIbzZTqEDETgFXqTho0QybSa7l++s0DH+LDiLs=
|
||||
github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA=
|
||||
github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY=
|
||||
github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA=
|
||||
github.com/go-playground/universal-translator v0.18.0/go.mod h1:UvRDBj+xPUEGrFYl+lu/H90nyDXpg0fqeB/AQUGNTVA=
|
||||
github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY=
|
||||
github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
|
||||
github.com/go-playground/validator/v10 v10.8.0/go.mod h1:9JhgTzTaE31GZDpH/HSvHiRJrJ3iKAgqqH0Bl/Ocjdk=
|
||||
github.com/go-playground/validator/v10 v10.15.5 h1:LEBecTWb/1j5TNY1YYG2RcOUN3R7NLylN+x8TTueE24=
|
||||
github.com/go-playground/validator/v10 v10.15.5/go.mod h1:9iXMNT7sEkjXb0I+enO7QXmzG6QCsPWY4zveKFVRSyU=
|
||||
github.com/go-redis/redis v6.15.9+incompatible h1:K0pv1D7EQUjfyoMql+r/jZqCLizCGKFlFgcHWWmHQjg=
|
||||
github.com/go-redis/redis v6.15.9+incompatible/go.mod h1:NAIEuMOZ/fxfXJIrKDQDz8wamY7mA7PouImQ2Jvg6kA=
|
||||
github.com/go-sql-driver/mysql v1.7.0/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI=
|
||||
github.com/go-sql-driver/mysql v1.7.1 h1:lUIinVbN1DY0xBg0eMOzmmtGoHwWBbvnWubQUrtU8EI=
|
||||
github.com/go-sql-driver/mysql v1.7.1/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI=
|
||||
github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE=
|
||||
github.com/go-zookeeper/zk v1.0.3 h1:7M2kwOsc//9VeeFiPtf+uSJlVpU66x9Ba5+8XK7/TDg=
|
||||
github.com/go-zookeeper/zk v1.0.3/go.mod h1:nOB03cncLtlp4t+UAkGSV+9beXP/akpekBwL+UX1Qcw=
|
||||
@@ -236,10 +190,11 @@ github.com/jcmturner/gokrb5/v8 v8.4.4/go.mod h1:1btQEpgT6k+unzCwX1KdWMEwPPkkgBtP
|
||||
github.com/jcmturner/rpc/v2 v2.0.3 h1:7FXXj8Ti1IaVFpSAziCZWNzbNuZmnvw/i6CqLNdWfZY=
|
||||
github.com/jcmturner/rpc/v2 v2.0.3/go.mod h1:VUJYCIDm3PVOEHw8sgt091/20OJjskO/YJki3ELg/Hc=
|
||||
github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
|
||||
github.com/jinzhu/copier v0.4.0 h1:w3ciUoD19shMCRargcpm0cm91ytaBhDvuRpz1ODO/U8=
|
||||
github.com/jinzhu/copier v0.4.0/go.mod h1:DfbEm0FYsaqBcKcFuvmOZb218JkPGtvSHsKg8S8hyyg=
|
||||
github.com/jinzhu/copier v0.3.5 h1:GlvfUwHk62RokgqVNvYsku0TATCF7bAHVwEXoBh3iJg=
|
||||
github.com/jinzhu/copier v0.3.5/go.mod h1:DfbEm0FYsaqBcKcFuvmOZb218JkPGtvSHsKg8S8hyyg=
|
||||
github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E=
|
||||
github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
|
||||
github.com/jinzhu/now v1.1.4/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
|
||||
github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ=
|
||||
github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
|
||||
github.com/jonboulle/clockwork v0.4.0 h1:p4Cf1aMWXnXAUh8lVfewRBx1zaTSYKrKMF2g3ST4RZ4=
|
||||
@@ -257,15 +212,11 @@ github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa02
|
||||
github.com/klauspost/cpuid/v2 v2.2.5 h1:0E5MSMDEoAulmXNFquVs//DdoomxaoTY1kUhbc/qbZg=
|
||||
github.com/klauspost/cpuid/v2 v2.2.5/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws=
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
|
||||
github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk=
|
||||
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/pty v1.1.8/go.mod h1:O1sed60cT9XZ5uDucP5qwvh+TE3NnUj51EiZO/lmSfw=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||
github.com/leodido/go-urn v1.2.1/go.mod h1:zt4jvISO2HfUBqxjfIshjdMTYS56ZS/qv49ictyFfxY=
|
||||
github.com/leodido/go-urn v1.2.4 h1:XlAE/cm/ms7TE/VMVoduSpNBoyc2dOxHs5MZSwAN63Q=
|
||||
github.com/leodido/go-urn v1.2.4/go.mod h1:7ZrI8mTSeBSHl/UaRyKQW1qZeMgak41ANeCNaVckg+4=
|
||||
github.com/lestrrat-go/envload v0.0.0-20180220234015-a3eb8ddeffcc h1:RKf14vYWi2ttpEmkA4aQ3j4u9dStX2t4M8UM6qqNsG8=
|
||||
@@ -322,7 +273,6 @@ github.com/pelletier/go-toml/v2 v2.0.8 h1:0ctb6s9mE31h0/lhu+J6OPmVeDxJn+kYnJc2jZ
|
||||
github.com/pelletier/go-toml/v2 v2.0.8/go.mod h1:vuYfssBdrU2XDZ9bYydBu6t+6a6PYNcZljzZR9VXg+4=
|
||||
github.com/pierrec/lz4/v4 v4.1.18 h1:xaKrnTkyoqfh1YItXl56+6KJNVYWlEEPuAQW9xsplYQ=
|
||||
github.com/pierrec/lz4/v4 v4.1.18/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4=
|
||||
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
|
||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
@@ -338,18 +288,12 @@ github.com/prometheus/common v0.44.0 h1:+5BrQJwiBB9xsMygAB3TNvpQKOwlkc25LbISbrdO
|
||||
github.com/prometheus/common v0.44.0/go.mod h1:ofAIvZbQ1e/nugmZGz4/qCb9Ap1VoSTIO7x0VV9VvuY=
|
||||
github.com/prometheus/procfs v0.11.1 h1:xRC8Iq1yyca5ypa9n1EZnWZkt7dwcoRPQwX/5gwaUuI=
|
||||
github.com/prometheus/procfs v0.11.1/go.mod h1:eesXgaPo1q7lBpVMoMy0ZOFTth9hBn4W/y0/p/ScXhY=
|
||||
github.com/qiniu/dyn v1.3.0/go.mod h1:E8oERcm8TtwJiZvkQPbcAh0RL8jO1G0VXJMW3FAWdkk=
|
||||
github.com/qiniu/go-sdk/v7 v7.18.2 h1:vk9eo5OO7aqgAOPF0Ytik/gt7CMKuNgzC/IPkhda6rk=
|
||||
github.com/qiniu/go-sdk/v7 v7.18.2/go.mod h1:nqoYCNo53ZlGA521RvRethvxUDvXKt4gtYXOwye868w=
|
||||
github.com/qiniu/x v1.10.5/go.mod h1:03Ni9tj+N2h2aKnAz+6N0Xfl8FwMEDRC2PAlxekASDs=
|
||||
github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 h1:N/ElC8H3+5XpJzTSTfLsJV/mx9Q9g7kxmchpfZyxgzM=
|
||||
github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
|
||||
github.com/redis/go-redis/v9 v9.2.1 h1:WlYJg71ODF0dVspZZCpYmoF1+U1Jjk9Rwd7pq6QmlCg=
|
||||
github.com/redis/go-redis/v9 v9.2.1/go.mod h1:hdY0cQFCN4fnSYT6TkisLufl/4W5UIXyv0b/CLO2V2M=
|
||||
github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs=
|
||||
github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro=
|
||||
github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
|
||||
github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE=
|
||||
github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M=
|
||||
github.com/rs/xid v1.5.0 h1:mKX4bl4iPYJtEIxp6CYiUuLQ/8DYMoz0PUdtGgMFRVc=
|
||||
github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg=
|
||||
@@ -372,7 +316,6 @@ github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpE
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
|
||||
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||
@@ -423,10 +366,8 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk
|
||||
golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw=
|
||||
golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58=
|
||||
golang.org/x/crypto v0.14.0 h1:wBqGXzWJW6m1XrIKlAH0Hs1JJ7+9KBwnIO8v66Q9cHc=
|
||||
golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4=
|
||||
@@ -457,7 +398,6 @@ golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v
|
||||
golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk=
|
||||
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||
golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco=
|
||||
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
||||
golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
||||
golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM=
|
||||
@@ -490,19 +430,16 @@ golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||
golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE=
|
||||
golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.14.0 h1:Vz7Qs629MkJkGyHxUlRHizWJRG2j8fbQKjELVSNhy7Q=
|
||||
golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
|
||||
golang.org/x/term v0.13.0 h1:bb+I9cTfFazGW51MZqBVmZy7+JEJMouUHTUSKVQLBek=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
@@ -511,7 +448,6 @@ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||
golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ=
|
||||
golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k=
|
||||
golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
|
||||
@@ -572,8 +508,6 @@ google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqw
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
||||
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
|
||||
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
|
||||
gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA=
|
||||
gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
||||
@@ -593,14 +527,10 @@ gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
|
||||
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gorm.io/driver/mysql v1.5.2 h1:QC2HRskSE75wBuOxe0+iCkyJZ+RqpudsQtqkp+IMuXs=
|
||||
gorm.io/driver/mysql v1.5.2/go.mod h1:pQLhh1Ut/WUAySdTHwBpBv6+JKcj+ua4ZFx1QQTBzb8=
|
||||
gorm.io/gorm v1.25.2-0.20230530020048-26663ab9bf55/go.mod h1:L4uxeKpfBml98NYqVqwAdmV1a2nBtAec/cf3fpucW/k=
|
||||
gorm.io/gorm v1.25.5 h1:zR9lOiiYf09VNh5Q1gphfyia1JpiClIWG9hQaxB/mls=
|
||||
gorm.io/gorm v1.25.5/go.mod h1:hbnx/Oo0ChWMn1BIhpy1oYozzpM15i4YPuHDmfYtwg8=
|
||||
gorm.io/gorm v1.23.8 h1:h8sGJ+biDgBA1AD1Ha9gFCx7h8npU7AsLdlkX0n2TpE=
|
||||
gorm.io/gorm v1.23.8/go.mod h1:l2lP/RyAtc1ynaTjFksBde/O8v9oOGIApu2/xRitmZk=
|
||||
gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo=
|
||||
gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw=
|
||||
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
|
||||
@@ -13,4 +13,5 @@ use (
|
||||
./tools/component
|
||||
./tools/url2im
|
||||
./tools/data-conversion
|
||||
./tools/up35
|
||||
)
|
||||
|
||||
+7
-7
@@ -63,7 +63,7 @@ PROXY=
|
||||
GITHUB_TOKEN=
|
||||
|
||||
# Default user is "root". If you need to modify it, uncomment and replace accordingly.
|
||||
# USER=root
|
||||
# OPENIM_USER=root
|
||||
|
||||
# Default password for redis, mysql, mongo, as well as accessSecret in config/config.yaml.
|
||||
# Remember, it should be a combination of 8 or more numbers and letters. If you want to set a different password, uncomment and replace "openIM123".
|
||||
@@ -244,10 +244,10 @@ function download_source_code() {
|
||||
function set_openim_env() {
|
||||
warn "This command can only be executed once. It will modify the component passwords in docker-compose based on the PASSWORD variable in .env, and modify the component passwords in config/config.yaml. If the password in .env changes, you need to first execute docker-compose down; rm components -rf and then execute this command."
|
||||
# Set default values for user input
|
||||
# If the USER environment variable is not set, it defaults to 'root'
|
||||
if [ -z "$USER" ]; then
|
||||
USER="root"
|
||||
debug "USER is not set. Defaulting to 'root'."
|
||||
# If the OPENIM_USER environment variable is not set, it defaults to 'root'
|
||||
if [ -z "$OPENIM_USER" ]; then
|
||||
OPENIM_USER="root"
|
||||
debug "OPENIM_USER is not set. Defaulting to 'root'."
|
||||
fi
|
||||
|
||||
# If the PASSWORD environment variable is not set, it defaults to 'openIM123'
|
||||
@@ -321,7 +321,7 @@ function cmd_help() {
|
||||
|
||||
function parseinput() {
|
||||
# set default values
|
||||
# USER=root
|
||||
# OPENIM_USER=root
|
||||
# PASSWORD=openIM123
|
||||
# ENDPOINT=http://127.0.0.1:10005
|
||||
# API=http://127.0.0.1:10002/object/
|
||||
@@ -347,7 +347,7 @@ function parseinput() {
|
||||
;;
|
||||
-u|--user)
|
||||
shift
|
||||
USER=$1
|
||||
OPENIM_USER=$1
|
||||
;;
|
||||
-p|--password)
|
||||
shift
|
||||
|
||||
@@ -1,176 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
echo "Welcome to the Open-IM-Server installation scripts."
|
||||
echo "Please select an deploy option:"
|
||||
echo "1. docker-compose install"
|
||||
echo "2. exit"
|
||||
|
||||
clear_openimlog() {
|
||||
rm -rf ./logs/*
|
||||
}
|
||||
|
||||
is_path() {
|
||||
if [ -e "$1" ]; then
|
||||
return 1
|
||||
else
|
||||
return 0
|
||||
fi
|
||||
}
|
||||
|
||||
is_empty() {
|
||||
if [ -z "$1" ]; then
|
||||
return 1
|
||||
else
|
||||
return 0
|
||||
fi
|
||||
}
|
||||
|
||||
is_directory_exists() {
|
||||
if [ -d "$1" ]; then
|
||||
return 1
|
||||
else
|
||||
return 0
|
||||
fi
|
||||
}
|
||||
|
||||
edit_config() {
|
||||
echo "Is edit config.yaml?"
|
||||
echo "1. vi edit config"
|
||||
echo "2. do not edit config"
|
||||
read choice
|
||||
case $choice in
|
||||
1)
|
||||
vi config/config.yaml
|
||||
;;
|
||||
2)
|
||||
echo "do not edit config"
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
edit_enterprise_config() {
|
||||
echo "Is edit enterprise config.yaml?"
|
||||
echo "1. vi edit enterprise config"
|
||||
echo "2. do not edit enterprise config"
|
||||
read choice
|
||||
case $choice in
|
||||
1)
|
||||
vi ./.docker-compose_cfg/config.yaml
|
||||
;;
|
||||
2)
|
||||
echo "Do not edit enterprise config"
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
install_docker_compose() {
|
||||
echo "Please input the installation path, default is $(pwd)/Open-IM-Server, press enter to use default"
|
||||
read install_path
|
||||
is_empty $install_path
|
||||
if [ $? -eq 1 ]; then
|
||||
install_path="."
|
||||
fi
|
||||
echo "Installing Open-IM-Server to ${install_path}/Open-IM-Server..."
|
||||
is_path $install_path
|
||||
mkdir -p $install_path
|
||||
cd $install_path
|
||||
is_directory_exists "${install_path}/Open-IM-Server"
|
||||
if [ $? -eq 1 ]; then
|
||||
echo "WARNING: Directory $install_path/Open-IM-Server exist, please ensure your path"
|
||||
echo "1. delete the directory and install"
|
||||
echo "2. exit"
|
||||
read choice
|
||||
case $choice in
|
||||
1)
|
||||
rm -rf "${install_path}/Open-IM-Server"
|
||||
;;
|
||||
2)
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
rm -rf ./Open-IM-Server
|
||||
set -e
|
||||
git clone https://github.com/openimsdk/open-im-server.git --recursive;
|
||||
set +e
|
||||
cd ./Open-IM-Server
|
||||
git checkout errcode
|
||||
echo "======== git clone success ========"
|
||||
source .env
|
||||
if [ $DATA_DIR = "./" ]; then
|
||||
DATA_DIR=$(pwd)/components
|
||||
fi
|
||||
echo "Please input the components data directory, deault is ${DATA_DIR}, press enter to use default"
|
||||
read NEW_DATA_DIR
|
||||
is_empty $NEW_DATA_DIR
|
||||
if [ $? -eq 0 ]; then
|
||||
DATA_DIR=$NEW_DATA_DIR
|
||||
fi
|
||||
echo "Please input the user, deault is root, press enter to use default"
|
||||
read NEW_USER
|
||||
is_empty $NEW_USER
|
||||
if [ $? -eq 0 ]; then
|
||||
USER=$NEW_USER
|
||||
fi
|
||||
|
||||
echo "Please input the password, default is openIM123, press enter to use default"
|
||||
read NEW_PASSWORD
|
||||
is_empty $NEW_PASSWORD
|
||||
if [ $? -eq 0 ]; then
|
||||
PASSWORD=$NEW_PASSWORD
|
||||
fi
|
||||
|
||||
echo "Please input the minio_endpoint, default will detect auto, press enter to use default"
|
||||
read NEW_MINIO_ENDPOINT
|
||||
is_empty $NEW_MINIO_ENDPOINT
|
||||
if [ $? -eq 1 ]; then
|
||||
internet_ip=`curl ifconfig.me -s`
|
||||
MINIO_ENDPOINT="http://${internet_ip}:10005"
|
||||
else
|
||||
MINIO_ENDPOINT=$NEW_MINIO_ENDPOINT
|
||||
fi
|
||||
set -e
|
||||
export MINIO_ENDPOINT
|
||||
export USER
|
||||
export PASSWORD
|
||||
export DATA_DIR
|
||||
|
||||
cat <<EOF > .env
|
||||
USER=${USER}
|
||||
PASSWORD=${PASSWORD}
|
||||
MINIO_ENDPOINT=${MINIO_ENDPOINT}
|
||||
DATA_DIR=${DATA_DIR}
|
||||
EOF
|
||||
|
||||
edit_config
|
||||
edit_enterprise_config
|
||||
|
||||
cd scripts;
|
||||
chmod +x *.sh;
|
||||
./init-pwd.sh;
|
||||
./env_check.sh;
|
||||
cd ..;
|
||||
docker-compose up -d;
|
||||
cd scripts;
|
||||
./docker-check-service.sh;
|
||||
}
|
||||
|
||||
read choice
|
||||
|
||||
case $choice in
|
||||
1)
|
||||
install_docker_compose
|
||||
;;
|
||||
2)
|
||||
|
||||
;;
|
||||
3)
|
||||
;;
|
||||
4)
|
||||
echo "Exiting installation scripts..."
|
||||
exit 0
|
||||
;;
|
||||
*)
|
||||
echo "Invalid option, please try again."
|
||||
;;
|
||||
esac
|
||||
+1
-1
@@ -150,7 +150,7 @@ func (m *MessageApi) DeleteMsgPhysical(c *gin.Context) {
|
||||
}
|
||||
|
||||
func (m *MessageApi) getSendMsgReq(c *gin.Context, req apistruct.SendMsg) (sendMsgReq *msg.SendMsgReq, err error) {
|
||||
var data interface{}
|
||||
var data any
|
||||
log.ZDebug(c, "getSendMsgReq", "req", req.Content)
|
||||
switch req.ContentType {
|
||||
case constant.Text:
|
||||
|
||||
@@ -22,8 +22,8 @@ import (
|
||||
)
|
||||
|
||||
type Encoder interface {
|
||||
Encode(data interface{}) ([]byte, error)
|
||||
Decode(encodeData []byte, decodeData interface{}) error
|
||||
Encode(data any) ([]byte, error)
|
||||
Decode(encodeData []byte, decodeData any) error
|
||||
}
|
||||
|
||||
type GobEncoder struct{}
|
||||
@@ -32,7 +32,7 @@ func NewGobEncoder() *GobEncoder {
|
||||
return &GobEncoder{}
|
||||
}
|
||||
|
||||
func (g *GobEncoder) Encode(data interface{}) ([]byte, error) {
|
||||
func (g *GobEncoder) Encode(data any) ([]byte, error) {
|
||||
buff := bytes.Buffer{}
|
||||
enc := gob.NewEncoder(&buff)
|
||||
err := enc.Encode(data)
|
||||
@@ -42,7 +42,7 @@ func (g *GobEncoder) Encode(data interface{}) ([]byte, error) {
|
||||
return buff.Bytes(), nil
|
||||
}
|
||||
|
||||
func (g *GobEncoder) Decode(encodeData []byte, decodeData interface{}) error {
|
||||
func (g *GobEncoder) Decode(encodeData []byte, decodeData any) error {
|
||||
buff := bytes.NewBuffer(encodeData)
|
||||
dec := gob.NewDecoder(buff)
|
||||
err := dec.Decode(decodeData)
|
||||
|
||||
@@ -49,7 +49,7 @@ type LongConnServer interface {
|
||||
wsHandler(w http.ResponseWriter, r *http.Request)
|
||||
GetUserAllCons(userID string) ([]*Client, bool)
|
||||
GetUserPlatformCons(userID string, platform int) ([]*Client, bool, bool)
|
||||
Validate(s interface{}) error
|
||||
Validate(s any) error
|
||||
SetCacheHandler(cache cache.MsgModel)
|
||||
SetDiscoveryRegistry(client discoveryregistry.SvcDiscoveryRegistry)
|
||||
KickUserConn(client *Client) error
|
||||
@@ -60,6 +60,12 @@ type LongConnServer interface {
|
||||
MessageHandler
|
||||
}
|
||||
|
||||
var bufferPool = sync.Pool{
|
||||
New: func() any {
|
||||
return make([]byte, 1024)
|
||||
},
|
||||
}
|
||||
|
||||
type WsServer struct {
|
||||
port int
|
||||
wsMaxConnNum int64
|
||||
@@ -120,7 +126,7 @@ func (ws *WsServer) UnRegister(c *Client) {
|
||||
ws.unregisterChan <- c
|
||||
}
|
||||
|
||||
func (ws *WsServer) Validate(s interface{}) error {
|
||||
func (ws *WsServer) Validate(s any) error {
|
||||
//?question?
|
||||
return nil
|
||||
}
|
||||
@@ -145,7 +151,7 @@ func NewWsServer(opts ...Option) (*WsServer, error) {
|
||||
writeBufferSize: config.writeBufferSize,
|
||||
handshakeTimeout: config.handshakeTimeout,
|
||||
clientPool: sync.Pool{
|
||||
New: func() interface{} {
|
||||
New: func() any {
|
||||
return new(Client)
|
||||
},
|
||||
},
|
||||
|
||||
@@ -17,21 +17,20 @@ package msgtransfer
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"log"
|
||||
"net/http"
|
||||
"sync"
|
||||
|
||||
"github.com/OpenIMSDK/tools/mw"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"github.com/prometheus/client_golang/prometheus/collectors"
|
||||
"github.com/prometheus/client_golang/prometheus/promhttp"
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/credentials/insecure"
|
||||
"log"
|
||||
"net/http"
|
||||
"sync"
|
||||
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/common/db/cache"
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/common/db/controller"
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/common/db/relation"
|
||||
relationtb "github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation"
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/common/db/unrelation"
|
||||
kdisc "github.com/openimsdk/open-im-server/v3/pkg/common/discoveryregister"
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/common/prommetrics"
|
||||
@@ -39,20 +38,12 @@ import (
|
||||
)
|
||||
|
||||
type MsgTransfer struct {
|
||||
persistentCH *PersistentConsumerHandler // 聊天记录持久化到mysql的消费者 订阅的topic: ws2ms_chat
|
||||
historyCH *OnlineHistoryRedisConsumerHandler // 这个消费者聚合消息, 订阅的topic:ws2ms_chat, 修改通知发往msg_to_modify topic, 消息存入redis后Incr Redis, 再发消息到ms2pschat topic推送, 发消息到msg_to_mongo topic持久化
|
||||
historyMongoCH *OnlineHistoryMongoConsumerHandler // mongoDB批量插入, 成功后删除redis中消息,以及处理删除通知消息删除的 订阅的topic: msg_to_mongo
|
||||
// modifyCH *ModifyMsgConsumerHandler // 负责消费修改消息通知的consumer, 订阅的topic: msg_to_modify
|
||||
}
|
||||
|
||||
func StartTransfer(prometheusPort int) error {
|
||||
db, err := relation.NewGormDB()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err := db.AutoMigrate(&relationtb.ChatLogModel{}); err != nil {
|
||||
fmt.Printf("gorm: AutoMigrate ChatLogModel err: %v\n", err)
|
||||
}
|
||||
rdb, err := cache.NewRedis()
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -78,21 +69,16 @@ func StartTransfer(prometheusPort int) error {
|
||||
client.AddOption(mw.GrpcClient(), grpc.WithTransportCredentials(insecure.NewCredentials()))
|
||||
msgModel := cache.NewMsgCacheModel(rdb)
|
||||
msgDocModel := unrelation.NewMsgMongoDriver(mongo.GetDatabase())
|
||||
msgMysModel := relation.NewChatLogGorm(db)
|
||||
chatLogDatabase := controller.NewChatLogDatabase(msgMysModel)
|
||||
msgDatabase := controller.NewCommonMsgDatabase(msgDocModel, msgModel)
|
||||
conversationRpcClient := rpcclient.NewConversationRpcClient(client)
|
||||
groupRpcClient := rpcclient.NewGroupRpcClient(client)
|
||||
msgTransfer := NewMsgTransfer(chatLogDatabase, msgDatabase, &conversationRpcClient, &groupRpcClient)
|
||||
msgTransfer := NewMsgTransfer(msgDatabase, &conversationRpcClient, &groupRpcClient)
|
||||
return msgTransfer.Start(prometheusPort)
|
||||
}
|
||||
|
||||
func NewMsgTransfer(chatLogDatabase controller.ChatLogDatabase,
|
||||
msgDatabase controller.CommonMsgDatabase,
|
||||
conversationRpcClient *rpcclient.ConversationRpcClient, groupRpcClient *rpcclient.GroupRpcClient,
|
||||
) *MsgTransfer {
|
||||
func NewMsgTransfer(msgDatabase controller.CommonMsgDatabase, conversationRpcClient *rpcclient.ConversationRpcClient, groupRpcClient *rpcclient.GroupRpcClient) *MsgTransfer {
|
||||
return &MsgTransfer{
|
||||
persistentCH: NewPersistentConsumerHandler(chatLogDatabase), historyCH: NewOnlineHistoryRedisConsumerHandler(msgDatabase, conversationRpcClient, groupRpcClient),
|
||||
historyCH: NewOnlineHistoryRedisConsumerHandler(msgDatabase, conversationRpcClient, groupRpcClient),
|
||||
historyMongoCH: NewOnlineHistoryMongoConsumerHandler(msgDatabase),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -61,7 +61,7 @@ type TriggerChannelValue struct {
|
||||
|
||||
type Cmd2Value struct {
|
||||
Cmd int
|
||||
Value interface{}
|
||||
Value any
|
||||
}
|
||||
type ContextMsg struct {
|
||||
message *sdkws.MsgData
|
||||
|
||||
@@ -1,119 +0,0 @@
|
||||
// Copyright © 2023 OpenIM. All rights reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package msgtransfer
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/OpenIMSDK/protocol/constant"
|
||||
pbmsg "github.com/OpenIMSDK/protocol/msg"
|
||||
"github.com/OpenIMSDK/tools/log"
|
||||
"github.com/OpenIMSDK/tools/utils"
|
||||
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/common/db/controller"
|
||||
kfk "github.com/openimsdk/open-im-server/v3/pkg/common/kafka"
|
||||
|
||||
"github.com/IBM/sarama"
|
||||
"google.golang.org/protobuf/proto"
|
||||
)
|
||||
|
||||
type PersistentConsumerHandler struct {
|
||||
persistentConsumerGroup *kfk.MConsumerGroup
|
||||
chatLogDatabase controller.ChatLogDatabase
|
||||
}
|
||||
|
||||
func NewPersistentConsumerHandler(database controller.ChatLogDatabase) *PersistentConsumerHandler {
|
||||
return &PersistentConsumerHandler{
|
||||
persistentConsumerGroup: kfk.NewMConsumerGroup(&kfk.MConsumerGroupConfig{
|
||||
KafkaVersion: sarama.V2_0_0_0,
|
||||
OffsetsInitial: sarama.OffsetNewest, IsReturnErr: false,
|
||||
}, []string{config.Config.Kafka.LatestMsgToRedis.Topic},
|
||||
config.Config.Kafka.Addr, config.Config.Kafka.ConsumerGroupID.MsgToMySql),
|
||||
chatLogDatabase: database,
|
||||
}
|
||||
}
|
||||
|
||||
func (pc *PersistentConsumerHandler) handleChatWs2Mysql(
|
||||
ctx context.Context,
|
||||
cMsg *sarama.ConsumerMessage,
|
||||
msgKey string,
|
||||
_ sarama.ConsumerGroupSession,
|
||||
) {
|
||||
msg := cMsg.Value
|
||||
var tag bool
|
||||
msgFromMQ := pbmsg.MsgDataToMQ{}
|
||||
err := proto.Unmarshal(msg, &msgFromMQ)
|
||||
if err != nil {
|
||||
log.ZError(ctx, "msg_transfer Unmarshal msg err", err)
|
||||
return
|
||||
}
|
||||
|
||||
log.ZDebug(ctx, "handleChatWs2Mysql", "msg", msgFromMQ.MsgData)
|
||||
// Control whether to store history messages (mysql)
|
||||
isPersist := utils.GetSwitchFromOptions(msgFromMQ.MsgData.Options, constant.IsPersistent)
|
||||
// Only process receiver data
|
||||
if isPersist {
|
||||
switch msgFromMQ.MsgData.SessionType {
|
||||
case constant.SingleChatType, constant.NotificationChatType:
|
||||
if msgKey == msgFromMQ.MsgData.RecvID {
|
||||
tag = true
|
||||
}
|
||||
case constant.GroupChatType:
|
||||
if msgKey == msgFromMQ.MsgData.SendID {
|
||||
tag = true
|
||||
}
|
||||
case constant.SuperGroupChatType:
|
||||
tag = true
|
||||
}
|
||||
if tag {
|
||||
log.ZInfo(ctx, "msg_transfer msg persisting", "msg", string(msg))
|
||||
if err = pc.chatLogDatabase.CreateChatLog(&msgFromMQ); err != nil {
|
||||
log.ZError(ctx, "Message insert failed", err, "msg", msgFromMQ.String())
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
func (PersistentConsumerHandler) Setup(_ sarama.ConsumerGroupSession) error { return nil }
|
||||
func (PersistentConsumerHandler) Cleanup(_ sarama.ConsumerGroupSession) error { return nil }
|
||||
|
||||
func (pc *PersistentConsumerHandler) ConsumeClaim(
|
||||
sess sarama.ConsumerGroupSession,
|
||||
claim sarama.ConsumerGroupClaim,
|
||||
) error {
|
||||
for msg := range claim.Messages() {
|
||||
ctx := pc.persistentConsumerGroup.GetContextFromMsg(msg)
|
||||
log.ZDebug(
|
||||
ctx,
|
||||
"kafka get info to mysql",
|
||||
"msgTopic",
|
||||
msg.Topic,
|
||||
"msgPartition",
|
||||
msg.Partition,
|
||||
"msg",
|
||||
string(msg.Value),
|
||||
"key",
|
||||
string(msg.Key),
|
||||
)
|
||||
if len(msg.Value) != 0 {
|
||||
pc.handleChatWs2Mysql(ctx, msg, string(msg.Key), sess)
|
||||
} else {
|
||||
log.ZError(ctx, "msg get from kafka but is nil", nil, "key", msg.Key)
|
||||
}
|
||||
sess.MarkMessage(msg, "")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -21,9 +21,9 @@ import (
|
||||
)
|
||||
|
||||
type Resp struct {
|
||||
Code int `json:"code"`
|
||||
Msg string `json:"msg"`
|
||||
Data interface{} `json:"data"`
|
||||
Code int `json:"code"`
|
||||
Msg string `json:"msg"`
|
||||
Data any `json:"data"`
|
||||
}
|
||||
|
||||
func (r *Resp) parseError() (err error) {
|
||||
|
||||
@@ -159,7 +159,7 @@ func (g *Client) singlePush(ctx context.Context, token, userID string, pushReq P
|
||||
return g.request(ctx, pushURL, pushReq, token, nil)
|
||||
}
|
||||
|
||||
func (g *Client) request(ctx context.Context, url string, input interface{}, token string, output interface{}) error {
|
||||
func (g *Client) request(ctx context.Context, url string, input any, token string, output any) error {
|
||||
header := map[string]string{"token": token}
|
||||
resp := &Resp{}
|
||||
resp.Data = output
|
||||
@@ -170,7 +170,7 @@ func (g *Client) postReturn(
|
||||
ctx context.Context,
|
||||
url string,
|
||||
header map[string]string,
|
||||
input interface{},
|
||||
input any,
|
||||
output RespI,
|
||||
timeout int,
|
||||
) error {
|
||||
|
||||
@@ -23,7 +23,7 @@ const (
|
||||
)
|
||||
|
||||
type Audience struct {
|
||||
Object interface{}
|
||||
Object any
|
||||
audience map[string][]string
|
||||
}
|
||||
|
||||
|
||||
@@ -15,10 +15,10 @@
|
||||
package body
|
||||
|
||||
type Message struct {
|
||||
MsgContent string `json:"msg_content"`
|
||||
Title string `json:"title,omitempty"`
|
||||
ContentType string `json:"content_type,omitempty"`
|
||||
Extras map[string]interface{} `json:"extras,omitempty"`
|
||||
MsgContent string `json:"msg_content"`
|
||||
Title string `json:"title,omitempty"`
|
||||
ContentType string `json:"content_type,omitempty"`
|
||||
Extras map[string]any `json:"extras,omitempty"`
|
||||
}
|
||||
|
||||
func (m *Message) SetMsgContent(c string) {
|
||||
@@ -33,9 +33,9 @@ func (m *Message) SetContentType(c string) {
|
||||
m.ContentType = c
|
||||
}
|
||||
|
||||
func (m *Message) SetExtras(key string, value interface{}) {
|
||||
func (m *Message) SetExtras(key string, value any) {
|
||||
if m.Extras == nil {
|
||||
m.Extras = make(map[string]interface{})
|
||||
m.Extras = make(map[string]any)
|
||||
}
|
||||
m.Extras[key] = value
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@ const (
|
||||
)
|
||||
|
||||
type Platform struct {
|
||||
Os interface{}
|
||||
Os any
|
||||
osArry []string
|
||||
}
|
||||
|
||||
|
||||
@@ -15,11 +15,11 @@
|
||||
package body
|
||||
|
||||
type PushObj struct {
|
||||
Platform interface{} `json:"platform"`
|
||||
Audience interface{} `json:"audience"`
|
||||
Notification interface{} `json:"notification,omitempty"`
|
||||
Message interface{} `json:"message,omitempty"`
|
||||
Options interface{} `json:"options,omitempty"`
|
||||
Platform any `json:"platform"`
|
||||
Audience any `json:"audience"`
|
||||
Notification any `json:"notification,omitempty"`
|
||||
Message any `json:"message,omitempty"`
|
||||
Options any `json:"options,omitempty"`
|
||||
}
|
||||
|
||||
func (p *PushObj) SetPlatform(pf *Platform) {
|
||||
|
||||
@@ -69,11 +69,11 @@ func (j *JPush) Push(ctx context.Context, userIDs []string, title, content strin
|
||||
pushObj.SetNotification(&no)
|
||||
pushObj.SetMessage(&msg)
|
||||
pushObj.SetOptions(&opt)
|
||||
var resp interface{}
|
||||
var resp any
|
||||
return j.request(ctx, pushObj, resp, 5)
|
||||
}
|
||||
|
||||
func (j *JPush) request(ctx context.Context, po body.PushObj, resp interface{}, timeout int) error {
|
||||
func (j *JPush) request(ctx context.Context, po body.PushObj, resp any, timeout int) error {
|
||||
return http2.PostReturn(
|
||||
ctx,
|
||||
config.Config.Push.Jpns.PushUrl,
|
||||
|
||||
@@ -16,6 +16,7 @@ package push
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/OpenIMSDK/tools/utils"
|
||||
"sync"
|
||||
|
||||
"google.golang.org/grpc"
|
||||
@@ -78,7 +79,14 @@ func (r *pushServer) PushMsg(ctx context.Context, pbData *pbpush.PushMsgReq) (re
|
||||
case constant.SuperGroupChatType:
|
||||
err = r.pusher.Push2SuperGroup(ctx, pbData.MsgData.GroupID, pbData.MsgData)
|
||||
default:
|
||||
err = r.pusher.Push2User(ctx, []string{pbData.MsgData.RecvID, pbData.MsgData.SendID}, pbData.MsgData)
|
||||
var pushUserIDList []string
|
||||
isSenderSync := utils.GetSwitchFromOptions(pbData.MsgData.Options, constant.IsSenderSync)
|
||||
if !isSenderSync {
|
||||
pushUserIDList = append(pushUserIDList, pbData.MsgData.RecvID)
|
||||
} else {
|
||||
pushUserIDList = append(pushUserIDList, pbData.MsgData.RecvID, pbData.MsgData.SendID)
|
||||
}
|
||||
err = r.pusher.Push2User(ctx, pushUserIDList, pbData.MsgData)
|
||||
}
|
||||
if err != nil {
|
||||
if err != errNoOfflinePusher {
|
||||
|
||||
@@ -133,7 +133,7 @@ func (p *Pusher) Push2User(ctx context.Context, userIDs []string, msg *sdkws.Msg
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *Pusher) UnmarshalNotificationElem(bytes []byte, t interface{}) error {
|
||||
func (p *Pusher) UnmarshalNotificationElem(bytes []byte, t any) error {
|
||||
var notification sdkws.NotificationElem
|
||||
if err := json.Unmarshal(bytes, ¬ification); err != nil {
|
||||
return err
|
||||
|
||||
@@ -16,6 +16,12 @@ package conversation
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
|
||||
"github.com/OpenIMSDK/tools/tx"
|
||||
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/common/db/mgo"
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/common/db/unrelation"
|
||||
|
||||
"google.golang.org/grpc"
|
||||
|
||||
@@ -24,13 +30,11 @@ import (
|
||||
"github.com/OpenIMSDK/tools/discoveryregistry"
|
||||
"github.com/OpenIMSDK/tools/errs"
|
||||
"github.com/OpenIMSDK/tools/log"
|
||||
"github.com/OpenIMSDK/tools/tx"
|
||||
"github.com/OpenIMSDK/tools/utils"
|
||||
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/common/convert"
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/common/db/cache"
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/common/db/controller"
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/common/db/relation"
|
||||
tablerelation "github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation"
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/rpcclient"
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/rpcclient/notification"
|
||||
@@ -43,24 +47,24 @@ type conversationServer struct {
|
||||
}
|
||||
|
||||
func Start(client discoveryregistry.SvcDiscoveryRegistry, server *grpc.Server) error {
|
||||
db, err := relation.NewGormDB()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err := db.AutoMigrate(&tablerelation.ConversationModel{}); err != nil {
|
||||
return err
|
||||
}
|
||||
rdb, err := cache.NewRedis()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
conversationDB := relation.NewConversationGorm(db)
|
||||
mongo, err := unrelation.NewMongo()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
conversationDB, err := mgo.NewConversationMongo(mongo.GetDatabase())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
groupRpcClient := rpcclient.NewGroupRpcClient(client)
|
||||
msgRpcClient := rpcclient.NewMessageRpcClient(client)
|
||||
pbconversation.RegisterConversationServer(server, &conversationServer{
|
||||
conversationNotificationSender: notification.NewConversationNotificationSender(&msgRpcClient),
|
||||
groupRpcClient: &groupRpcClient,
|
||||
conversationDatabase: controller.NewConversationDatabase(conversationDB, cache.NewConversationRedis(rdb, cache.GetDefaultOpt(), conversationDB), tx.NewGorm(db)),
|
||||
conversationDatabase: controller.NewConversationDatabase(conversationDB, cache.NewConversationRedis(rdb, cache.GetDefaultOpt(), conversationDB), tx.NewMongo(mongo.GetClient())),
|
||||
})
|
||||
return nil
|
||||
}
|
||||
@@ -145,7 +149,7 @@ func (c *conversationServer) SetConversations(ctx context.Context,
|
||||
conversation.ConversationType = req.Conversation.ConversationType
|
||||
conversation.UserID = req.Conversation.UserID
|
||||
conversation.GroupID = req.Conversation.GroupID
|
||||
m := make(map[string]interface{})
|
||||
m := make(map[string]any)
|
||||
if req.Conversation.RecvMsgOpt != nil {
|
||||
m["recv_msg_opt"] = req.Conversation.RecvMsgOpt.Value
|
||||
if req.Conversation.RecvMsgOpt.Value != conv.RecvMsgOpt {
|
||||
@@ -229,11 +233,12 @@ func (c *conversationServer) SetConversations(ctx context.Context,
|
||||
|
||||
// 获取超级大群开启免打扰的用户ID.
|
||||
func (c *conversationServer) GetRecvMsgNotNotifyUserIDs(ctx context.Context, req *pbconversation.GetRecvMsgNotNotifyUserIDsReq) (*pbconversation.GetRecvMsgNotNotifyUserIDsResp, error) {
|
||||
userIDs, err := c.conversationDatabase.FindRecvMsgNotNotifyUserIDs(ctx, req.GroupID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &pbconversation.GetRecvMsgNotNotifyUserIDsResp{UserIDs: userIDs}, nil
|
||||
//userIDs, err := c.conversationDatabase.FindRecvMsgNotNotifyUserIDs(ctx, req.GroupID)
|
||||
//if err != nil {
|
||||
// return nil, err
|
||||
//}
|
||||
//return &pbconversation.GetRecvMsgNotNotifyUserIDsResp{UserIDs: userIDs}, nil
|
||||
return nil, errors.New("deprecated")
|
||||
}
|
||||
|
||||
// create conversation without notification for msg redis transfer.
|
||||
@@ -284,7 +289,7 @@ func (c *conversationServer) CreateGroupChatConversations(ctx context.Context, r
|
||||
|
||||
func (c *conversationServer) SetConversationMaxSeq(ctx context.Context, req *pbconversation.SetConversationMaxSeqReq) (*pbconversation.SetConversationMaxSeqResp, error) {
|
||||
if err := c.conversationDatabase.UpdateUsersConversationFiled(ctx, req.OwnerUserID, req.ConversationID,
|
||||
map[string]interface{}{"max_seq": req.MaxSeq}); err != nil {
|
||||
map[string]any{"max_seq": req.MaxSeq}); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &pbconversation.SetConversationMaxSeqResp{}, nil
|
||||
|
||||
@@ -27,19 +27,11 @@ import (
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation"
|
||||
)
|
||||
|
||||
func (s *friendServer) GetPaginationBlacks(
|
||||
ctx context.Context,
|
||||
req *pbfriend.GetPaginationBlacksReq,
|
||||
) (resp *pbfriend.GetPaginationBlacksResp, err error) {
|
||||
func (s *friendServer) GetPaginationBlacks(ctx context.Context, req *pbfriend.GetPaginationBlacksReq) (resp *pbfriend.GetPaginationBlacksResp, err error) {
|
||||
if err := s.userRpcClient.Access(ctx, req.UserID); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var pageNumber, showNumber int32
|
||||
if req.Pagination != nil {
|
||||
pageNumber = req.Pagination.PageNumber
|
||||
showNumber = req.Pagination.ShowNumber
|
||||
}
|
||||
blacks, total, err := s.blackDatabase.FindOwnerBlacks(ctx, req.UserID, pageNumber, showNumber)
|
||||
total, blacks, err := s.blackDatabase.FindOwnerBlacks(ctx, req.UserID, req.Pagination)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -63,10 +55,7 @@ func (s *friendServer) IsBlack(ctx context.Context, req *pbfriend.IsBlackReq) (*
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
func (s *friendServer) RemoveBlack(
|
||||
ctx context.Context,
|
||||
req *pbfriend.RemoveBlackReq,
|
||||
) (*pbfriend.RemoveBlackResp, error) {
|
||||
func (s *friendServer) RemoveBlack(ctx context.Context, req *pbfriend.RemoveBlackReq) (*pbfriend.RemoveBlackResp, error) {
|
||||
if err := s.userRpcClient.Access(ctx, req.OwnerUserID); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -74,9 +63,6 @@ func (s *friendServer) RemoveBlack(
|
||||
return nil, err
|
||||
}
|
||||
s.notificationSender.BlackDeletedNotification(ctx, req)
|
||||
if err := CallbackAfterRemoveBlack(ctx, req); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &pbfriend.RemoveBlackResp{}, nil
|
||||
}
|
||||
|
||||
@@ -88,9 +74,6 @@ func (s *friendServer) AddBlack(ctx context.Context, req *pbfriend.AddBlackReq)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := CallbackBeforeAddBlack(ctx, req); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
black := relation.BlackModel{
|
||||
OwnerUserID: req.OwnerUserID,
|
||||
BlockUserID: req.BlackUserID,
|
||||
|
||||
@@ -16,6 +16,7 @@ package friend
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/OpenIMSDK/tools/tx"
|
||||
|
||||
"github.com/OpenIMSDK/protocol/sdkws"
|
||||
|
||||
@@ -32,13 +33,13 @@ import (
|
||||
pbfriend "github.com/OpenIMSDK/protocol/friend"
|
||||
registry "github.com/OpenIMSDK/tools/discoveryregistry"
|
||||
"github.com/OpenIMSDK/tools/errs"
|
||||
"github.com/OpenIMSDK/tools/tx"
|
||||
"github.com/OpenIMSDK/tools/utils"
|
||||
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/common/db/cache"
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/common/db/controller"
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/common/db/relation"
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/common/db/mgo"
|
||||
tablerelation "github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation"
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/common/db/unrelation"
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/rpcclient/notification"
|
||||
)
|
||||
|
||||
@@ -52,49 +53,65 @@ type friendServer struct {
|
||||
}
|
||||
|
||||
func Start(client registry.SvcDiscoveryRegistry, server *grpc.Server) error {
|
||||
db, err := relation.NewGormDB()
|
||||
// Initialize MongoDB
|
||||
mongo, err := unrelation.NewMongo()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err := db.AutoMigrate(&tablerelation.FriendModel{}, &tablerelation.FriendRequestModel{}, &tablerelation.BlackModel{}); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Initialize Redis
|
||||
rdb, err := cache.NewRedis()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
blackDB := relation.NewBlackGorm(db)
|
||||
friendDB := relation.NewFriendGorm(db)
|
||||
|
||||
friendMongoDB, err := mgo.NewFriendMongo(mongo.GetDatabase())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
friendRequestMongoDB, err := mgo.NewFriendRequestMongo(mongo.GetDatabase())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
blackMongoDB, err := mgo.NewBlackMongo(mongo.GetDatabase())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Initialize RPC clients
|
||||
userRpcClient := rpcclient.NewUserRpcClient(client)
|
||||
msgRpcClient := rpcclient.NewMessageRpcClient(client)
|
||||
|
||||
// Initialize notification sender
|
||||
notificationSender := notification.NewFriendNotificationSender(
|
||||
&msgRpcClient,
|
||||
notification.WithRpcFunc(userRpcClient.GetUsersInfo),
|
||||
)
|
||||
// Register Friend server with refactored MongoDB and Redis integrations
|
||||
pbfriend.RegisterFriendServer(server, &friendServer{
|
||||
friendDatabase: controller.NewFriendDatabase(
|
||||
friendDB,
|
||||
relation.NewFriendRequestGorm(db),
|
||||
cache.NewFriendCacheRedis(rdb, friendDB, cache.GetDefaultOpt()),
|
||||
tx.NewGorm(db),
|
||||
friendMongoDB,
|
||||
friendRequestMongoDB,
|
||||
cache.NewFriendCacheRedis(rdb, friendMongoDB, cache.GetDefaultOpt()),
|
||||
tx.NewMongo(mongo.GetClient()),
|
||||
),
|
||||
blackDatabase: controller.NewBlackDatabase(
|
||||
blackDB,
|
||||
cache.NewBlackCacheRedis(rdb, blackDB, cache.GetDefaultOpt()),
|
||||
blackMongoDB,
|
||||
cache.NewBlackCacheRedis(rdb, blackMongoDB, cache.GetDefaultOpt()),
|
||||
),
|
||||
userRpcClient: &userRpcClient,
|
||||
notificationSender: notificationSender,
|
||||
RegisterCenter: client,
|
||||
conversationRpcClient: rpcclient.NewConversationRpcClient(client),
|
||||
})
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// ok.
|
||||
func (s *friendServer) ApplyToAddFriend(
|
||||
ctx context.Context,
|
||||
req *pbfriend.ApplyToAddFriendReq,
|
||||
) (resp *pbfriend.ApplyToAddFriendResp, err error) {
|
||||
func (s *friendServer) ApplyToAddFriend(ctx context.Context, req *pbfriend.ApplyToAddFriendReq) (resp *pbfriend.ApplyToAddFriendResp, err error) {
|
||||
defer log.ZInfo(ctx, utils.GetFuncName()+" Return")
|
||||
resp = &pbfriend.ApplyToAddFriendResp{}
|
||||
if err := authverify.CheckAccessV3(ctx, req.FromUserID); err != nil {
|
||||
@@ -127,10 +144,7 @@ func (s *friendServer) ApplyToAddFriend(
|
||||
}
|
||||
|
||||
// ok.
|
||||
func (s *friendServer) ImportFriends(
|
||||
ctx context.Context,
|
||||
req *pbfriend.ImportFriendReq,
|
||||
) (resp *pbfriend.ImportFriendResp, err error) {
|
||||
func (s *friendServer) ImportFriends(ctx context.Context, req *pbfriend.ImportFriendReq) (resp *pbfriend.ImportFriendResp, err error) {
|
||||
defer log.ZInfo(ctx, utils.GetFuncName()+" Return")
|
||||
if err := authverify.CheckAdmin(ctx); err != nil {
|
||||
return nil, err
|
||||
@@ -165,10 +179,7 @@ func (s *friendServer) ImportFriends(
|
||||
}
|
||||
|
||||
// ok.
|
||||
func (s *friendServer) RespondFriendApply(
|
||||
ctx context.Context,
|
||||
req *pbfriend.RespondFriendApplyReq,
|
||||
) (resp *pbfriend.RespondFriendApplyResp, err error) {
|
||||
func (s *friendServer) RespondFriendApply(ctx context.Context, req *pbfriend.RespondFriendApplyReq) (resp *pbfriend.RespondFriendApplyResp, err error) {
|
||||
defer log.ZInfo(ctx, utils.GetFuncName()+" Return")
|
||||
resp = &pbfriend.RespondFriendApplyResp{}
|
||||
if err := authverify.CheckAccessV3(ctx, req.ToUserID); err != nil {
|
||||
@@ -204,10 +215,7 @@ func (s *friendServer) RespondFriendApply(
|
||||
}
|
||||
|
||||
// ok.
|
||||
func (s *friendServer) DeleteFriend(
|
||||
ctx context.Context,
|
||||
req *pbfriend.DeleteFriendReq,
|
||||
) (resp *pbfriend.DeleteFriendResp, err error) {
|
||||
func (s *friendServer) DeleteFriend(ctx context.Context, req *pbfriend.DeleteFriendReq) (resp *pbfriend.DeleteFriendResp, err error) {
|
||||
defer log.ZInfo(ctx, utils.GetFuncName()+" Return")
|
||||
resp = &pbfriend.DeleteFriendResp{}
|
||||
if err := s.userRpcClient.Access(ctx, req.OwnerUserID); err != nil {
|
||||
@@ -228,10 +236,7 @@ func (s *friendServer) DeleteFriend(
|
||||
}
|
||||
|
||||
// ok.
|
||||
func (s *friendServer) SetFriendRemark(
|
||||
ctx context.Context,
|
||||
req *pbfriend.SetFriendRemarkReq,
|
||||
) (resp *pbfriend.SetFriendRemarkResp, err error) {
|
||||
func (s *friendServer) SetFriendRemark(ctx context.Context, req *pbfriend.SetFriendRemarkReq) (resp *pbfriend.SetFriendRemarkResp, err error) {
|
||||
defer log.ZInfo(ctx, utils.GetFuncName()+" Return")
|
||||
|
||||
if err = CallbackBeforeSetFriendRemark(ctx, req); err != nil && err != errs.ErrCallbackContinue {
|
||||
@@ -256,10 +261,7 @@ func (s *friendServer) SetFriendRemark(
|
||||
}
|
||||
|
||||
// ok.
|
||||
func (s *friendServer) GetDesignatedFriends(
|
||||
ctx context.Context,
|
||||
req *pbfriend.GetDesignatedFriendsReq,
|
||||
) (resp *pbfriend.GetDesignatedFriendsResp, err error) {
|
||||
func (s *friendServer) GetDesignatedFriends(ctx context.Context, req *pbfriend.GetDesignatedFriendsReq) (resp *pbfriend.GetDesignatedFriendsResp, err error) {
|
||||
defer log.ZInfo(ctx, utils.GetFuncName()+" Return")
|
||||
resp = &pbfriend.GetDesignatedFriendsResp{}
|
||||
if utils.Duplicate(req.FriendUserIDs) {
|
||||
@@ -290,15 +292,12 @@ func (s *friendServer) GetDesignatedFriendsApply(ctx context.Context,
|
||||
}
|
||||
|
||||
// ok 获取接收到的好友申请(即别人主动申请的).
|
||||
func (s *friendServer) GetPaginationFriendsApplyTo(
|
||||
ctx context.Context,
|
||||
req *pbfriend.GetPaginationFriendsApplyToReq,
|
||||
) (resp *pbfriend.GetPaginationFriendsApplyToResp, err error) {
|
||||
func (s *friendServer) GetPaginationFriendsApplyTo(ctx context.Context, req *pbfriend.GetPaginationFriendsApplyToReq) (resp *pbfriend.GetPaginationFriendsApplyToResp, err error) {
|
||||
defer log.ZInfo(ctx, utils.GetFuncName()+" Return")
|
||||
if err := s.userRpcClient.Access(ctx, req.UserID); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
friendRequests, total, err := s.friendDatabase.PageFriendRequestToMe(ctx, req.UserID, req.Pagination.PageNumber, req.Pagination.ShowNumber)
|
||||
total, friendRequests, err := s.friendDatabase.PageFriendRequestToMe(ctx, req.UserID, req.Pagination)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -312,16 +311,13 @@ func (s *friendServer) GetPaginationFriendsApplyTo(
|
||||
}
|
||||
|
||||
// ok 获取主动发出去的好友申请列表.
|
||||
func (s *friendServer) GetPaginationFriendsApplyFrom(
|
||||
ctx context.Context,
|
||||
req *pbfriend.GetPaginationFriendsApplyFromReq,
|
||||
) (resp *pbfriend.GetPaginationFriendsApplyFromResp, err error) {
|
||||
func (s *friendServer) GetPaginationFriendsApplyFrom(ctx context.Context, req *pbfriend.GetPaginationFriendsApplyFromReq) (resp *pbfriend.GetPaginationFriendsApplyFromResp, err error) {
|
||||
defer log.ZInfo(ctx, utils.GetFuncName()+" Return")
|
||||
resp = &pbfriend.GetPaginationFriendsApplyFromResp{}
|
||||
if err := s.userRpcClient.Access(ctx, req.UserID); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
friendRequests, total, err := s.friendDatabase.PageFriendRequestFromMe(ctx, req.UserID, req.Pagination.PageNumber, req.Pagination.ShowNumber)
|
||||
total, friendRequests, err := s.friendDatabase.PageFriendRequestFromMe(ctx, req.UserID, req.Pagination)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -334,10 +330,7 @@ func (s *friendServer) GetPaginationFriendsApplyFrom(
|
||||
}
|
||||
|
||||
// ok.
|
||||
func (s *friendServer) IsFriend(
|
||||
ctx context.Context,
|
||||
req *pbfriend.IsFriendReq,
|
||||
) (resp *pbfriend.IsFriendResp, err error) {
|
||||
func (s *friendServer) IsFriend(ctx context.Context, req *pbfriend.IsFriendReq) (resp *pbfriend.IsFriendResp, err error) {
|
||||
defer log.ZInfo(ctx, utils.GetFuncName()+" Return")
|
||||
resp = &pbfriend.IsFriendResp{}
|
||||
resp.InUser1Friends, resp.InUser2Friends, err = s.friendDatabase.CheckIn(ctx, req.UserID1, req.UserID2)
|
||||
@@ -347,15 +340,12 @@ func (s *friendServer) IsFriend(
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
func (s *friendServer) GetPaginationFriends(
|
||||
ctx context.Context,
|
||||
req *pbfriend.GetPaginationFriendsReq,
|
||||
) (resp *pbfriend.GetPaginationFriendsResp, err error) {
|
||||
func (s *friendServer) GetPaginationFriends(ctx context.Context, req *pbfriend.GetPaginationFriendsReq) (resp *pbfriend.GetPaginationFriendsResp, err error) {
|
||||
defer log.ZInfo(ctx, utils.GetFuncName()+" Return")
|
||||
if err := s.userRpcClient.Access(ctx, req.UserID); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
friends, total, err := s.friendDatabase.PageOwnerFriends(ctx, req.UserID, req.Pagination.PageNumber, req.Pagination.ShowNumber)
|
||||
total, friends, err := s.friendDatabase.PageOwnerFriends(ctx, req.UserID, req.Pagination)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -368,10 +358,7 @@ func (s *friendServer) GetPaginationFriends(
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
func (s *friendServer) GetFriendIDs(
|
||||
ctx context.Context,
|
||||
req *pbfriend.GetFriendIDsReq,
|
||||
) (resp *pbfriend.GetFriendIDsResp, err error) {
|
||||
func (s *friendServer) GetFriendIDs(ctx context.Context, req *pbfriend.GetFriendIDsReq) (resp *pbfriend.GetFriendIDsResp, err error) {
|
||||
defer log.ZInfo(ctx, utils.GetFuncName()+" Return")
|
||||
if err := s.userRpcClient.Access(ctx, req.UserID); err != nil {
|
||||
return nil, err
|
||||
|
||||
@@ -26,7 +26,7 @@ func (s *groupServer) GetGroupInfoCache(
|
||||
ctx context.Context,
|
||||
req *pbgroup.GetGroupInfoCacheReq,
|
||||
) (resp *pbgroup.GetGroupInfoCacheResp, err error) {
|
||||
group, err := s.GroupDatabase.TakeGroup(ctx, req.GroupID)
|
||||
group, err := s.db.TakeGroup(ctx, req.GroupID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -38,7 +38,7 @@ func (s *groupServer) GetGroupMemberCache(
|
||||
ctx context.Context,
|
||||
req *pbgroup.GetGroupMemberCacheReq,
|
||||
) (resp *pbgroup.GetGroupMemberCacheResp, err error) {
|
||||
members, err := s.GroupDatabase.TakeGroupMember(ctx, req.GroupID, req.GroupMemberID)
|
||||
members, err := s.db.TakeGroupMember(ctx, req.GroupID, req.GroupMemberID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -27,7 +27,7 @@ import (
|
||||
func UpdateGroupInfoMap(ctx context.Context, group *sdkws.GroupInfoForSet) map[string]any {
|
||||
m := make(map[string]any)
|
||||
if group.GroupName != "" {
|
||||
m["name"] = group.GroupName
|
||||
m["group_name"] = group.GroupName
|
||||
}
|
||||
if group.Notification != "" {
|
||||
m["notification"] = group.Notification
|
||||
|
||||
+2
-112
@@ -17,119 +17,9 @@ package group
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/OpenIMSDK/tools/utils"
|
||||
|
||||
relationtb "github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation"
|
||||
)
|
||||
|
||||
func (s *groupServer) FindGroupMember(ctx context.Context, groupIDs []string, userIDs []string, roleLevels []int32) ([]*relationtb.GroupMemberModel, error) {
|
||||
members, err := s.GroupDatabase.FindGroupMember(ctx, groupIDs, userIDs, roleLevels)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
emptyUserIDs := make(map[string]struct{})
|
||||
for _, member := range members {
|
||||
if member.Nickname == "" || member.FaceURL == "" {
|
||||
emptyUserIDs[member.UserID] = struct{}{}
|
||||
}
|
||||
}
|
||||
if len(emptyUserIDs) > 0 {
|
||||
users, err := s.User.GetPublicUserInfoMap(ctx, utils.Keys(emptyUserIDs), true)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for i, member := range members {
|
||||
user, ok := users[member.UserID]
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
if member.Nickname == "" {
|
||||
members[i].Nickname = user.Nickname
|
||||
}
|
||||
if member.FaceURL == "" {
|
||||
members[i].FaceURL = user.FaceURL
|
||||
}
|
||||
}
|
||||
}
|
||||
return members, nil
|
||||
}
|
||||
|
||||
func (s *groupServer) TakeGroupMember(
|
||||
ctx context.Context,
|
||||
groupID string,
|
||||
userID string,
|
||||
) (*relationtb.GroupMemberModel, error) {
|
||||
member, err := s.GroupDatabase.TakeGroupMember(ctx, groupID, userID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if member.Nickname == "" || member.FaceURL == "" {
|
||||
user, err := s.User.GetPublicUserInfo(ctx, userID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if member.Nickname == "" {
|
||||
member.Nickname = user.Nickname
|
||||
}
|
||||
if member.FaceURL == "" {
|
||||
member.FaceURL = user.FaceURL
|
||||
}
|
||||
}
|
||||
return member, nil
|
||||
}
|
||||
|
||||
func (s *groupServer) TakeGroupOwner(ctx context.Context, groupID string) (*relationtb.GroupMemberModel, error) {
|
||||
owner, err := s.GroupDatabase.TakeGroupOwner(ctx, groupID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if owner.Nickname == "" || owner.FaceURL == "" {
|
||||
user, err := s.User.GetUserInfo(ctx, owner.UserID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if owner.Nickname == "" {
|
||||
owner.Nickname = user.Nickname
|
||||
}
|
||||
if owner.FaceURL == "" {
|
||||
owner.FaceURL = user.FaceURL
|
||||
}
|
||||
}
|
||||
return owner, nil
|
||||
}
|
||||
|
||||
func (s *groupServer) PageGetGroupMember(
|
||||
ctx context.Context,
|
||||
groupID string,
|
||||
pageNumber, showNumber int32,
|
||||
) (uint32, []*relationtb.GroupMemberModel, error) {
|
||||
total, members, err := s.GroupDatabase.PageGetGroupMember(ctx, groupID, pageNumber, showNumber)
|
||||
if err != nil {
|
||||
return 0, nil, err
|
||||
}
|
||||
emptyUserIDs := make(map[string]struct{})
|
||||
for _, member := range members {
|
||||
if member.Nickname == "" || member.FaceURL == "" {
|
||||
emptyUserIDs[member.UserID] = struct{}{}
|
||||
}
|
||||
}
|
||||
if len(emptyUserIDs) > 0 {
|
||||
users, err := s.User.GetPublicUserInfoMap(ctx, utils.Keys(emptyUserIDs), true)
|
||||
if err != nil {
|
||||
return 0, nil, err
|
||||
}
|
||||
for i, member := range members {
|
||||
user, ok := users[member.UserID]
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
if member.Nickname == "" {
|
||||
members[i].Nickname = user.Nickname
|
||||
}
|
||||
if member.FaceURL == "" {
|
||||
members[i].FaceURL = user.FaceURL
|
||||
}
|
||||
}
|
||||
}
|
||||
return total, members, nil
|
||||
func (s *groupServer) PopulateGroupMember(ctx context.Context, members ...*relationtb.GroupMemberModel) error {
|
||||
return s.Notification.PopulateGroupMember(ctx, members...)
|
||||
}
|
||||
|
||||
+391
-539
File diff suppressed because it is too large
Load Diff
@@ -26,16 +26,16 @@ func (s *groupServer) GroupCreateCount(ctx context.Context, req *group.GroupCrea
|
||||
if req.Start > req.End {
|
||||
return nil, errs.ErrArgs.Wrap("start > end")
|
||||
}
|
||||
total, err := s.GroupDatabase.CountTotal(ctx, nil)
|
||||
total, err := s.db.CountTotal(ctx, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
start := time.UnixMilli(req.Start)
|
||||
before, err := s.GroupDatabase.CountTotal(ctx, &start)
|
||||
before, err := s.db.CountTotal(ctx, &start)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
count, err := s.GroupDatabase.CountRangeEverydayTotal(ctx, start, time.UnixMilli(req.End))
|
||||
count, err := s.db.CountRangeEverydayTotal(ctx, start, time.UnixMilli(req.End))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -16,99 +16,15 @@ package group
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strings"
|
||||
"errors"
|
||||
|
||||
"github.com/OpenIMSDK/protocol/constant"
|
||||
pbgroup "github.com/OpenIMSDK/protocol/group"
|
||||
sdkws "github.com/OpenIMSDK/protocol/sdkws"
|
||||
"github.com/OpenIMSDK/tools/errs"
|
||||
"github.com/OpenIMSDK/tools/utils"
|
||||
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/common/convert"
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation"
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/common/db/table/unrelation"
|
||||
)
|
||||
|
||||
func (s *groupServer) GetJoinedSuperGroupList(
|
||||
ctx context.Context,
|
||||
req *pbgroup.GetJoinedSuperGroupListReq,
|
||||
) (*pbgroup.GetJoinedSuperGroupListResp, error) {
|
||||
resp := &pbgroup.GetJoinedSuperGroupListResp{}
|
||||
groupIDs, err := s.GroupDatabase.FindJoinSuperGroup(ctx, req.UserID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(groupIDs) == 0 {
|
||||
return resp, nil
|
||||
}
|
||||
owners, err := s.FindGroupMember(ctx, groupIDs, nil, []int32{constant.GroupOwner})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ownerMap := utils.SliceToMap(owners, func(e *relation.GroupMemberModel) string {
|
||||
return e.GroupID
|
||||
})
|
||||
if ids := utils.Single(groupIDs, utils.Keys(ownerMap)); len(ids) > 0 {
|
||||
return nil, errs.ErrData.Wrap(fmt.Sprintf("super group %s not owner", strings.Join(ids, ",")))
|
||||
}
|
||||
groups, err := s.GroupDatabase.FindGroup(ctx, groupIDs)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
groupMap := utils.SliceToMap(groups, func(e *relation.GroupModel) string {
|
||||
return e.GroupID
|
||||
})
|
||||
if ids := utils.Single(groupIDs, utils.Keys(groupMap)); len(ids) > 0 {
|
||||
return nil, errs.ErrData.Wrap(fmt.Sprintf("super group info %s not found", strings.Join(ids, ",")))
|
||||
}
|
||||
superGroupMembers, err := s.GroupDatabase.FindSuperGroup(ctx, groupIDs)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
superGroupMemberMap := utils.SliceToMapAny(
|
||||
superGroupMembers,
|
||||
func(e *unrelation.SuperGroupModel) (string, []string) {
|
||||
return e.GroupID, e.MemberIDs
|
||||
},
|
||||
)
|
||||
resp.Groups = utils.Slice(groupIDs, func(groupID string) *sdkws.GroupInfo {
|
||||
return convert.Db2PbGroupInfo(groupMap[groupID], ownerMap[groupID].UserID, uint32(len(superGroupMemberMap)))
|
||||
})
|
||||
return resp, nil
|
||||
func (s *groupServer) GetJoinedSuperGroupList(context.Context, *pbgroup.GetJoinedSuperGroupListReq) (*pbgroup.GetJoinedSuperGroupListResp, error) {
|
||||
return nil, errors.New("deprecated")
|
||||
}
|
||||
|
||||
func (s *groupServer) GetSuperGroupsInfo(
|
||||
ctx context.Context,
|
||||
req *pbgroup.GetSuperGroupsInfoReq,
|
||||
) (resp *pbgroup.GetSuperGroupsInfoResp, err error) {
|
||||
resp = &pbgroup.GetSuperGroupsInfoResp{}
|
||||
if len(req.GroupIDs) == 0 {
|
||||
return nil, errs.ErrArgs.Wrap("groupIDs empty")
|
||||
}
|
||||
groups, err := s.GroupDatabase.FindGroup(ctx, req.GroupIDs)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
superGroupMembers, err := s.GroupDatabase.FindSuperGroup(ctx, req.GroupIDs)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
superGroupMemberMap := utils.SliceToMapAny(
|
||||
superGroupMembers,
|
||||
func(e *unrelation.SuperGroupModel) (string, []string) {
|
||||
return e.GroupID, e.MemberIDs
|
||||
},
|
||||
)
|
||||
owners, err := s.FindGroupMember(ctx, req.GroupIDs, nil, []int32{constant.GroupOwner})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ownerMap := utils.SliceToMap(owners, func(e *relation.GroupMemberModel) string {
|
||||
return e.GroupID
|
||||
})
|
||||
resp.GroupInfos = utils.Slice(groups, func(e *relation.GroupModel) *sdkws.GroupInfo {
|
||||
return convert.Db2PbGroupInfo(e, ownerMap[e.GroupID].UserID, uint32(len(superGroupMemberMap[e.GroupID])))
|
||||
})
|
||||
return resp, nil
|
||||
func (s *groupServer) GetSuperGroupsInfo(context.Context, *pbgroup.GetSuperGroupsInfoReq) (resp *pbgroup.GetSuperGroupsInfoResp, err error) {
|
||||
return nil, errors.New("deprecated")
|
||||
}
|
||||
|
||||
+55
-41
@@ -16,14 +16,12 @@ package msg
|
||||
|
||||
import (
|
||||
"context"
|
||||
cbapi "github.com/openimsdk/open-im-server/v3/pkg/callbackstruct"
|
||||
|
||||
utils2 "github.com/OpenIMSDK/tools/utils"
|
||||
|
||||
"github.com/redis/go-redis/v9"
|
||||
|
||||
cbapi "github.com/openimsdk/open-im-server/v3/pkg/callbackstruct"
|
||||
"github.com/OpenIMSDK/protocol/constant"
|
||||
"github.com/OpenIMSDK/protocol/conversation"
|
||||
"github.com/OpenIMSDK/protocol/msg"
|
||||
"github.com/OpenIMSDK/protocol/sdkws"
|
||||
"github.com/OpenIMSDK/tools/errs"
|
||||
@@ -92,7 +90,10 @@ func (m *msgServer) SetConversationHasReadSeq(
|
||||
return &msg.SetConversationHasReadSeqResp{}, nil
|
||||
}
|
||||
|
||||
func (m *msgServer) MarkMsgsAsRead(ctx context.Context, req *msg.MarkMsgsAsReadReq) (resp *msg.MarkMsgsAsReadResp, err error) {
|
||||
func (m *msgServer) MarkMsgsAsRead(
|
||||
ctx context.Context,
|
||||
req *msg.MarkMsgsAsReadReq,
|
||||
) (resp *msg.MarkMsgsAsReadResp, err error) {
|
||||
if len(req.Seqs) < 1 {
|
||||
return nil, errs.ErrArgs.Wrap("seqs must not be empty")
|
||||
}
|
||||
@@ -111,6 +112,7 @@ func (m *msgServer) MarkMsgsAsRead(ctx context.Context, req *msg.MarkMsgsAsReadR
|
||||
if err = m.MsgDatabase.MarkSingleChatMsgsAsRead(ctx, req.UserID, req.ConversationID, req.Seqs); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
currentHasReadSeq, err := m.MsgDatabase.GetHasReadSeq(ctx, req.UserID, req.ConversationID)
|
||||
if err != nil && errs.Unwrap(err) != redis.Nil {
|
||||
return
|
||||
@@ -128,7 +130,10 @@ func (m *msgServer) MarkMsgsAsRead(ctx context.Context, req *msg.MarkMsgsAsReadR
|
||||
return &msg.MarkMsgsAsReadResp{}, nil
|
||||
}
|
||||
|
||||
func (m *msgServer) MarkConversationAsRead(ctx context.Context, req *msg.MarkConversationAsReadReq) (resp *msg.MarkConversationAsReadResp, err error) {
|
||||
func (m *msgServer) MarkConversationAsRead(
|
||||
ctx context.Context,
|
||||
req *msg.MarkConversationAsReadReq,
|
||||
) (resp *msg.MarkConversationAsReadResp, err error) {
|
||||
conversation, err := m.Conversation.GetConversation(ctx, req.UserID, req.ConversationID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -137,34 +142,54 @@ func (m *msgServer) MarkConversationAsRead(ctx context.Context, req *msg.MarkCon
|
||||
if err != nil && errs.Unwrap(err) != redis.Nil {
|
||||
return nil, err
|
||||
}
|
||||
seqs := generateSeqs(hasReadSeq, req)
|
||||
var seqs []int64
|
||||
|
||||
if len(seqs) > 0 || req.HasReadSeq > hasReadSeq {
|
||||
err = m.updateReadStatus(ctx, req, conversation, seqs, hasReadSeq)
|
||||
if err != nil {
|
||||
log.ZDebug(ctx, "MarkConversationAsRead", "hasReadSeq", hasReadSeq,
|
||||
"req.HasReadSeq", req.HasReadSeq)
|
||||
if conversation.ConversationType == constant.SingleChatType {
|
||||
for i := hasReadSeq + 1; i <= req.HasReadSeq; i++ {
|
||||
seqs = append(seqs, i)
|
||||
}
|
||||
//avoid client missed call MarkConversationMessageAsRead by order
|
||||
for _, val := range req.Seqs {
|
||||
if !utils2.Contain(val, seqs...) {
|
||||
seqs = append(seqs, val)
|
||||
}
|
||||
}
|
||||
if len(seqs) > 0 {
|
||||
log.ZDebug(ctx, "MarkConversationAsRead", "seqs", seqs, "conversationID", req.ConversationID)
|
||||
if err = m.MsgDatabase.MarkSingleChatMsgsAsRead(ctx, req.UserID, req.ConversationID, seqs); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
if req.HasReadSeq > hasReadSeq {
|
||||
err = m.MsgDatabase.SetHasReadSeq(ctx, req.UserID, req.ConversationID, req.HasReadSeq)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
hasReadSeq = req.HasReadSeq
|
||||
}
|
||||
if err = m.sendMarkAsReadNotification(ctx, req.ConversationID, conversation.ConversationType, req.UserID,
|
||||
m.conversationAndGetRecvID(conversation, req.UserID), seqs, hasReadSeq); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return &msg.MarkConversationAsReadResp{}, nil
|
||||
}
|
||||
|
||||
func generateSeqs(hasReadSeq int64, req *msg.MarkConversationAsReadReq) []int64 {
|
||||
var seqs []int64
|
||||
for _, val := range req.Seqs {
|
||||
if val > hasReadSeq && !utils2.Contain(val, seqs...) {
|
||||
seqs = append(seqs, val)
|
||||
|
||||
} else if conversation.ConversationType == constant.SuperGroupChatType ||
|
||||
conversation.ConversationType == constant.NotificationChatType {
|
||||
if req.HasReadSeq > hasReadSeq {
|
||||
err = m.MsgDatabase.SetHasReadSeq(ctx, req.UserID, req.ConversationID, req.HasReadSeq)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
hasReadSeq = req.HasReadSeq
|
||||
}
|
||||
}
|
||||
return seqs
|
||||
}
|
||||
|
||||
func (m *msgServer) updateReadStatus(ctx context.Context, req *msg.MarkConversationAsReadReq, conversation *conversation.Conversation, seqs []int64, hasReadSeq int64) error {
|
||||
if conversation.ConversationType == constant.SingleChatType && len(seqs) > 0 {
|
||||
log.ZDebug(ctx, "MarkConversationAsRead", "seqs", seqs, "conversationID", req.ConversationID)
|
||||
if err := m.MsgDatabase.MarkSingleChatMsgsAsRead(ctx, req.UserID, req.ConversationID, seqs); err != nil {
|
||||
return err
|
||||
if err = m.sendMarkAsReadNotification(ctx, req.ConversationID, constant.SingleChatType, req.UserID,
|
||||
req.UserID, seqs, hasReadSeq); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
reqCall := &cbapi.CallbackGroupMsgReadReq{
|
||||
SendID: conversation.OwnerUserID,
|
||||
ReceiveID: req.UserID,
|
||||
@@ -172,21 +197,10 @@ func (m *msgServer) updateReadStatus(ctx context.Context, req *msg.MarkConversat
|
||||
ContentType: int64(conversation.ConversationType),
|
||||
}
|
||||
if err := CallbackGroupMsgRead(ctx, reqCall); err != nil {
|
||||
return err
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if req.HasReadSeq > hasReadSeq {
|
||||
if err := m.MsgDatabase.SetHasReadSeq(ctx, req.UserID, req.ConversationID, req.HasReadSeq); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
recvID := m.conversationAndGetRecvID(conversation, req.UserID)
|
||||
if conversation.ConversationType == constant.SuperGroupChatType || conversation.ConversationType == constant.NotificationChatType {
|
||||
recvID = req.UserID
|
||||
}
|
||||
|
||||
return m.sendMarkAsReadNotification(ctx, req.ConversationID, conversation.ConversationType, req.UserID, recvID, seqs, req.HasReadSeq)
|
||||
return &msg.MarkConversationAsReadResp{}, nil
|
||||
}
|
||||
|
||||
func (m *msgServer) sendMarkAsReadNotification(
|
||||
@@ -208,4 +222,4 @@ func (m *msgServer) sendMarkAsReadNotification(
|
||||
log.ZWarn(ctx, "send has read Receipt err", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
}
|
||||
@@ -15,12 +15,11 @@
|
||||
package msg
|
||||
|
||||
import (
|
||||
"github.com/redis/go-redis/v9"
|
||||
"gorm.io/gorm"
|
||||
|
||||
"github.com/OpenIMSDK/protocol/constant"
|
||||
"github.com/OpenIMSDK/protocol/sdkws"
|
||||
"github.com/OpenIMSDK/tools/utils"
|
||||
"github.com/redis/go-redis/v9"
|
||||
"go.mongodb.org/mongo-driver/mongo"
|
||||
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
|
||||
)
|
||||
@@ -45,7 +44,7 @@ func isMessageHasReadEnabled(msgData *sdkws.MsgData) bool {
|
||||
|
||||
func IsNotFound(err error) bool {
|
||||
switch utils.Unwrap(err) {
|
||||
case redis.Nil, gorm.ErrRecordNotFound:
|
||||
case redis.Nil, mongo.ErrNoDocuments:
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
|
||||
+11
-13
@@ -32,11 +32,11 @@ func genLogID() string {
|
||||
}
|
||||
|
||||
func (t *thirdServer) UploadLogs(ctx context.Context, req *third.UploadLogsReq) (*third.UploadLogsResp, error) {
|
||||
var DBlogs []*relationtb.Log
|
||||
var DBlogs []*relationtb.LogModel
|
||||
userID := ctx.Value(constant.OpUserID).(string)
|
||||
platform := constant.PlatformID2Name[int(req.Platform)]
|
||||
for _, fileURL := range req.FileURLs {
|
||||
log := relationtb.Log{
|
||||
log := relationtb.LogModel{
|
||||
Version: req.Version,
|
||||
SystemType: req.SystemType,
|
||||
Platform: platform,
|
||||
@@ -57,7 +57,7 @@ func (t *thirdServer) UploadLogs(ctx context.Context, req *third.UploadLogsReq)
|
||||
}
|
||||
}
|
||||
if log.LogID == "" {
|
||||
return nil, errs.ErrData.Wrap("Log id gen error")
|
||||
return nil, errs.ErrData.Wrap("LogModel id gen error")
|
||||
}
|
||||
DBlogs = append(DBlogs, &log)
|
||||
}
|
||||
@@ -92,8 +92,8 @@ func (t *thirdServer) DeleteLogs(ctx context.Context, req *third.DeleteLogsReq)
|
||||
return &third.DeleteLogsResp{}, nil
|
||||
}
|
||||
|
||||
func dbToPbLogInfos(logs []*relationtb.Log) []*third.LogInfo {
|
||||
db2pbForLogInfo := func(log *relationtb.Log) *third.LogInfo {
|
||||
func dbToPbLogInfos(logs []*relationtb.LogModel) []*third.LogInfo {
|
||||
db2pbForLogInfo := func(log *relationtb.LogModel) *third.LogInfo {
|
||||
return &third.LogInfo{
|
||||
Filename: log.FileName,
|
||||
UserID: log.UserID,
|
||||
@@ -120,7 +120,7 @@ func (t *thirdServer) SearchLogs(ctx context.Context, req *third.SearchLogsReq)
|
||||
if req.StartTime > req.EndTime {
|
||||
return nil, errs.ErrArgs.Wrap("startTime>endTime")
|
||||
}
|
||||
total, logs, err := t.thirdDatabase.SearchLogs(ctx, req.Keyword, time.UnixMilli(req.StartTime), time.UnixMilli(req.EndTime), req.Pagination.PageNumber, req.Pagination.ShowNumber)
|
||||
total, logs, err := t.thirdDatabase.SearchLogs(ctx, req.Keyword, time.UnixMilli(req.StartTime), time.UnixMilli(req.EndTime), req.Pagination)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -128,18 +128,16 @@ func (t *thirdServer) SearchLogs(ctx context.Context, req *third.SearchLogsReq)
|
||||
for _, log := range logs {
|
||||
userIDs = append(userIDs, log.UserID)
|
||||
}
|
||||
users, err := t.thirdDatabase.FindUsers(ctx, userIDs)
|
||||
userMap, err := t.userRpcClient.GetUsersInfoMap(ctx, userIDs)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
IDtoName := make(map[string]string)
|
||||
for _, user := range users {
|
||||
IDtoName[user.UserID] = user.Nickname
|
||||
}
|
||||
for _, pbLog := range pbLogs {
|
||||
pbLog.Nickname = IDtoName[pbLog.UserID]
|
||||
if user, ok := userMap[pbLog.UserID]; ok {
|
||||
pbLog.Nickname = user.Nickname
|
||||
}
|
||||
}
|
||||
resp.LogsInfos = pbLogs
|
||||
resp.Total = total
|
||||
resp.Total = uint32(total)
|
||||
return &resp, nil
|
||||
}
|
||||
|
||||
@@ -64,7 +64,7 @@ func (t *thirdServer) InitiateMultipartUpload(ctx context.Context, req *third.In
|
||||
Key: haErr.Object.Key,
|
||||
Size: haErr.Object.Size,
|
||||
ContentType: req.ContentType,
|
||||
Cause: req.Cause,
|
||||
Group: req.Cause,
|
||||
CreateTime: time.Now(),
|
||||
}
|
||||
if err := t.s3dataBase.SetObject(ctx, obj); err != nil {
|
||||
@@ -143,7 +143,7 @@ func (t *thirdServer) CompleteMultipartUpload(ctx context.Context, req *third.Co
|
||||
Key: result.Key,
|
||||
Size: result.Size,
|
||||
ContentType: req.ContentType,
|
||||
Cause: req.Cause,
|
||||
Group: req.Cause,
|
||||
CreateTime: time.Now(),
|
||||
}
|
||||
if err := t.s3dataBase.SetObject(ctx, obj); err != nil {
|
||||
|
||||
+18
-22
@@ -17,15 +17,17 @@ package third
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"net/url"
|
||||
"time"
|
||||
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/common/db/mgo"
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/common/db/unrelation"
|
||||
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/common/db/s3"
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/common/db/s3/cos"
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/common/db/s3/kodo"
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/common/db/s3/minio"
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/common/db/s3/oss"
|
||||
|
||||
"google.golang.org/grpc"
|
||||
|
||||
"github.com/OpenIMSDK/protocol/third"
|
||||
@@ -34,13 +36,22 @@ import (
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/common/db/cache"
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/common/db/controller"
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/common/db/relation"
|
||||
relationtb "github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation"
|
||||
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/rpcclient"
|
||||
)
|
||||
|
||||
func Start(client discoveryregistry.SvcDiscoveryRegistry, server *grpc.Server) error {
|
||||
mongo, err := unrelation.NewMongo()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
logdb, err := mgo.NewLogMongo(mongo.GetDatabase())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
s3db, err := mgo.NewS3Mongo(mongo.GetDatabase())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
apiURL := config.Config.Object.ApiURL
|
||||
if apiURL == "" {
|
||||
return fmt.Errorf("api url is empty")
|
||||
@@ -56,13 +67,6 @@ func Start(client discoveryregistry.SvcDiscoveryRegistry, server *grpc.Server) e
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
db, err := relation.NewGormDB()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err := db.AutoMigrate(&relationtb.ObjectModel{}); err != nil {
|
||||
return err
|
||||
}
|
||||
// 根据配置文件策略选择 oss 方式
|
||||
enable := config.Config.Object.Enable
|
||||
var o s3.Interface
|
||||
@@ -73,25 +77,17 @@ func Start(client discoveryregistry.SvcDiscoveryRegistry, server *grpc.Server) e
|
||||
o, err = cos.NewCos()
|
||||
case "oss":
|
||||
o, err = oss.NewOSS()
|
||||
case "kodo":
|
||||
o, err = kodo.NewKodo()
|
||||
default:
|
||||
err = fmt.Errorf("invalid object enable: %s", enable)
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
//specialerror.AddErrHandler(func(err error) errs.CodeError {
|
||||
// if o.IsNotFound(err) {
|
||||
// return errs.ErrRecordNotFound
|
||||
// }
|
||||
// return nil
|
||||
//})
|
||||
third.RegisterThirdServer(server, &thirdServer{
|
||||
apiURL: apiURL,
|
||||
thirdDatabase: controller.NewThirdDatabase(cache.NewMsgCacheModel(rdb), db),
|
||||
thirdDatabase: controller.NewThirdDatabase(cache.NewMsgCacheModel(rdb), logdb),
|
||||
userRpcClient: rpcclient.NewUserRpcClient(client),
|
||||
s3dataBase: controller.NewS3Database(rdb, o, relation.NewObjectInfo(db)),
|
||||
s3dataBase: controller.NewS3Database(rdb, o, s3db),
|
||||
defaultExpire: time.Hour * 24 * 7,
|
||||
})
|
||||
return nil
|
||||
|
||||
+16
-27
@@ -20,11 +20,14 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/OpenIMSDK/tools/tx"
|
||||
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/common/db/mgo"
|
||||
|
||||
"github.com/OpenIMSDK/protocol/constant"
|
||||
"github.com/OpenIMSDK/protocol/sdkws"
|
||||
"github.com/OpenIMSDK/tools/errs"
|
||||
"github.com/OpenIMSDK/tools/log"
|
||||
"github.com/OpenIMSDK/tools/tx"
|
||||
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/authverify"
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/common/db/unrelation"
|
||||
@@ -35,7 +38,6 @@ import (
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/common/convert"
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/common/db/cache"
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/common/db/controller"
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/common/db/relation"
|
||||
tablerelation "github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation"
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/rpcclient"
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/rpcclient/notification"
|
||||
@@ -55,10 +57,6 @@ type userServer struct {
|
||||
}
|
||||
|
||||
func Start(client registry.SvcDiscoveryRegistry, server *grpc.Server) error {
|
||||
db, err := relation.NewGormDB()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
rdb, err := cache.NewRedis()
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -67,9 +65,6 @@ func Start(client registry.SvcDiscoveryRegistry, server *grpc.Server) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err := db.AutoMigrate(&tablerelation.UserModel{}); err != nil {
|
||||
return err
|
||||
}
|
||||
users := make([]*tablerelation.UserModel, 0)
|
||||
if len(config.Config.Manager.UserID) != len(config.Config.Manager.Nickname) {
|
||||
return errors.New("len(config.Config.Manager.AppManagerUid) != len(config.Config.Manager.Nickname)")
|
||||
@@ -77,10 +72,13 @@ func Start(client registry.SvcDiscoveryRegistry, server *grpc.Server) error {
|
||||
for k, v := range config.Config.Manager.UserID {
|
||||
users = append(users, &tablerelation.UserModel{UserID: v, Nickname: config.Config.Manager.Nickname[k], AppMangerLevel: constant.AppAdmin})
|
||||
}
|
||||
userDB := relation.NewUserGorm(db)
|
||||
userDB, err := mgo.NewUserMongo(mongo.GetDatabase())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
cache := cache.NewUserCacheRedis(rdb, userDB, cache.GetDefaultOpt())
|
||||
userMongoDB := unrelation.NewUserMongoDriver(mongo.GetDatabase())
|
||||
database := controller.NewUserDatabase(userDB, cache, tx.NewGorm(db), userMongoDB)
|
||||
database := controller.NewUserDatabase(userDB, cache, tx.NewMongo(mongo.GetClient()), userMongoDB)
|
||||
friendRpcClient := rpcclient.NewFriendRpcClient(client)
|
||||
groupRpcClient := rpcclient.NewGroupRpcClient(client)
|
||||
msgRpcClient := rpcclient.NewMessageRpcClient(client)
|
||||
@@ -118,12 +116,8 @@ func (s *userServer) UpdateUserInfo(ctx context.Context, req *pbuser.UpdateUserI
|
||||
if err := CallbackBeforeUpdateUserInfo(ctx, req); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
user := convert.UserPb2DB(req.UserInfo)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
err = s.Update(ctx, user)
|
||||
if err != nil {
|
||||
data := convert.UserPb2DBMap(req.UserInfo)
|
||||
if err := s.UpdateByMap(ctx, req.UserInfo.UserID, data); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
_ = s.friendNotificationSender.UserInfoUpdatedNotification(ctx, req.UserInfo.UserID)
|
||||
@@ -153,7 +147,7 @@ func (s *userServer) SetGlobalRecvMessageOpt(ctx context.Context, req *pbuser.Se
|
||||
if _, err := s.FindWithError(ctx, []string{req.UserID}); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
m := make(map[string]interface{}, 1)
|
||||
m := make(map[string]any, 1)
|
||||
m["global_recv_msg_opt"] = req.GlobalRecvMsgOpt
|
||||
if err := s.UpdateByMap(ctx, req.UserID, m); err != nil {
|
||||
return nil, err
|
||||
@@ -175,7 +169,7 @@ func (s *userServer) AccountCheck(ctx context.Context, req *pbuser.AccountCheckR
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
userIDs := make(map[string]interface{}, 0)
|
||||
userIDs := make(map[string]any, 0)
|
||||
for _, v := range users {
|
||||
userIDs[v.UserID] = nil
|
||||
}
|
||||
@@ -192,12 +186,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) {
|
||||
var pageNumber, showNumber int32
|
||||
if req.Pagination != nil {
|
||||
pageNumber = req.Pagination.PageNumber
|
||||
showNumber = req.Pagination.ShowNumber
|
||||
}
|
||||
users, total, err := s.Page(ctx, pageNumber, showNumber)
|
||||
total, users, err := s.Page(ctx, req.Pagination)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -269,11 +258,11 @@ func (s *userServer) GetGlobalRecvMessageOpt(ctx context.Context, req *pbuser.Ge
|
||||
|
||||
// GetAllUserID Get user account by page.
|
||||
func (s *userServer) GetAllUserID(ctx context.Context, req *pbuser.GetAllUserIDReq) (resp *pbuser.GetAllUserIDResp, err error) {
|
||||
userIDs, err := s.UserDatabase.GetAllUserID(ctx, req.Pagination.PageNumber, req.Pagination.ShowNumber)
|
||||
total, userIDs, err := s.UserDatabase.GetAllUserID(ctx, req.Pagination)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &pbuser.GetAllUserIDResp{UserIDs: userIDs}, nil
|
||||
return &pbuser.GetAllUserIDResp{Total: int32(total), UserIDs: userIDs}, nil
|
||||
}
|
||||
|
||||
// SubscribeOrCancelUsersStatus Subscribe online or cancel online users.
|
||||
|
||||
@@ -19,6 +19,8 @@ import (
|
||||
"math/rand"
|
||||
"time"
|
||||
|
||||
"github.com/OpenIMSDK/protocol/sdkws"
|
||||
|
||||
"github.com/OpenIMSDK/tools/log"
|
||||
"github.com/OpenIMSDK/tools/mcontext"
|
||||
"github.com/OpenIMSDK/tools/utils"
|
||||
@@ -91,7 +93,11 @@ func (c *MsgTool) ConversationsDestructMsgs() {
|
||||
}
|
||||
for i := 0; i < count; i++ {
|
||||
pageNumber := rand.Int63() % maxPage
|
||||
conversationIDs, err := c.conversationDatabase.PageConversationIDs(ctx, int32(pageNumber), batchNum)
|
||||
pagination := &sdkws.RequestPagination{
|
||||
PageNumber: int32(pageNumber),
|
||||
ShowNumber: batchNum,
|
||||
}
|
||||
conversationIDs, err := c.conversationDatabase.PageConversationIDs(ctx, pagination)
|
||||
if err != nil {
|
||||
log.ZError(ctx, "PageConversationIDs failed", err, "pageNumber", pageNumber)
|
||||
continue
|
||||
@@ -133,7 +139,7 @@ func (c *MsgTool) ConversationsDestructMsgs() {
|
||||
continue
|
||||
}
|
||||
if len(seqs) > 0 {
|
||||
if err := c.conversationDatabase.UpdateUsersConversationFiled(ctx, []string{conversation.OwnerUserID}, conversation.ConversationID, map[string]interface{}{"latest_msg_destruct_time": now}); err != nil {
|
||||
if err := c.conversationDatabase.UpdateUsersConversationFiled(ctx, []string{conversation.OwnerUserID}, conversation.ConversationID, map[string]any{"latest_msg_destruct_time": now}); err != nil {
|
||||
log.ZError(ctx, "updateUsersConversationFiled failed", err, "conversationID", conversation.ConversationID, "ownerUserID", conversation.OwnerUserID)
|
||||
continue
|
||||
}
|
||||
|
||||
+37
-18
@@ -19,6 +19,11 @@ import (
|
||||
"fmt"
|
||||
"math"
|
||||
|
||||
"github.com/OpenIMSDK/protocol/sdkws"
|
||||
"github.com/OpenIMSDK/tools/tx"
|
||||
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/common/db/mgo"
|
||||
|
||||
"github.com/redis/go-redis/v9"
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/credentials/insecure"
|
||||
@@ -31,13 +36,11 @@ import (
|
||||
"github.com/OpenIMSDK/tools/log"
|
||||
"github.com/OpenIMSDK/tools/mcontext"
|
||||
"github.com/OpenIMSDK/tools/mw"
|
||||
"github.com/OpenIMSDK/tools/tx"
|
||||
"github.com/OpenIMSDK/tools/utils"
|
||||
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/common/db/cache"
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/common/db/controller"
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/common/db/relation"
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/common/db/unrelation"
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/rpcclient"
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/rpcclient/notification"
|
||||
@@ -72,33 +75,45 @@ func InitMsgTool() (*MsgTool, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
db, err := relation.NewGormDB()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
discov, err := kdisc.NewDiscoveryRegister(config.Config.Envs.Discovery)
|
||||
/*
|
||||
discov, err := zookeeper.NewClient(config.Config.Zookeeper.ZkAddr, config.Config.Zookeeper.Schema,
|
||||
zookeeper.WithFreq(time.Hour), zookeeper.WithRoundRobin(), zookeeper.WithUserNameAndPassword(config.Config.Zookeeper.Username,
|
||||
config.Config.Zookeeper.Password), zookeeper.WithTimeout(10), zookeeper.WithLogger(log.NewZkLogger()))*/
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
discov.AddOption(mw.GrpcClient(), grpc.WithTransportCredentials(insecure.NewCredentials()))
|
||||
userDB := relation.NewUserGorm(db)
|
||||
userDB, err := mgo.NewUserMongo(mongo.GetDatabase())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
msgDatabase := controller.InitCommonMsgDatabase(rdb, mongo.GetDatabase())
|
||||
userMongoDB := unrelation.NewUserMongoDriver(mongo.GetDatabase())
|
||||
ctxTx := tx.NewMongo(mongo.GetClient())
|
||||
userDatabase := controller.NewUserDatabase(
|
||||
userDB,
|
||||
cache.NewUserCacheRedis(rdb, relation.NewUserGorm(db), cache.GetDefaultOpt()),
|
||||
tx.NewGorm(db),
|
||||
cache.NewUserCacheRedis(rdb, userDB, cache.GetDefaultOpt()),
|
||||
ctxTx,
|
||||
userMongoDB,
|
||||
)
|
||||
groupDatabase := controller.InitGroupDatabase(db, rdb, mongo.GetDatabase(), nil)
|
||||
groupDB, err := mgo.NewGroupMongo(mongo.GetDatabase())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
groupMemberDB, err := mgo.NewGroupMember(mongo.GetDatabase())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
groupRequestDB, err := mgo.NewGroupRequestMgo(mongo.GetDatabase())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
conversationDB, err := mgo.NewConversationMongo(mongo.GetDatabase())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
groupDatabase := controller.NewGroupDatabase(rdb, groupDB, groupMemberDB, groupRequestDB, ctxTx, nil)
|
||||
conversationDatabase := controller.NewConversationDatabase(
|
||||
relation.NewConversationGorm(db),
|
||||
cache.NewConversationRedis(rdb, cache.GetDefaultOpt(), relation.NewConversationGorm(db)),
|
||||
tx.NewGorm(db),
|
||||
conversationDB,
|
||||
cache.NewConversationRedis(rdb, cache.GetDefaultOpt(), conversationDB),
|
||||
ctxTx,
|
||||
)
|
||||
msgRpcClient := rpcclient.NewMessageRpcClient(discov)
|
||||
msgNotificationSender := notification.NewMsgNotificationSender(rpcclient.WithRpcClient(&msgRpcClient))
|
||||
@@ -144,7 +159,11 @@ func (c *MsgTool) AllConversationClearMsgAndFixSeq() {
|
||||
}
|
||||
for i := 0; i < count; i++ {
|
||||
pageNumber := rand.Int63() % maxPage
|
||||
conversationIDs, err := c.conversationDatabase.PageConversationIDs(ctx, int32(pageNumber), batchNum)
|
||||
pagination := &sdkws.RequestPagination{
|
||||
PageNumber: int32(pageNumber),
|
||||
ShowNumber: batchNum,
|
||||
}
|
||||
conversationIDs, err := c.conversationDatabase.PageConversationIDs(ctx, pagination)
|
||||
if err != nil {
|
||||
log.ZError(ctx, "PageConversationIDs failed", err, "pageNumber", pageNumber)
|
||||
continue
|
||||
|
||||
@@ -32,7 +32,7 @@ func (c *MsgTool) convertTools() {
|
||||
for _, conversationID := range conversationIDs {
|
||||
conversationIDs = append(conversationIDs, msgprocessor.GetNotificationConversationIDByConversationID(conversationID))
|
||||
}
|
||||
userIDs, err := c.userDatabase.GetAllUserID(ctx, 0, 0)
|
||||
_, userIDs, err := c.userDatabase.GetAllUserID(ctx, nil)
|
||||
if err != nil {
|
||||
log.ZError(ctx, "get all user ids failed", err)
|
||||
return
|
||||
|
||||
@@ -36,7 +36,7 @@ type SendMsg struct {
|
||||
SenderPlatformID int32 `json:"senderPlatformID"`
|
||||
|
||||
// Content is the actual content of the message, required and excluded from Swagger documentation.
|
||||
Content map[string]interface{} `json:"content" binding:"required" swaggerignore:"true"`
|
||||
Content map[string]any `json:"content" binding:"required" swaggerignore:"true"`
|
||||
|
||||
// ContentType is an integer that represents the type of the content.
|
||||
ContentType int32 `json:"contentType" binding:"required"`
|
||||
|
||||
@@ -28,7 +28,7 @@ import (
|
||||
)
|
||||
|
||||
func Secret() jwt.Keyfunc {
|
||||
return func(token *jwt.Token) (interface{}, error) {
|
||||
return func(token *jwt.Token) (any, error) {
|
||||
return []byte(config.Config.Secret), nil
|
||||
}
|
||||
}
|
||||
@@ -55,7 +55,7 @@ func CheckAdmin(ctx context.Context) error {
|
||||
return errs.ErrNoPermission.Wrap(fmt.Sprintf("user %s is not admin userID", mcontext.GetOpUserID(ctx)))
|
||||
}
|
||||
|
||||
func ParseRedisInterfaceToken(redisToken interface{}) (*tokenverify.Claims, error) {
|
||||
func ParseRedisInterfaceToken(redisToken any) (*tokenverify.Claims, error) {
|
||||
return tokenverify.GetClaimFromToken(string(redisToken.([]uint8)), Secret())
|
||||
}
|
||||
|
||||
|
||||
@@ -46,15 +46,13 @@ func (a *RpcCmd) Exec() error {
|
||||
return a.Execute()
|
||||
}
|
||||
|
||||
func (a *RpcCmd) StartSvr(
|
||||
name string,
|
||||
rpcFn func(discov discoveryregistry.SvcDiscoveryRegistry, server *grpc.Server) error,
|
||||
) error {
|
||||
func (a *RpcCmd) StartSvr(name string, rpcFn func(discov discoveryregistry.SvcDiscoveryRegistry, server *grpc.Server) error) error {
|
||||
if a.GetPortFlag() == 0 {
|
||||
return errors.New("port is required")
|
||||
}
|
||||
return startrpc.Start(a.GetPortFlag(), name, a.GetPrometheusPortFlag(), rpcFn)
|
||||
}
|
||||
|
||||
func (a *RpcCmd) GetPortFromConfig(portType string) int {
|
||||
switch a.Name {
|
||||
case RpcPushServer:
|
||||
|
||||
+13
-11
@@ -44,6 +44,18 @@ type POfflinePush struct {
|
||||
Ext string `yaml:"ext"`
|
||||
}
|
||||
|
||||
type MYSQL struct {
|
||||
Address []string `yaml:"address"`
|
||||
Username string `yaml:"username"`
|
||||
Password string `yaml:"password"`
|
||||
Database string `yaml:"database"`
|
||||
MaxOpenConn int `yaml:"maxOpenConn"`
|
||||
MaxIdleConn int `yaml:"maxIdleConn"`
|
||||
MaxLifeTime int `yaml:"maxLifeTime"`
|
||||
LogLevel int `yaml:"logLevel"`
|
||||
SlowThreshold int `yaml:"slowThreshold"`
|
||||
}
|
||||
|
||||
type configStruct struct {
|
||||
Envs struct {
|
||||
Discovery string `yaml:"discovery"`
|
||||
@@ -55,17 +67,7 @@ type configStruct struct {
|
||||
Password string `yaml:"password"`
|
||||
} `yaml:"zookeeper"`
|
||||
|
||||
Mysql struct {
|
||||
Address []string `yaml:"address"`
|
||||
Username string `yaml:"username"`
|
||||
Password string `yaml:"password"`
|
||||
Database string `yaml:"database"`
|
||||
MaxOpenConn int `yaml:"maxOpenConn"`
|
||||
MaxIdleConn int `yaml:"maxIdleConn"`
|
||||
MaxLifeTime int `yaml:"maxLifeTime"`
|
||||
LogLevel int `yaml:"logLevel"`
|
||||
SlowThreshold int `yaml:"slowThreshold"`
|
||||
} `yaml:"mysql"`
|
||||
Mysql *MYSQL `yaml:"mysql"`
|
||||
|
||||
Mongo struct {
|
||||
Uri string `yaml:"uri"`
|
||||
|
||||
@@ -71,7 +71,7 @@ func GetOptionsByNotification(cfg NotificationConf) msgprocessor.Options {
|
||||
return opts
|
||||
}
|
||||
|
||||
func initConfig(config interface{}, configName, configFolderPath string) error {
|
||||
func initConfig(config any, configName, configFolderPath string) error {
|
||||
configFolderPath = filepath.Join(configFolderPath, configName)
|
||||
_, err := os.Stat(configFolderPath)
|
||||
if err != nil {
|
||||
|
||||
@@ -76,7 +76,7 @@ func TestGetOptionsByNotification(t *testing.T) {
|
||||
|
||||
func Test_initConfig(t *testing.T) {
|
||||
type args struct {
|
||||
config interface{}
|
||||
config any
|
||||
configName string
|
||||
configFolderPath string
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@ package convert
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/OpenIMSDK/protocol/sdkws"
|
||||
"github.com/OpenIMSDK/tools/utils"
|
||||
@@ -31,23 +32,22 @@ func FriendPb2DB(friend *sdkws.FriendInfo) *relation.FriendModel {
|
||||
return dbFriend
|
||||
}
|
||||
|
||||
func FriendDB2Pb(
|
||||
ctx context.Context,
|
||||
friendDB *relation.FriendModel,
|
||||
func FriendDB2Pb(ctx context.Context, friendDB *relation.FriendModel,
|
||||
getUsers func(ctx context.Context, userIDs []string) (map[string]*sdkws.UserInfo, error),
|
||||
) (*sdkws.FriendInfo, error) {
|
||||
pbfriend := &sdkws.FriendInfo{FriendUser: &sdkws.UserInfo{}}
|
||||
utils.CopyStructFields(pbfriend, friendDB)
|
||||
users, err := getUsers(ctx, []string{friendDB.FriendUserID})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
pbfriend.FriendUser.UserID = users[friendDB.FriendUserID].UserID
|
||||
pbfriend.FriendUser.Nickname = users[friendDB.FriendUserID].Nickname
|
||||
pbfriend.FriendUser.FaceURL = users[friendDB.FriendUserID].FaceURL
|
||||
pbfriend.FriendUser.Ex = users[friendDB.FriendUserID].Ex
|
||||
pbfriend.CreateTime = friendDB.CreateTime.Unix()
|
||||
return pbfriend, nil
|
||||
user, ok := users[friendDB.FriendUserID]
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("user not found: %s", friendDB.FriendUserID)
|
||||
}
|
||||
|
||||
return &sdkws.FriendInfo{
|
||||
FriendUser: user,
|
||||
CreateTime: friendDB.CreateTime.Unix(),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func FriendsDB2Pb(
|
||||
@@ -118,3 +118,37 @@ func FriendRequestDB2Pb(
|
||||
}
|
||||
return res, nil
|
||||
}
|
||||
|
||||
// FriendPb2DBMap converts a FriendInfo protobuf object to a map suitable for database operations.
|
||||
// It only includes non-zero or non-empty fields in the map.
|
||||
func FriendPb2DBMap(friend *sdkws.FriendInfo) map[string]any {
|
||||
if friend == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
val := make(map[string]any)
|
||||
|
||||
// Assuming FriendInfo has similar fields to those in FriendModel.
|
||||
// Add or remove fields based on your actual FriendInfo and FriendModel structures.
|
||||
if friend.FriendUser != nil {
|
||||
if friend.FriendUser.UserID != "" {
|
||||
val["friend_user_id"] = friend.FriendUser.UserID
|
||||
}
|
||||
if friend.FriendUser.Nickname != "" {
|
||||
val["nickname"] = friend.FriendUser.Nickname
|
||||
}
|
||||
if friend.FriendUser.FaceURL != "" {
|
||||
val["face_url"] = friend.FriendUser.FaceURL
|
||||
}
|
||||
if friend.FriendUser.Ex != "" {
|
||||
val["ex"] = friend.FriendUser.Ex
|
||||
}
|
||||
}
|
||||
if friend.CreateTime != 0 {
|
||||
val["create_time"] = friend.CreateTime // You might need to convert this to a proper time format.
|
||||
}
|
||||
|
||||
// Include other fields from FriendInfo as needed, similar to the above pattern.
|
||||
|
||||
return val
|
||||
}
|
||||
|
||||
+44
-18
@@ -16,32 +16,58 @@ package convert
|
||||
|
||||
import (
|
||||
"github.com/OpenIMSDK/protocol/sdkws"
|
||||
"time"
|
||||
|
||||
relationtb "github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation"
|
||||
)
|
||||
|
||||
func UsersDB2Pb(users []*relationtb.UserModel) (result []*sdkws.UserInfo) {
|
||||
func UsersDB2Pb(users []*relationtb.UserModel) []*sdkws.UserInfo {
|
||||
result := make([]*sdkws.UserInfo, 0, len(users))
|
||||
for _, user := range users {
|
||||
var userPb sdkws.UserInfo
|
||||
userPb.UserID = user.UserID
|
||||
userPb.Nickname = user.Nickname
|
||||
userPb.FaceURL = user.FaceURL
|
||||
userPb.Ex = user.Ex
|
||||
userPb.CreateTime = user.CreateTime.UnixMilli()
|
||||
userPb.AppMangerLevel = user.AppMangerLevel
|
||||
userPb.GlobalRecvMsgOpt = user.GlobalRecvMsgOpt
|
||||
result = append(result, &userPb)
|
||||
userPb := &sdkws.UserInfo{
|
||||
UserID: user.UserID,
|
||||
Nickname: user.Nickname,
|
||||
FaceURL: user.FaceURL,
|
||||
Ex: user.Ex,
|
||||
CreateTime: user.CreateTime.UnixMilli(),
|
||||
AppMangerLevel: user.AppMangerLevel,
|
||||
GlobalRecvMsgOpt: user.GlobalRecvMsgOpt,
|
||||
}
|
||||
result = append(result, userPb)
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
func UserPb2DB(user *sdkws.UserInfo) *relationtb.UserModel {
|
||||
var userDB relationtb.UserModel
|
||||
userDB.UserID = user.UserID
|
||||
userDB.Nickname = user.Nickname
|
||||
userDB.FaceURL = user.FaceURL
|
||||
userDB.Ex = user.Ex
|
||||
userDB.AppMangerLevel = user.AppMangerLevel
|
||||
userDB.GlobalRecvMsgOpt = user.GlobalRecvMsgOpt
|
||||
return &userDB
|
||||
return &relationtb.UserModel{
|
||||
UserID: user.UserID,
|
||||
Nickname: user.Nickname,
|
||||
FaceURL: user.FaceURL,
|
||||
Ex: user.Ex,
|
||||
CreateTime: time.UnixMilli(user.CreateTime),
|
||||
AppMangerLevel: user.AppMangerLevel,
|
||||
GlobalRecvMsgOpt: user.GlobalRecvMsgOpt,
|
||||
}
|
||||
}
|
||||
|
||||
func UserPb2DBMap(user *sdkws.UserInfo) map[string]any {
|
||||
if user == nil {
|
||||
return nil
|
||||
}
|
||||
val := make(map[string]any)
|
||||
fields := map[string]any{
|
||||
"nickname": user.Nickname,
|
||||
"face_url": user.FaceURL,
|
||||
"ex": user.Ex,
|
||||
"app_manager_level": user.AppMangerLevel,
|
||||
"global_recv_msg_opt": user.GlobalRecvMsgOpt,
|
||||
}
|
||||
for key, value := range fields {
|
||||
if v, ok := value.(string); ok && v != "" {
|
||||
val[key] = v
|
||||
} else if v, ok := value.(int32); ok && v != 0 {
|
||||
val[key] = v
|
||||
}
|
||||
}
|
||||
return val
|
||||
}
|
||||
|
||||
@@ -0,0 +1,87 @@
|
||||
// Copyright © 2023 OpenIM. All rights reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package convert
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
"github.com/OpenIMSDK/protocol/sdkws"
|
||||
|
||||
relationtb "github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation"
|
||||
)
|
||||
|
||||
func TestUsersDB2Pb(t *testing.T) {
|
||||
type args struct {
|
||||
users []*relationtb.UserModel
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
wantResult []*sdkws.UserInfo
|
||||
}{
|
||||
// TODO: Add test cases.
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
if gotResult := UsersDB2Pb(tt.args.users); !reflect.DeepEqual(gotResult, tt.wantResult) {
|
||||
t.Errorf("UsersDB2Pb() = %v, want %v", gotResult, tt.wantResult)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestUserPb2DB(t *testing.T) {
|
||||
type args struct {
|
||||
user *sdkws.UserInfo
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
want *relationtb.UserModel
|
||||
}{
|
||||
// TODO: Add test cases.
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
if got := UserPb2DB(tt.args.user); !reflect.DeepEqual(got, tt.want) {
|
||||
t.Errorf("UserPb2DB() = %v, want %v", got, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestUserPb2DBMap(t *testing.T) {
|
||||
user := &sdkws.UserInfo{
|
||||
Nickname: "TestUser",
|
||||
FaceURL: "http://openim.io/logo.jpg",
|
||||
Ex: "Extra Data",
|
||||
AppMangerLevel: 1,
|
||||
GlobalRecvMsgOpt: 2,
|
||||
}
|
||||
|
||||
expected := map[string]any{
|
||||
"nickname": "TestUser",
|
||||
"face_url": "http://openim.io/logo.jpg",
|
||||
"ex": "Extra Data",
|
||||
"app_manager_level": int32(1),
|
||||
"global_recv_msg_opt": int32(2),
|
||||
}
|
||||
|
||||
result := UserPb2DBMap(user)
|
||||
if !reflect.DeepEqual(result, expected) {
|
||||
t.Errorf("UserPb2DBMap returned unexpected map. Got %v, want %v", result, expected)
|
||||
}
|
||||
}
|
||||
Vendored
+34
-35
@@ -26,7 +26,6 @@ import (
|
||||
|
||||
"github.com/OpenIMSDK/tools/utils"
|
||||
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/common/db/relation"
|
||||
relationtb "github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation"
|
||||
)
|
||||
|
||||
@@ -67,10 +66,10 @@ type ConversationCache interface {
|
||||
GetUserRecvMsgOpt(ctx context.Context, ownerUserID, conversationID string) (opt int, err error)
|
||||
DelUserRecvMsgOpt(ownerUserID, conversationID string) ConversationCache
|
||||
// get one super group recv msg but do not notification userID list
|
||||
GetSuperGroupRecvMsgNotNotifyUserIDs(ctx context.Context, groupID string) (userIDs []string, err error)
|
||||
//GetSuperGroupRecvMsgNotNotifyUserIDs(ctx context.Context, groupID string) (userIDs []string, err error)
|
||||
DelSuperGroupRecvMsgNotNotifyUserIDs(groupID string) ConversationCache
|
||||
// get one super group recv msg but do not notification userID list hash
|
||||
GetSuperGroupRecvMsgNotNotifyUserIDsHash(ctx context.Context, groupID string) (hash uint64, err error)
|
||||
//GetSuperGroupRecvMsgNotNotifyUserIDsHash(ctx context.Context, groupID string) (hash uint64, err error)
|
||||
DelSuperGroupRecvMsgNotNotifyUserIDsHash(groupID string) ConversationCache
|
||||
|
||||
//GetUserAllHasReadSeqs(ctx context.Context, ownerUserID string) (map[string]int64, error)
|
||||
@@ -101,20 +100,20 @@ type ConversationRedisCache struct {
|
||||
expireTime time.Duration
|
||||
}
|
||||
|
||||
func NewNewConversationRedis(
|
||||
rdb redis.UniversalClient,
|
||||
conversationDB *relation.ConversationGorm,
|
||||
options rockscache.Options,
|
||||
) ConversationCache {
|
||||
rcClient := rockscache.NewClient(rdb, options)
|
||||
|
||||
return &ConversationRedisCache{
|
||||
rcClient: rcClient,
|
||||
metaCache: NewMetaCacheRedis(rcClient),
|
||||
conversationDB: conversationDB,
|
||||
expireTime: conversationExpireTime,
|
||||
}
|
||||
}
|
||||
//func NewNewConversationRedis(
|
||||
// rdb redis.UniversalClient,
|
||||
// conversationDB *relation.ConversationGorm,
|
||||
// options rockscache.Options,
|
||||
//) ConversationCache {
|
||||
// rcClient := rockscache.NewClient(rdb, options)
|
||||
//
|
||||
// return &ConversationRedisCache{
|
||||
// rcClient: rcClient,
|
||||
// metaCache: NewMetaCacheRedis(rcClient),
|
||||
// conversationDB: conversationDB,
|
||||
// expireTime: conversationExpireTime,
|
||||
// }
|
||||
//}
|
||||
|
||||
func (c *ConversationRedisCache) NewCache() ConversationCache {
|
||||
return &ConversationRedisCache{
|
||||
@@ -282,11 +281,11 @@ func (c *ConversationRedisCache) GetUserRecvMsgOpt(ctx context.Context, ownerUse
|
||||
})
|
||||
}
|
||||
|
||||
func (c *ConversationRedisCache) GetSuperGroupRecvMsgNotNotifyUserIDs(ctx context.Context, groupID string) (userIDs []string, err error) {
|
||||
return getCache(ctx, c.rcClient, c.getSuperGroupRecvNotNotifyUserIDsKey(groupID), c.expireTime, func(ctx context.Context) (userIDs []string, err error) {
|
||||
return c.conversationDB.FindSuperGroupRecvMsgNotNotifyUserIDs(ctx, groupID)
|
||||
})
|
||||
}
|
||||
//func (c *ConversationRedisCache) GetSuperGroupRecvMsgNotNotifyUserIDs(ctx context.Context, groupID string) (userIDs []string, err error) {
|
||||
// return getCache(ctx, c.rcClient, c.getSuperGroupRecvNotNotifyUserIDsKey(groupID), c.expireTime, func(ctx context.Context) (userIDs []string, err error) {
|
||||
// return c.conversationDB.FindSuperGroupRecvMsgNotNotifyUserIDs(ctx, groupID)
|
||||
// })
|
||||
//}
|
||||
|
||||
func (c *ConversationRedisCache) DelUsersConversation(conversationID string, ownerUserIDs ...string) ConversationCache {
|
||||
keys := make([]string, 0, len(ownerUserIDs))
|
||||
@@ -313,19 +312,19 @@ func (c *ConversationRedisCache) DelSuperGroupRecvMsgNotNotifyUserIDs(groupID st
|
||||
return cache
|
||||
}
|
||||
|
||||
func (c *ConversationRedisCache) GetSuperGroupRecvMsgNotNotifyUserIDsHash(ctx context.Context, groupID string) (hash uint64, err error) {
|
||||
return getCache(ctx, c.rcClient, c.getSuperGroupRecvNotNotifyUserIDsHashKey(groupID), c.expireTime, func(ctx context.Context) (hash uint64, err error) {
|
||||
userIDs, err := c.GetSuperGroupRecvMsgNotNotifyUserIDs(ctx, groupID)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
utils.Sort(userIDs, true)
|
||||
bi := big.NewInt(0)
|
||||
bi.SetString(utils.Md5(strings.Join(userIDs, ";"))[0:8], 16)
|
||||
return bi.Uint64(), nil
|
||||
},
|
||||
)
|
||||
}
|
||||
//func (c *ConversationRedisCache) GetSuperGroupRecvMsgNotNotifyUserIDsHash(ctx context.Context, groupID string) (hash uint64, err error) {
|
||||
// return getCache(ctx, c.rcClient, c.getSuperGroupRecvNotNotifyUserIDsHashKey(groupID), c.expireTime, func(ctx context.Context) (hash uint64, err error) {
|
||||
// userIDs, err := c.GetSuperGroupRecvMsgNotNotifyUserIDs(ctx, groupID)
|
||||
// if err != nil {
|
||||
// return 0, err
|
||||
// }
|
||||
// utils.Sort(userIDs, true)
|
||||
// bi := big.NewInt(0)
|
||||
// bi.SetString(utils.Md5(strings.Join(userIDs, ";"))[0:8], 16)
|
||||
// return bi.Uint64(), nil
|
||||
// },
|
||||
// )
|
||||
//}
|
||||
|
||||
func (c *ConversationRedisCache) DelSuperGroupRecvMsgNotNotifyUserIDsHash(groupID string) ConversationCache {
|
||||
cache := c.NewCache()
|
||||
|
||||
Vendored
+17
-7
@@ -33,19 +33,20 @@ const (
|
||||
friendKey = "FRIEND_INFO:"
|
||||
)
|
||||
|
||||
// args fn will exec when no data in msgCache.
|
||||
// FriendCache is an interface for caching friend-related data.
|
||||
type FriendCache interface {
|
||||
metaCache
|
||||
NewCache() FriendCache
|
||||
GetFriendIDs(ctx context.Context, ownerUserID string) (friendIDs []string, err error)
|
||||
// call when friendID List changed
|
||||
// Called when friendID list changed
|
||||
DelFriendIDs(ownerUserID ...string) FriendCache
|
||||
// get single friendInfo from msgCache
|
||||
// Get single friendInfo from the cache
|
||||
GetFriend(ctx context.Context, ownerUserID, friendUserID string) (friend *relationtb.FriendModel, err error)
|
||||
// del friend when friend info changed
|
||||
// Delete friend when friend info changed
|
||||
DelFriend(ownerUserID, friendUserID string) FriendCache
|
||||
}
|
||||
|
||||
// FriendCacheRedis is an implementation of the FriendCache interface using Redis.
|
||||
type FriendCacheRedis struct {
|
||||
metaCache
|
||||
friendDB relationtb.FriendModelInterface
|
||||
@@ -53,6 +54,7 @@ type FriendCacheRedis struct {
|
||||
rcClient *rockscache.Client
|
||||
}
|
||||
|
||||
// NewFriendCacheRedis creates a new instance of FriendCacheRedis.
|
||||
func NewFriendCacheRedis(rdb redis.UniversalClient, friendDB relationtb.FriendModelInterface,
|
||||
options rockscache.Options) FriendCache {
|
||||
rcClient := rockscache.NewClient(rdb, options)
|
||||
@@ -64,6 +66,7 @@ func NewFriendCacheRedis(rdb redis.UniversalClient, friendDB relationtb.FriendMo
|
||||
}
|
||||
}
|
||||
|
||||
// NewCache creates a new instance of FriendCacheRedis with the same configuration.
|
||||
func (f *FriendCacheRedis) NewCache() FriendCache {
|
||||
return &FriendCacheRedis{
|
||||
rcClient: f.rcClient,
|
||||
@@ -73,24 +76,29 @@ func (f *FriendCacheRedis) NewCache() FriendCache {
|
||||
}
|
||||
}
|
||||
|
||||
// getFriendIDsKey returns the key for storing friend IDs in the cache.
|
||||
func (f *FriendCacheRedis) getFriendIDsKey(ownerUserID string) string {
|
||||
return friendIDsKey + ownerUserID
|
||||
}
|
||||
|
||||
// getTwoWayFriendsIDsKey returns the key for storing two-way friend IDs in the cache.
|
||||
func (f *FriendCacheRedis) getTwoWayFriendsIDsKey(ownerUserID string) string {
|
||||
return TwoWayFriendsIDsKey + ownerUserID
|
||||
}
|
||||
|
||||
// getFriendKey returns the key for storing friend info in the cache.
|
||||
func (f *FriendCacheRedis) getFriendKey(ownerUserID, friendUserID string) string {
|
||||
return friendKey + ownerUserID + "-" + friendUserID
|
||||
}
|
||||
|
||||
// GetFriendIDs retrieves friend IDs from the cache or the database if not found.
|
||||
func (f *FriendCacheRedis) GetFriendIDs(ctx context.Context, ownerUserID string) (friendIDs []string, err error) {
|
||||
return getCache(ctx, f.rcClient, f.getFriendIDsKey(ownerUserID), f.expireTime, func(ctx context.Context) ([]string, error) {
|
||||
return f.friendDB.FindFriendUserIDs(ctx, ownerUserID)
|
||||
})
|
||||
}
|
||||
|
||||
// DelFriendIDs deletes friend IDs from the cache.
|
||||
func (f *FriendCacheRedis) DelFriendIDs(ownerUserIDs ...string) FriendCache {
|
||||
newGroupCache := f.NewCache()
|
||||
keys := make([]string, 0, len(ownerUserIDs))
|
||||
@@ -102,7 +110,7 @@ func (f *FriendCacheRedis) DelFriendIDs(ownerUserIDs ...string) FriendCache {
|
||||
return newGroupCache
|
||||
}
|
||||
|
||||
// todo.
|
||||
// GetTwoWayFriendIDs retrieves two-way friend IDs from the cache.
|
||||
func (f *FriendCacheRedis) GetTwoWayFriendIDs(ctx context.Context, ownerUserID string) (twoWayFriendIDs []string, err error) {
|
||||
friendIDs, err := f.GetFriendIDs(ctx, ownerUserID)
|
||||
if err != nil {
|
||||
@@ -121,6 +129,7 @@ func (f *FriendCacheRedis) GetTwoWayFriendIDs(ctx context.Context, ownerUserID s
|
||||
return twoWayFriendIDs, nil
|
||||
}
|
||||
|
||||
// DelTwoWayFriendIDs deletes two-way friend IDs from the cache.
|
||||
func (f *FriendCacheRedis) DelTwoWayFriendIDs(ctx context.Context, ownerUserID string) FriendCache {
|
||||
newFriendCache := f.NewCache()
|
||||
newFriendCache.AddKeys(f.getTwoWayFriendsIDsKey(ownerUserID))
|
||||
@@ -128,14 +137,15 @@ func (f *FriendCacheRedis) DelTwoWayFriendIDs(ctx context.Context, ownerUserID s
|
||||
return newFriendCache
|
||||
}
|
||||
|
||||
func (f *FriendCacheRedis) GetFriend(ctx context.Context, ownerUserID,
|
||||
friendUserID string) (friend *relationtb.FriendModel, err error) {
|
||||
// GetFriend retrieves friend info from the cache or the database if not found.
|
||||
func (f *FriendCacheRedis) GetFriend(ctx context.Context, ownerUserID, friendUserID string) (friend *relationtb.FriendModel, err error) {
|
||||
return getCache(ctx, f.rcClient, f.getFriendKey(ownerUserID,
|
||||
friendUserID), f.expireTime, func(ctx context.Context) (*relationtb.FriendModel, error) {
|
||||
return f.friendDB.Take(ctx, ownerUserID, friendUserID)
|
||||
})
|
||||
}
|
||||
|
||||
// DelFriend deletes friend info from the cache.
|
||||
func (f *FriendCacheRedis) DelFriend(ownerUserID, friendUserID string) FriendCache {
|
||||
newFriendCache := f.NewCache()
|
||||
newFriendCache.AddKeys(f.getFriendKey(ownerUserID, friendUserID))
|
||||
|
||||
Vendored
+123
-158
@@ -16,8 +16,13 @@ package cache
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/OpenIMSDK/protocol/constant"
|
||||
"github.com/OpenIMSDK/tools/errs"
|
||||
|
||||
"github.com/OpenIMSDK/tools/log"
|
||||
|
||||
"github.com/dtm-labs/rockscache"
|
||||
@@ -26,21 +31,24 @@ import (
|
||||
"github.com/OpenIMSDK/tools/utils"
|
||||
|
||||
relationtb "github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation"
|
||||
unrelationtb "github.com/openimsdk/open-im-server/v3/pkg/common/db/table/unrelation"
|
||||
)
|
||||
|
||||
const (
|
||||
groupExpireTime = time.Second * 60 * 60 * 12
|
||||
groupInfoKey = "GROUP_INFO:"
|
||||
groupMemberIDsKey = "GROUP_MEMBER_IDS:"
|
||||
groupMembersHashKey = "GROUP_MEMBERS_HASH2:"
|
||||
groupMemberInfoKey = "GROUP_MEMBER_INFO:"
|
||||
joinedSuperGroupsKey = "JOIN_SUPER_GROUPS:"
|
||||
SuperGroupMemberIDsKey = "SUPER_GROUP_MEMBER_IDS:"
|
||||
joinedGroupsKey = "JOIN_GROUPS_KEY:"
|
||||
groupMemberNumKey = "GROUP_MEMBER_NUM_CACHE:"
|
||||
groupExpireTime = time.Second * 60 * 60 * 12
|
||||
groupInfoKey = "GROUP_INFO:"
|
||||
groupMemberIDsKey = "GROUP_MEMBER_IDS:"
|
||||
groupMembersHashKey = "GROUP_MEMBERS_HASH2:"
|
||||
groupMemberInfoKey = "GROUP_MEMBER_INFO:"
|
||||
//groupOwnerInfoKey = "GROUP_OWNER_INFO:"
|
||||
joinedGroupsKey = "JOIN_GROUPS_KEY:"
|
||||
groupMemberNumKey = "GROUP_MEMBER_NUM_CACHE:"
|
||||
groupRoleLevelMemberIDsKey = "GROUP_ROLE_LEVEL_MEMBER_IDS:"
|
||||
)
|
||||
|
||||
type GroupHash interface {
|
||||
GetGroupHash(ctx context.Context, groupID string) (uint64, error)
|
||||
}
|
||||
|
||||
type GroupCache interface {
|
||||
metaCache
|
||||
NewCache() GroupCache
|
||||
@@ -48,11 +56,6 @@ type GroupCache interface {
|
||||
GetGroupInfo(ctx context.Context, groupID string) (group *relationtb.GroupModel, err error)
|
||||
DelGroupsInfo(groupIDs ...string) GroupCache
|
||||
|
||||
GetJoinedSuperGroupIDs(ctx context.Context, userID string) (joinedSuperGroupIDs []string, err error)
|
||||
DelJoinedSuperGroupIDs(userIDs ...string) GroupCache
|
||||
GetSuperGroupMemberIDs(ctx context.Context, groupIDs ...string) (models []*unrelationtb.SuperGroupModel, err error)
|
||||
DelSuperGroupMemberIDs(groupIDs ...string) GroupCache
|
||||
|
||||
GetGroupMembersHash(ctx context.Context, groupID string) (hashCode uint64, err error)
|
||||
GetGroupMemberHashMap(ctx context.Context, groupIDs []string) (map[string]*relationtb.GroupSimpleUserID, error)
|
||||
DelGroupMembersHash(groupID string) GroupCache
|
||||
@@ -69,9 +72,16 @@ type GroupCache interface {
|
||||
GetGroupMembersInfo(ctx context.Context, groupID string, userID []string) (groupMembers []*relationtb.GroupMemberModel, err error)
|
||||
GetAllGroupMembersInfo(ctx context.Context, groupID string) (groupMembers []*relationtb.GroupMemberModel, err error)
|
||||
GetGroupMembersPage(ctx context.Context, groupID string, userID []string, showNumber, pageNumber int32) (total uint32, groupMembers []*relationtb.GroupMemberModel, err error)
|
||||
FindGroupMemberUser(ctx context.Context, groupIDs []string, userID string) ([]*relationtb.GroupMemberModel, error)
|
||||
|
||||
GetGroupRoleLevelMemberIDs(ctx context.Context, groupID string, roleLevel int32) ([]string, error)
|
||||
GetGroupOwner(ctx context.Context, groupID string) (*relationtb.GroupMemberModel, error)
|
||||
GetGroupsOwner(ctx context.Context, groupIDs []string) ([]*relationtb.GroupMemberModel, error)
|
||||
DelGroupRoleLevel(groupID string, roleLevel []int32) GroupCache
|
||||
DelGroupAllRoleLevel(groupID string) GroupCache
|
||||
DelGroupMembersInfo(groupID string, userID ...string) GroupCache
|
||||
|
||||
GetGroupRoleLevelMemberInfo(ctx context.Context, groupID string, roleLevel int32) ([]*relationtb.GroupMemberModel, error)
|
||||
GetGroupRolesLevelMemberInfo(ctx context.Context, groupID string, roleLevels []int32) ([]*relationtb.GroupMemberModel, error)
|
||||
GetGroupMemberNum(ctx context.Context, groupID string) (memberNum int64, err error)
|
||||
DelGroupsMemberNum(groupID ...string) GroupCache
|
||||
}
|
||||
@@ -81,10 +91,9 @@ type GroupCacheRedis struct {
|
||||
groupDB relationtb.GroupModelInterface
|
||||
groupMemberDB relationtb.GroupMemberModelInterface
|
||||
groupRequestDB relationtb.GroupRequestModelInterface
|
||||
mongoDB unrelationtb.SuperGroupModelInterface
|
||||
expireTime time.Duration
|
||||
rcClient *rockscache.Client
|
||||
hashCode func(ctx context.Context, groupID string) (uint64, error)
|
||||
groupHash GroupHash
|
||||
}
|
||||
|
||||
func NewGroupCacheRedis(
|
||||
@@ -92,8 +101,7 @@ func NewGroupCacheRedis(
|
||||
groupDB relationtb.GroupModelInterface,
|
||||
groupMemberDB relationtb.GroupMemberModelInterface,
|
||||
groupRequestDB relationtb.GroupRequestModelInterface,
|
||||
mongoClient unrelationtb.SuperGroupModelInterface,
|
||||
hashCode func(ctx context.Context, groupID string) (uint64, error),
|
||||
hashCode GroupHash,
|
||||
opts rockscache.Options,
|
||||
) GroupCache {
|
||||
rcClient := rockscache.NewClient(rdb, opts)
|
||||
@@ -101,8 +109,7 @@ func NewGroupCacheRedis(
|
||||
return &GroupCacheRedis{
|
||||
rcClient: rcClient, expireTime: groupExpireTime,
|
||||
groupDB: groupDB, groupMemberDB: groupMemberDB, groupRequestDB: groupRequestDB,
|
||||
mongoDB: mongoClient,
|
||||
hashCode: hashCode,
|
||||
groupHash: hashCode,
|
||||
metaCache: NewMetaCacheRedis(rcClient),
|
||||
}
|
||||
}
|
||||
@@ -114,7 +121,6 @@ func (g *GroupCacheRedis) NewCache() GroupCache {
|
||||
groupDB: g.groupDB,
|
||||
groupMemberDB: g.groupMemberDB,
|
||||
groupRequestDB: g.groupRequestDB,
|
||||
mongoDB: g.mongoDB,
|
||||
metaCache: NewMetaCacheRedis(g.rcClient, g.metaCache.GetPreDelKeys()...),
|
||||
}
|
||||
}
|
||||
@@ -123,18 +129,10 @@ func (g *GroupCacheRedis) getGroupInfoKey(groupID string) string {
|
||||
return groupInfoKey + groupID
|
||||
}
|
||||
|
||||
func (g *GroupCacheRedis) getJoinedSuperGroupsIDKey(userID string) string {
|
||||
return joinedSuperGroupsKey + userID
|
||||
}
|
||||
|
||||
func (g *GroupCacheRedis) getJoinedGroupsKey(userID string) string {
|
||||
return joinedGroupsKey + userID
|
||||
}
|
||||
|
||||
func (g *GroupCacheRedis) getSuperGroupMemberIDsKey(groupID string) string {
|
||||
return SuperGroupMemberIDsKey + groupID
|
||||
}
|
||||
|
||||
func (g *GroupCacheRedis) getGroupMembersHashKey(groupID string) string {
|
||||
return groupMembersHashKey + groupID
|
||||
}
|
||||
@@ -151,6 +149,10 @@ func (g *GroupCacheRedis) getGroupMemberNumKey(groupID string) string {
|
||||
return groupMemberNumKey + groupID
|
||||
}
|
||||
|
||||
func (g *GroupCacheRedis) getGroupRoleLevelMemberIDsKey(groupID string, roleLevel int32) string {
|
||||
return groupRoleLevelMemberIDsKey + groupID + "-" + strconv.Itoa(int(roleLevel))
|
||||
}
|
||||
|
||||
func (g *GroupCacheRedis) GetGroupIndex(group *relationtb.GroupModel, keys []string) (int, error) {
|
||||
key := g.getGroupInfoKey(group.GroupID)
|
||||
for i, _key := range keys {
|
||||
@@ -173,15 +175,7 @@ func (g *GroupCacheRedis) GetGroupMemberIndex(groupMember *relationtb.GroupMembe
|
||||
return 0, errIndex
|
||||
}
|
||||
|
||||
// / groupInfo.
|
||||
func (g *GroupCacheRedis) GetGroupsInfo(ctx context.Context, groupIDs []string) (groups []*relationtb.GroupModel, err error) {
|
||||
//var keys []string
|
||||
//for _, group := range groupIDs {
|
||||
// keys = append(keys, g.getGroupInfoKey(group))
|
||||
//}
|
||||
//return batchGetCache(ctx, g.rcClient, keys, g.expireTime, g.GetGroupIndex, func(ctx context.Context) ([]*relationtb.GroupModel, error) {
|
||||
// return g.groupDB.Find(ctx, groupIDs)
|
||||
//})
|
||||
return batchGetCache2(ctx, g.rcClient, g.expireTime, groupIDs, func(groupID string) string {
|
||||
return g.getGroupInfoKey(groupID)
|
||||
}, func(ctx context.Context, groupID string) (*relationtb.GroupModel, error) {
|
||||
@@ -206,123 +200,44 @@ func (g *GroupCacheRedis) DelGroupsInfo(groupIDs ...string) GroupCache {
|
||||
return newGroupCache
|
||||
}
|
||||
|
||||
func (g *GroupCacheRedis) GetJoinedSuperGroupIDs(ctx context.Context, userID string) (joinedSuperGroupIDs []string, err error) {
|
||||
return getCache(ctx, g.rcClient, g.getJoinedSuperGroupsIDKey(userID), g.expireTime, func(ctx context.Context) ([]string, error) {
|
||||
userGroup, err := g.mongoDB.GetSuperGroupByUserID(ctx, userID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return userGroup.GroupIDs, nil
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
func (g *GroupCacheRedis) GetSuperGroupMemberIDs(ctx context.Context, groupIDs ...string) (models []*unrelationtb.SuperGroupModel, err error) {
|
||||
//var keys []string
|
||||
//for _, group := range groupIDs {
|
||||
// keys = append(keys, g.getSuperGroupMemberIDsKey(group))
|
||||
//}
|
||||
//return batchGetCache(ctx, g.rcClient, keys, g.expireTime, func(model *unrelationtb.SuperGroupModel, keys []string) (int, error) {
|
||||
// for i, key := range keys {
|
||||
// if g.getSuperGroupMemberIDsKey(model.GroupID) == key {
|
||||
// return i, nil
|
||||
// }
|
||||
// }
|
||||
// return 0, errIndex
|
||||
//},
|
||||
// func(ctx context.Context) ([]*unrelationtb.SuperGroupModel, error) {
|
||||
// return g.mongoDB.FindSuperGroup(ctx, groupIDs)
|
||||
// })
|
||||
return batchGetCache2(ctx, g.rcClient, g.expireTime, groupIDs, func(groupID string) string {
|
||||
return g.getSuperGroupMemberIDsKey(groupID)
|
||||
}, func(ctx context.Context, groupID string) (*unrelationtb.SuperGroupModel, error) {
|
||||
return g.mongoDB.TakeSuperGroup(ctx, groupID)
|
||||
})
|
||||
}
|
||||
|
||||
// userJoinSuperGroup.
|
||||
func (g *GroupCacheRedis) DelJoinedSuperGroupIDs(userIDs ...string) GroupCache {
|
||||
newGroupCache := g.NewCache()
|
||||
keys := make([]string, 0, len(userIDs))
|
||||
for _, userID := range userIDs {
|
||||
keys = append(keys, g.getJoinedSuperGroupsIDKey(userID))
|
||||
}
|
||||
newGroupCache.AddKeys(keys...)
|
||||
|
||||
return newGroupCache
|
||||
}
|
||||
|
||||
func (g *GroupCacheRedis) DelSuperGroupMemberIDs(groupIDs ...string) GroupCache {
|
||||
func (g *GroupCacheRedis) DelGroupsOwner(groupIDs ...string) GroupCache {
|
||||
newGroupCache := g.NewCache()
|
||||
keys := make([]string, 0, len(groupIDs))
|
||||
for _, groupID := range groupIDs {
|
||||
keys = append(keys, g.getSuperGroupMemberIDsKey(groupID))
|
||||
keys = append(keys, g.getGroupRoleLevelMemberIDsKey(groupID, constant.GroupOwner))
|
||||
}
|
||||
newGroupCache.AddKeys(keys...)
|
||||
|
||||
return newGroupCache
|
||||
}
|
||||
|
||||
// groupMembersHash.
|
||||
func (g *GroupCacheRedis) GetGroupMembersHash(ctx context.Context, groupID string) (hashCode uint64, err error) {
|
||||
return getCache(ctx, g.rcClient, g.getGroupMembersHashKey(groupID), g.expireTime, func(ctx context.Context) (uint64, error) {
|
||||
return g.hashCode(ctx, groupID)
|
||||
})
|
||||
func (g *GroupCacheRedis) DelGroupRoleLevel(groupID string, roleLevels []int32) GroupCache {
|
||||
newGroupCache := g.NewCache()
|
||||
keys := make([]string, 0, len(roleLevels))
|
||||
for _, roleLevel := range roleLevels {
|
||||
keys = append(keys, g.getGroupRoleLevelMemberIDsKey(groupID, roleLevel))
|
||||
}
|
||||
newGroupCache.AddKeys(keys...)
|
||||
return newGroupCache
|
||||
}
|
||||
|
||||
//return getCache(ctx, g.rcClient, g.getGroupMembersHashKey(groupID), g.expireTime,
|
||||
// func(ctx context.Context) (uint64, error) {
|
||||
// userIDs, err := g.GetGroupMemberIDs(ctx, groupID)
|
||||
// if err != nil {
|
||||
// return 0, err
|
||||
// }
|
||||
// log.ZInfo(ctx, "GetGroupMembersHash", "groupID", groupID, "userIDs", userIDs)
|
||||
// var members []*relationtb.GroupMemberModel
|
||||
// if len(userIDs) > 0 {
|
||||
// members, err = g.GetGroupMembersInfo(ctx, groupID, userIDs)
|
||||
// if err != nil {
|
||||
// return 0, err
|
||||
// }
|
||||
// utils.Sort(userIDs, true)
|
||||
// }
|
||||
// memberMap := make(map[string]*relationtb.GroupMemberModel)
|
||||
// for i, member := range members {
|
||||
// memberMap[member.UserID] = members[i]
|
||||
// }
|
||||
// data := make([]string, 0, len(members)*11)
|
||||
// for _, userID := range userIDs {
|
||||
// member, ok := memberMap[userID]
|
||||
// if !ok {
|
||||
// continue
|
||||
// }
|
||||
// data = append(data,
|
||||
// member.GroupID,
|
||||
// member.UserID,
|
||||
// member.Nickname,
|
||||
// member.FaceURL,
|
||||
// strconv.Itoa(int(member.RoleLevel)),
|
||||
// strconv.FormatInt(member.JoinTime.UnixMilli(), 10),
|
||||
// strconv.Itoa(int(member.JoinSource)),
|
||||
// member.InviterUserID,
|
||||
// member.OperatorUserID,
|
||||
// strconv.FormatInt(member.MuteEndTime.UnixMilli(), 10),
|
||||
// member.Ex,
|
||||
// )
|
||||
// }
|
||||
// log.ZInfo(ctx, "hash data info", "userIDs.len", len(userIDs), "hash.data.len", len(data))
|
||||
// log.ZInfo(ctx, "json hash data", "groupID", groupID, "data", data)
|
||||
// val, err := json.Marshal(data)
|
||||
// if err != nil {
|
||||
// return 0, err
|
||||
// }
|
||||
// sum := md5.Sum(val)
|
||||
// code := binary.BigEndian.Uint64(sum[:])
|
||||
// log.ZInfo(ctx, "GetGroupMembersHash", "groupID", groupID, "hashCode", code, "num", len(members))
|
||||
// return code, nil
|
||||
// },
|
||||
//)
|
||||
func (g *GroupCacheRedis) DelGroupAllRoleLevel(groupID string) GroupCache {
|
||||
return g.DelGroupRoleLevel(groupID, []int32{constant.GroupOwner, constant.GroupAdmin, constant.GroupOrdinaryUsers})
|
||||
}
|
||||
|
||||
func (g *GroupCacheRedis) GetGroupMembersHash(ctx context.Context, groupID string) (hashCode uint64, err error) {
|
||||
if g.groupHash == nil {
|
||||
return 0, errs.ErrInternalServer.Wrap("group hash is nil")
|
||||
}
|
||||
return getCache(ctx, g.rcClient, g.getGroupMembersHashKey(groupID), g.expireTime, func(ctx context.Context) (uint64, error) {
|
||||
return g.groupHash.GetGroupHash(ctx, groupID)
|
||||
})
|
||||
}
|
||||
|
||||
func (g *GroupCacheRedis) GetGroupMemberHashMap(ctx context.Context, groupIDs []string) (map[string]*relationtb.GroupSimpleUserID, error) {
|
||||
if g.groupHash == nil {
|
||||
return nil, errs.ErrInternalServer.Wrap("group hash is nil")
|
||||
}
|
||||
res := make(map[string]*relationtb.GroupSimpleUserID)
|
||||
for _, groupID := range groupIDs {
|
||||
hash, err := g.GetGroupMembersHash(ctx, groupID)
|
||||
@@ -347,7 +262,6 @@ func (g *GroupCacheRedis) DelGroupMembersHash(groupID string) GroupCache {
|
||||
return cache
|
||||
}
|
||||
|
||||
// groupMemberIDs.
|
||||
func (g *GroupCacheRedis) GetGroupMemberIDs(ctx context.Context, groupID string) (groupMemberIDs []string, err error) {
|
||||
return getCache(ctx, g.rcClient, g.getGroupMemberIDsKey(groupID), g.expireTime, func(ctx context.Context) ([]string, error) {
|
||||
return g.groupMemberDB.FindMemberUserID(ctx, groupID)
|
||||
@@ -398,13 +312,6 @@ func (g *GroupCacheRedis) GetGroupMemberInfo(ctx context.Context, groupID, userI
|
||||
}
|
||||
|
||||
func (g *GroupCacheRedis) GetGroupMembersInfo(ctx context.Context, groupID string, userIDs []string) ([]*relationtb.GroupMemberModel, error) {
|
||||
//var keys []string
|
||||
//for _, userID := range userIDs {
|
||||
// keys = append(keys, g.getGroupMemberInfoKey(groupID, userID))
|
||||
//}
|
||||
//return batchGetCache(ctx, g.rcClient, keys, g.expireTime, g.GetGroupMemberIndex, func(ctx context.Context) ([]*relationtb.GroupMemberModel, error) {
|
||||
// return g.groupMemberDB.Find(ctx, []string{groupID}, userIDs, nil)
|
||||
//})
|
||||
return batchGetCache2(ctx, g.rcClient, g.expireTime, userIDs, func(userID string) string {
|
||||
return g.getGroupMemberInfoKey(groupID, userID)
|
||||
}, func(ctx context.Context, userID string) (*relationtb.GroupMemberModel, error) {
|
||||
@@ -446,13 +353,6 @@ func (g *GroupCacheRedis) GetAllGroupMemberInfo(ctx context.Context, groupID str
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
//var keys []string
|
||||
//for _, groupMemberID := range groupMemberIDs {
|
||||
// keys = append(keys, g.getGroupMemberInfoKey(groupID, groupMemberID))
|
||||
//}
|
||||
//return batchGetCache(ctx, g.rcClient, keys, g.expireTime, g.GetGroupMemberIndex, func(ctx context.Context) ([]*relationtb.GroupMemberModel, error) {
|
||||
// return g.groupMemberDB.Find(ctx, []string{groupID}, groupMemberIDs, nil)
|
||||
//})
|
||||
return g.GetGroupMembersInfo(ctx, groupID, groupMemberIDs)
|
||||
}
|
||||
|
||||
@@ -483,3 +383,68 @@ func (g *GroupCacheRedis) DelGroupsMemberNum(groupID ...string) GroupCache {
|
||||
|
||||
return cache
|
||||
}
|
||||
|
||||
func (g *GroupCacheRedis) GetGroupOwner(ctx context.Context, groupID string) (*relationtb.GroupMemberModel, error) {
|
||||
members, err := g.GetGroupRoleLevelMemberInfo(ctx, groupID, constant.GroupOwner)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(members) == 0 {
|
||||
return nil, errs.ErrRecordNotFound.Wrap(fmt.Sprintf("group %s owner not found", groupID))
|
||||
}
|
||||
return members[0], nil
|
||||
}
|
||||
|
||||
func (g *GroupCacheRedis) GetGroupsOwner(ctx context.Context, groupIDs []string) ([]*relationtb.GroupMemberModel, error) {
|
||||
members := make([]*relationtb.GroupMemberModel, 0, len(groupIDs))
|
||||
for _, groupID := range groupIDs {
|
||||
items, err := g.GetGroupRoleLevelMemberInfo(ctx, groupID, constant.GroupOwner)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(items) > 0 {
|
||||
members = append(members, items[0])
|
||||
}
|
||||
}
|
||||
return members, nil
|
||||
}
|
||||
|
||||
func (g *GroupCacheRedis) GetGroupRoleLevelMemberIDs(ctx context.Context, groupID string, roleLevel int32) ([]string, error) {
|
||||
return getCache(ctx, g.rcClient, g.getGroupRoleLevelMemberIDsKey(groupID, roleLevel), g.expireTime, func(ctx context.Context) ([]string, error) {
|
||||
return g.groupMemberDB.FindRoleLevelUserIDs(ctx, groupID, roleLevel)
|
||||
})
|
||||
}
|
||||
|
||||
func (g *GroupCacheRedis) GetGroupRoleLevelMemberInfo(ctx context.Context, groupID string, roleLevel int32) ([]*relationtb.GroupMemberModel, error) {
|
||||
userIDs, err := g.GetGroupRoleLevelMemberIDs(ctx, groupID, roleLevel)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return g.GetGroupMembersInfo(ctx, groupID, userIDs)
|
||||
}
|
||||
|
||||
func (g *GroupCacheRedis) GetGroupRolesLevelMemberInfo(ctx context.Context, groupID string, roleLevels []int32) ([]*relationtb.GroupMemberModel, error) {
|
||||
var userIDs []string
|
||||
for _, roleLevel := range roleLevels {
|
||||
ids, err := g.GetGroupRoleLevelMemberIDs(ctx, groupID, roleLevel)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
userIDs = append(userIDs, ids...)
|
||||
}
|
||||
return g.GetGroupMembersInfo(ctx, groupID, userIDs)
|
||||
}
|
||||
|
||||
func (g *GroupCacheRedis) FindGroupMemberUser(ctx context.Context, groupIDs []string, userID string) (_ []*relationtb.GroupMemberModel, err error) {
|
||||
if len(groupIDs) == 0 {
|
||||
groupIDs, err = g.GetJoinedGroupIDs(ctx, userID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return batchGetCache2(ctx, g.rcClient, g.expireTime, groupIDs, func(groupID string) string {
|
||||
return g.getGroupMemberInfoKey(groupID, userID)
|
||||
}, func(ctx context.Context, groupID string) (*relationtb.GroupMemberModel, error) {
|
||||
return g.groupMemberDB.Take(ctx, groupID, userID)
|
||||
})
|
||||
}
|
||||
|
||||
Vendored
+19
-1
@@ -18,6 +18,8 @@ import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/redis/go-redis/v9"
|
||||
@@ -43,6 +45,9 @@ func NewRedis() (redis.UniversalClient, error) {
|
||||
return redisClient, nil
|
||||
}
|
||||
|
||||
// Read configuration from environment variables
|
||||
overrideConfigFromEnv()
|
||||
|
||||
if len(config.Config.Redis.Address) == 0 {
|
||||
return nil, errors.New("redis address is empty")
|
||||
}
|
||||
@@ -60,7 +65,7 @@ func NewRedis() (redis.UniversalClient, error) {
|
||||
rdb = redis.NewClient(&redis.Options{
|
||||
Addr: config.Config.Redis.Address[0],
|
||||
Username: config.Config.Redis.Username,
|
||||
Password: config.Config.Redis.Password, // no password set
|
||||
Password: config.Config.Redis.Password,
|
||||
DB: 0, // use default DB
|
||||
PoolSize: 100, // connection pool size
|
||||
MaxRetries: maxRetry,
|
||||
@@ -78,3 +83,16 @@ func NewRedis() (redis.UniversalClient, error) {
|
||||
redisClient = rdb
|
||||
return rdb, err
|
||||
}
|
||||
|
||||
// overrideConfigFromEnv overrides configuration fields with environment variables if present.
|
||||
func overrideConfigFromEnv() {
|
||||
if envAddr := os.Getenv("REDIS_ADDRESS"); envAddr != "" {
|
||||
config.Config.Redis.Address = strings.Split(envAddr, ",") // Assuming addresses are comma-separated
|
||||
}
|
||||
if envUser := os.Getenv("REDIS_USERNAME"); envUser != "" {
|
||||
config.Config.Redis.Username = envUser
|
||||
}
|
||||
if envPass := os.Getenv("REDIS_PASSWORD"); envPass != "" {
|
||||
config.Config.Redis.Password = envPass
|
||||
}
|
||||
}
|
||||
Vendored
+5
-2
@@ -38,7 +38,7 @@ const (
|
||||
var errIndex = errors.New("err index")
|
||||
|
||||
type metaCache interface {
|
||||
ExecDel(ctx context.Context) error
|
||||
ExecDel(ctx context.Context, distinct ...bool) error
|
||||
// delete key rapid
|
||||
DelKey(ctx context.Context, key string) error
|
||||
AddKeys(keys ...string)
|
||||
@@ -57,7 +57,10 @@ type metaCacheRedis struct {
|
||||
retryInterval time.Duration
|
||||
}
|
||||
|
||||
func (m *metaCacheRedis) ExecDel(ctx context.Context) error {
|
||||
func (m *metaCacheRedis) ExecDel(ctx context.Context, distinct ...bool) error {
|
||||
if len(distinct) > 0 && distinct[0] {
|
||||
m.keys = utils.Distinct(m.keys)
|
||||
}
|
||||
if len(m.keys) > 0 {
|
||||
log.ZDebug(ctx, "delete cache", "keys", m.keys)
|
||||
for _, key := range m.keys {
|
||||
|
||||
Vendored
+13
-56
@@ -173,20 +173,7 @@ func (c *msgCache) getSeqs(ctx context.Context, items []string, getkey func(s st
|
||||
}
|
||||
|
||||
func (c *msgCache) SetMaxSeq(ctx context.Context, conversationID string, maxSeq int64) error {
|
||||
var retErr error
|
||||
for {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return errs.Wrap(retErr, "SetMaxSeq redis retry too many amount")
|
||||
default:
|
||||
retErr = c.setSeq(ctx, conversationID, maxSeq, c.getMaxSeqKey)
|
||||
if retErr != nil {
|
||||
time.Sleep(time.Second * 2)
|
||||
continue
|
||||
}
|
||||
return nil
|
||||
}
|
||||
}
|
||||
return c.setSeq(ctx, conversationID, maxSeq, c.getMaxSeqKey)
|
||||
}
|
||||
|
||||
func (c *msgCache) GetMaxSeqs(ctx context.Context, conversationIDs []string) (m map[string]int64, err error) {
|
||||
@@ -194,21 +181,7 @@ func (c *msgCache) GetMaxSeqs(ctx context.Context, conversationIDs []string) (m
|
||||
}
|
||||
|
||||
func (c *msgCache) GetMaxSeq(ctx context.Context, conversationID string) (int64, error) {
|
||||
var retErr error
|
||||
var retData int64
|
||||
for {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return -1, errs.Wrap(retErr, "GetMaxSeq redis retry too many amount")
|
||||
default:
|
||||
retData, retErr = c.getSeq(ctx, conversationID, c.getMaxSeqKey)
|
||||
if retErr != nil && errs.Unwrap(retErr) != redis.Nil {
|
||||
time.Sleep(time.Second * 2)
|
||||
continue
|
||||
}
|
||||
return retData, retErr
|
||||
}
|
||||
}
|
||||
return c.getSeq(ctx, conversationID, c.getMaxSeqKey)
|
||||
}
|
||||
|
||||
func (c *msgCache) SetMinSeq(ctx context.Context, conversationID string, minSeq int64) error {
|
||||
@@ -314,7 +287,7 @@ func (c *msgCache) GetTokensWithoutError(ctx context.Context, userID string, pla
|
||||
|
||||
func (c *msgCache) SetTokenMapByUidPid(ctx context.Context, userID string, platform int, m map[string]int) error {
|
||||
key := uidPidToken + userID + ":" + constant.PlatformIDToName(platform)
|
||||
mm := make(map[string]interface{})
|
||||
mm := make(map[string]any)
|
||||
for k, v := range m {
|
||||
mm[k] = v
|
||||
}
|
||||
@@ -672,35 +645,19 @@ func (c *msgCache) PipeDeleteMessages(ctx context.Context, conversationID string
|
||||
}
|
||||
|
||||
func (c *msgCache) CleanUpOneConversationAllMsg(ctx context.Context, conversationID string) error {
|
||||
var (
|
||||
cursor uint64
|
||||
keys []string
|
||||
err error
|
||||
|
||||
key = c.allMessageCacheKey(conversationID)
|
||||
)
|
||||
|
||||
for {
|
||||
// scan up to 10000 at a time, the count (10000) param refers to the number of scans on redis server.
|
||||
// if the count is too small, needs to be run scan on redis frequently.
|
||||
var limit int64 = 10000
|
||||
keys, cursor, err = c.rdb.Scan(ctx, cursor, key, limit).Result()
|
||||
if err != nil {
|
||||
vals, err := c.rdb.Keys(ctx, c.allMessageCacheKey(conversationID)).Result()
|
||||
if errors.Is(err, redis.Nil) {
|
||||
return nil
|
||||
}
|
||||
if err != nil {
|
||||
return errs.Wrap(err)
|
||||
}
|
||||
for _, v := range vals {
|
||||
if err := c.rdb.Del(ctx, v).Err(); err != nil {
|
||||
return errs.Wrap(err)
|
||||
}
|
||||
|
||||
for _, key := range keys {
|
||||
err := c.rdb.Del(ctx, key).Err()
|
||||
if err != nil {
|
||||
return errs.Wrap(err)
|
||||
}
|
||||
}
|
||||
|
||||
// scan end
|
||||
if cursor == 0 {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *msgCache) DelMsgFromCache(ctx context.Context, userID string, seqs []int64) error {
|
||||
|
||||
Vendored
-47
@@ -385,50 +385,3 @@ func testParallelDeleteMessagesMix(t *testing.T, cid string, seqs []int64, input
|
||||
assert.EqualValues(t, 1, val) // exists
|
||||
}
|
||||
}
|
||||
|
||||
func TestCleanUpOneConversationAllMsg(t *testing.T) {
|
||||
rdb := redis.NewClient(&redis.Options{})
|
||||
defer rdb.Close()
|
||||
|
||||
cacher := msgCache{rdb: rdb}
|
||||
count := 1000
|
||||
prefix := fmt.Sprintf("%v", rand.Int63())
|
||||
|
||||
ids := []string{}
|
||||
for i := 0; i < count; i++ {
|
||||
id := fmt.Sprintf("%v-cid-%v", prefix, rand.Int63())
|
||||
ids = append(ids, id)
|
||||
|
||||
key := cacher.allMessageCacheKey(id)
|
||||
rdb.Set(context.Background(), key, "openim", 0)
|
||||
}
|
||||
|
||||
// delete 100 keys with scan.
|
||||
for i := 0; i < 100; i++ {
|
||||
pickedKey := ids[i]
|
||||
err := cacher.CleanUpOneConversationAllMsg(context.Background(), pickedKey)
|
||||
assert.Nil(t, err)
|
||||
|
||||
ls, err := rdb.Keys(context.Background(), pickedKey).Result()
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, 0, len(ls))
|
||||
|
||||
rcode, err := rdb.Exists(context.Background(), pickedKey).Result()
|
||||
assert.Nil(t, err)
|
||||
assert.EqualValues(t, 0, rcode) // non-exists
|
||||
}
|
||||
|
||||
sid := fmt.Sprintf("%v-cid-*", prefix)
|
||||
ls, err := rdb.Keys(context.Background(), cacher.allMessageCacheKey(sid)).Result()
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, count-100, len(ls))
|
||||
|
||||
// delete fuzzy matching keys.
|
||||
err = cacher.CleanUpOneConversationAllMsg(context.Background(), sid)
|
||||
assert.Nil(t, err)
|
||||
|
||||
// don't contains keys matched `{prefix}-cid-{random}` on redis
|
||||
ls, err = rdb.Keys(context.Background(), cacher.allMessageCacheKey(sid)).Result()
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, 0, len(ls))
|
||||
}
|
||||
|
||||
Vendored
+9
-9
@@ -14,8 +14,8 @@ import (
|
||||
|
||||
type ObjectCache interface {
|
||||
metaCache
|
||||
GetName(ctx context.Context, name string) (*relationtb.ObjectModel, error)
|
||||
DelObjectName(names ...string) ObjectCache
|
||||
GetName(ctx context.Context, engine string, name string) (*relationtb.ObjectModel, error)
|
||||
DelObjectName(engine string, names ...string) ObjectCache
|
||||
}
|
||||
|
||||
func NewObjectCacheRedis(rdb redis.UniversalClient, objDB relationtb.ObjectInfoModelInterface) ObjectCache {
|
||||
@@ -44,23 +44,23 @@ func (g *objectCacheRedis) NewCache() ObjectCache {
|
||||
}
|
||||
}
|
||||
|
||||
func (g *objectCacheRedis) DelObjectName(names ...string) ObjectCache {
|
||||
func (g *objectCacheRedis) DelObjectName(engine string, names ...string) ObjectCache {
|
||||
objectCache := g.NewCache()
|
||||
keys := make([]string, 0, len(names))
|
||||
for _, name := range names {
|
||||
keys = append(keys, g.getObjectKey(name))
|
||||
keys = append(keys, g.getObjectKey(name, engine))
|
||||
}
|
||||
objectCache.AddKeys(keys...)
|
||||
return objectCache
|
||||
}
|
||||
|
||||
func (g *objectCacheRedis) getObjectKey(name string) string {
|
||||
return "OBJECT:" + name
|
||||
func (g *objectCacheRedis) getObjectKey(engine string, name string) string {
|
||||
return "OBJECT:" + engine + ":" + name
|
||||
}
|
||||
|
||||
func (g *objectCacheRedis) GetName(ctx context.Context, name string) (*relationtb.ObjectModel, error) {
|
||||
return getCache(ctx, g.rcClient, g.getObjectKey(name), g.expireTime, func(ctx context.Context) (*relationtb.ObjectModel, error) {
|
||||
return g.objDB.Take(ctx, name)
|
||||
func (g *objectCacheRedis) GetName(ctx context.Context, engine string, name string) (*relationtb.ObjectModel, error) {
|
||||
return getCache(ctx, g.rcClient, g.getObjectKey(name, engine), g.expireTime, func(ctx context.Context) (*relationtb.ObjectModel, error) {
|
||||
return g.objDB.Take(ctx, engine, name)
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
Vendored
+8
-34
@@ -22,6 +22,8 @@ import (
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
relationtb "github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation"
|
||||
|
||||
"github.com/OpenIMSDK/tools/log"
|
||||
|
||||
"github.com/OpenIMSDK/protocol/constant"
|
||||
@@ -31,8 +33,6 @@ import (
|
||||
|
||||
"github.com/dtm-labs/rockscache"
|
||||
"github.com/redis/go-redis/v9"
|
||||
|
||||
relationtb "github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -59,7 +59,8 @@ type UserCache interface {
|
||||
|
||||
type UserCacheRedis struct {
|
||||
metaCache
|
||||
rdb redis.UniversalClient
|
||||
rdb redis.UniversalClient
|
||||
//userDB relationtb.UserModelInterface
|
||||
userDB relationtb.UserModelInterface
|
||||
expireTime time.Duration
|
||||
rcClient *rockscache.Client
|
||||
@@ -100,39 +101,13 @@ func (u *UserCacheRedis) getUserGlobalRecvMsgOptKey(userID string) string {
|
||||
}
|
||||
|
||||
func (u *UserCacheRedis) GetUserInfo(ctx context.Context, userID string) (userInfo *relationtb.UserModel, err error) {
|
||||
return getCache(
|
||||
ctx,
|
||||
u.rcClient,
|
||||
u.getUserInfoKey(userID),
|
||||
u.expireTime,
|
||||
func(ctx context.Context) (*relationtb.UserModel, error) {
|
||||
return u.userDB.Take(ctx, userID)
|
||||
},
|
||||
return getCache(ctx, u.rcClient, u.getUserInfoKey(userID), u.expireTime, func(ctx context.Context) (*relationtb.UserModel, error) {
|
||||
return u.userDB.Take(ctx, userID)
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
func (u *UserCacheRedis) GetUsersInfo(ctx context.Context, userIDs []string) ([]*relationtb.UserModel, error) {
|
||||
//var keys []string
|
||||
//for _, userID := range userIDs {
|
||||
// keys = append(keys, u.getUserInfoKey(userID))
|
||||
//}
|
||||
//return batchGetCache(
|
||||
// ctx,
|
||||
// u.rcClient,
|
||||
// keys,
|
||||
// u.expireTime,
|
||||
// func(user *relationtb.UserModel, keys []string) (int, error) {
|
||||
// for i, key := range keys {
|
||||
// if key == u.getUserInfoKey(user.UserID) {
|
||||
// return i, nil
|
||||
// }
|
||||
// }
|
||||
// return 0, errIndex
|
||||
// },
|
||||
// func(ctx context.Context) ([]*relationtb.UserModel, error) {
|
||||
// return u.userDB.Find(ctx, userIDs)
|
||||
// },
|
||||
//)
|
||||
return batchGetCache2(ctx, u.rcClient, u.expireTime, userIDs, func(userID string) string {
|
||||
return u.getUserInfoKey(userID)
|
||||
}, func(ctx context.Context, userID string) (*relationtb.UserModel, error) {
|
||||
@@ -214,8 +189,7 @@ func (u *UserCacheRedis) SetUserStatus(ctx context.Context, userID string, statu
|
||||
UserIDNum := crc32.ChecksumIEEE([]byte(userID))
|
||||
modKey := strconv.Itoa(int(UserIDNum % statusMod))
|
||||
key := olineStatusKey + modKey
|
||||
log.ZDebug(ctx, "SetUserStatus args", "userID", userID, "status", status,
|
||||
"platformID", platformID, "modKey", modKey, "key", key)
|
||||
log.ZDebug(ctx, "SetUserStatus args", "userID", userID, "status", status, "platformID", platformID, "modKey", modKey, "key", key)
|
||||
isNewKey, err := u.rdb.Exists(ctx, key).Result()
|
||||
if err != nil {
|
||||
return errs.Wrap(err)
|
||||
|
||||
@@ -17,6 +17,8 @@ package controller
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/OpenIMSDK/tools/pagination"
|
||||
|
||||
"github.com/OpenIMSDK/tools/log"
|
||||
"github.com/OpenIMSDK/tools/utils"
|
||||
|
||||
@@ -30,12 +32,7 @@ type BlackDatabase interface {
|
||||
// Delete 删除黑名单
|
||||
Delete(ctx context.Context, blacks []*relation.BlackModel) (err error)
|
||||
// FindOwnerBlacks 获取黑名单列表
|
||||
FindOwnerBlacks(
|
||||
ctx context.Context,
|
||||
ownerUserID string,
|
||||
pageNumber, showNumber int32,
|
||||
) (blacks []*relation.BlackModel, total int64, err error)
|
||||
FindBlackIDs(ctx context.Context, ownerUserID string) (blackIDs []string, err error)
|
||||
FindOwnerBlacks(ctx context.Context, ownerUserID string, pagination pagination.Pagination) (total int64, blacks []*relation.BlackModel, err error)
|
||||
FindBlackInfos(ctx context.Context, ownerUserID string, userIDs []string) (blacks []*relation.BlackModel, err error)
|
||||
// CheckIn 检查user2是否在user1的黑名单列表中(inUser1Blacks==true) 检查user1是否在user2的黑名单列表中(inUser2Blacks==true)
|
||||
CheckIn(ctx context.Context, userID1, userID2 string) (inUser1Blacks bool, inUser2Blacks bool, err error)
|
||||
@@ -75,12 +72,8 @@ func (b *blackDatabase) deleteBlackIDsCache(ctx context.Context, blacks []*relat
|
||||
}
|
||||
|
||||
// FindOwnerBlacks 获取黑名单列表.
|
||||
func (b *blackDatabase) FindOwnerBlacks(
|
||||
ctx context.Context,
|
||||
ownerUserID string,
|
||||
pageNumber, showNumber int32,
|
||||
) (blacks []*relation.BlackModel, total int64, err error) {
|
||||
return b.black.FindOwnerBlacks(ctx, ownerUserID, pageNumber, showNumber)
|
||||
func (b *blackDatabase) FindOwnerBlacks(ctx context.Context, ownerUserID string, pagination pagination.Pagination) (total int64, blacks []*relation.BlackModel, err error) {
|
||||
return b.black.FindOwnerBlacks(ctx, ownerUserID, pagination)
|
||||
}
|
||||
|
||||
// CheckIn 检查user2是否在user1的黑名单列表中(inUser1Blacks==true) 检查user1是否在user2的黑名单列表中(inUser2Blacks==true).
|
||||
|
||||
@@ -1,37 +0,0 @@
|
||||
// Copyright © 2023 OpenIM. All rights reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package controller
|
||||
|
||||
import (
|
||||
pbmsg "github.com/OpenIMSDK/protocol/msg"
|
||||
|
||||
relationtb "github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation"
|
||||
)
|
||||
|
||||
type ChatLogDatabase interface {
|
||||
CreateChatLog(msg *pbmsg.MsgDataToMQ) error
|
||||
}
|
||||
|
||||
func NewChatLogDatabase(chatLogModelInterface relationtb.ChatLogModelInterface) ChatLogDatabase {
|
||||
return &chatLogDatabase{chatLogModel: chatLogModelInterface}
|
||||
}
|
||||
|
||||
type chatLogDatabase struct {
|
||||
chatLogModel relationtb.ChatLogModelInterface
|
||||
}
|
||||
|
||||
func (c *chatLogDatabase) CreateChatLog(msg *pbmsg.MsgDataToMQ) error {
|
||||
return c.chatLogModel.Create(msg)
|
||||
}
|
||||
@@ -18,6 +18,8 @@ import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"github.com/OpenIMSDK/tools/pagination"
|
||||
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/msgprocessor"
|
||||
|
||||
"github.com/OpenIMSDK/protocol/constant"
|
||||
@@ -31,7 +33,7 @@ import (
|
||||
|
||||
type ConversationDatabase interface {
|
||||
// UpdateUserConversationFiled 更新用户该会话的属性信息
|
||||
UpdateUsersConversationFiled(ctx context.Context, userIDs []string, conversationID string, args map[string]interface{}) error
|
||||
UpdateUsersConversationFiled(ctx context.Context, userIDs []string, conversationID string, args map[string]any) error
|
||||
// CreateConversation 创建一批新的会话
|
||||
CreateConversation(ctx context.Context, conversations []*relationtb.ConversationModel) error
|
||||
// SyncPeerUserPrivateConversation 同步对端私聊会话内部保证事务操作
|
||||
@@ -39,26 +41,26 @@ type ConversationDatabase interface {
|
||||
// FindConversations 根据会话ID获取某个用户的多个会话
|
||||
FindConversations(ctx context.Context, ownerUserID string, conversationIDs []string) ([]*relationtb.ConversationModel, error)
|
||||
// FindRecvMsgNotNotifyUserIDs 获取超级大群开启免打扰的用户ID
|
||||
FindRecvMsgNotNotifyUserIDs(ctx context.Context, groupID string) ([]string, error)
|
||||
//FindRecvMsgNotNotifyUserIDs(ctx context.Context, groupID string) ([]string, error)
|
||||
// GetUserAllConversation 获取一个用户在服务器上所有的会话
|
||||
GetUserAllConversation(ctx context.Context, ownerUserID string) ([]*relationtb.ConversationModel, error)
|
||||
// SetUserConversations 设置用户多个会话属性,如果会话不存在则创建,否则更新,内部保证原子性
|
||||
SetUserConversations(ctx context.Context, ownerUserID string, conversations []*relationtb.ConversationModel) error
|
||||
// SetUsersConversationFiledTx 设置多个用户会话关于某个字段的更新操作,如果会话不存在则创建,否则更新,内部保证事务操作
|
||||
SetUsersConversationFiledTx(ctx context.Context, userIDs []string, conversation *relationtb.ConversationModel, filedMap map[string]interface{}) error
|
||||
SetUsersConversationFiledTx(ctx context.Context, userIDs []string, conversation *relationtb.ConversationModel, filedMap map[string]any) error
|
||||
CreateGroupChatConversation(ctx context.Context, groupID string, userIDs []string) error
|
||||
GetConversationIDs(ctx context.Context, userID string) ([]string, error)
|
||||
GetUserConversationIDsHash(ctx context.Context, ownerUserID string) (hash uint64, err error)
|
||||
GetAllConversationIDs(ctx context.Context) ([]string, error)
|
||||
GetAllConversationIDsNumber(ctx context.Context) (int64, error)
|
||||
PageConversationIDs(ctx context.Context, pageNumber, showNumber int32) (conversationIDs []string, err error)
|
||||
PageConversationIDs(ctx context.Context, pagination pagination.Pagination) (conversationIDs []string, err error)
|
||||
//GetUserAllHasReadSeqs(ctx context.Context, ownerUserID string) (map[string]int64, error)
|
||||
GetConversationsByConversationID(ctx context.Context, conversationIDs []string) ([]*relationtb.ConversationModel, error)
|
||||
GetConversationIDsNeedDestruct(ctx context.Context) ([]*relationtb.ConversationModel, error)
|
||||
GetConversationNotReceiveMessageUserIDs(ctx context.Context, conversationID string) ([]string, error)
|
||||
}
|
||||
|
||||
func NewConversationDatabase(conversation relationtb.ConversationModelInterface, cache cache.ConversationCache, tx tx.Tx) ConversationDatabase {
|
||||
func NewConversationDatabase(conversation relationtb.ConversationModelInterface, cache cache.ConversationCache, tx tx.CtxTx) ConversationDatabase {
|
||||
return &conversationDatabase{
|
||||
conversationDB: conversation,
|
||||
cache: cache,
|
||||
@@ -69,22 +71,21 @@ func NewConversationDatabase(conversation relationtb.ConversationModelInterface,
|
||||
type conversationDatabase struct {
|
||||
conversationDB relationtb.ConversationModelInterface
|
||||
cache cache.ConversationCache
|
||||
tx tx.Tx
|
||||
tx tx.CtxTx
|
||||
}
|
||||
|
||||
func (c *conversationDatabase) SetUsersConversationFiledTx(ctx context.Context, userIDs []string, conversation *relationtb.ConversationModel, filedMap map[string]interface{}) (err error) {
|
||||
cache := c.cache.NewCache()
|
||||
if conversation.GroupID != "" {
|
||||
cache = cache.DelSuperGroupRecvMsgNotNotifyUserIDs(conversation.GroupID).DelSuperGroupRecvMsgNotNotifyUserIDsHash(conversation.GroupID)
|
||||
}
|
||||
if err := c.tx.Transaction(func(tx any) error {
|
||||
conversationTx := c.conversationDB.NewTx(tx)
|
||||
haveUserIDs, err := conversationTx.FindUserID(ctx, userIDs, []string{conversation.ConversationID})
|
||||
func (c *conversationDatabase) SetUsersConversationFiledTx(ctx context.Context, userIDs []string, conversation *relationtb.ConversationModel, filedMap map[string]any) (err error) {
|
||||
return c.tx.Transaction(ctx, func(ctx context.Context) error {
|
||||
cache := c.cache.NewCache()
|
||||
if conversation.GroupID != "" {
|
||||
cache = cache.DelSuperGroupRecvMsgNotNotifyUserIDs(conversation.GroupID).DelSuperGroupRecvMsgNotNotifyUserIDsHash(conversation.GroupID)
|
||||
}
|
||||
haveUserIDs, err := c.conversationDB.FindUserID(ctx, userIDs, []string{conversation.ConversationID})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if len(haveUserIDs) > 0 {
|
||||
_, err = conversationTx.UpdateByMap(ctx, haveUserIDs, conversation.ConversationID, filedMap)
|
||||
_, err = c.conversationDB.UpdateByMap(ctx, haveUserIDs, conversation.ConversationID, filedMap)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -112,20 +113,17 @@ func (c *conversationDatabase) SetUsersConversationFiledTx(ctx context.Context,
|
||||
conversations = append(conversations, temp)
|
||||
}
|
||||
if len(conversations) > 0 {
|
||||
err = conversationTx.Create(ctx, conversations)
|
||||
err = c.conversationDB.Create(ctx, conversations)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
cache = cache.DelConversationIDs(NotUserIDs...).DelUserConversationIDsHash(NotUserIDs...).DelConversations(conversation.ConversationID, NotUserIDs...)
|
||||
}
|
||||
return nil
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
return cache.ExecDel(ctx)
|
||||
return cache.ExecDel(ctx)
|
||||
})
|
||||
}
|
||||
|
||||
func (c *conversationDatabase) UpdateUsersConversationFiled(ctx context.Context, userIDs []string, conversationID string, args map[string]interface{}) error {
|
||||
func (c *conversationDatabase) UpdateUsersConversationFiled(ctx context.Context, userIDs []string, conversationID string, args map[string]any) error {
|
||||
_, err := c.conversationDB.UpdateByMap(ctx, userIDs, conversationID, args)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -153,19 +151,18 @@ func (c *conversationDatabase) CreateConversation(ctx context.Context, conversat
|
||||
}
|
||||
|
||||
func (c *conversationDatabase) SyncPeerUserPrivateConversationTx(ctx context.Context, conversations []*relationtb.ConversationModel) error {
|
||||
cache := c.cache.NewCache()
|
||||
if err := c.tx.Transaction(func(tx any) error {
|
||||
conversationTx := c.conversationDB.NewTx(tx)
|
||||
return c.tx.Transaction(ctx, func(ctx context.Context) error {
|
||||
cache := c.cache.NewCache()
|
||||
for _, conversation := range conversations {
|
||||
for _, v := range [][2]string{{conversation.OwnerUserID, conversation.UserID}, {conversation.UserID, conversation.OwnerUserID}} {
|
||||
ownerUserID := v[0]
|
||||
userID := v[1]
|
||||
haveUserIDs, err := conversationTx.FindUserID(ctx, []string{ownerUserID}, []string{conversation.ConversationID})
|
||||
haveUserIDs, err := c.conversationDB.FindUserID(ctx, []string{ownerUserID}, []string{conversation.ConversationID})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if len(haveUserIDs) > 0 {
|
||||
_, err := conversationTx.UpdateByMap(ctx, []string{ownerUserID}, conversation.ConversationID, map[string]interface{}{"is_private_chat": conversation.IsPrivateChat})
|
||||
_, err := c.conversationDB.UpdateByMap(ctx, []string{ownerUserID}, conversation.ConversationID, map[string]any{"is_private_chat": conversation.IsPrivateChat})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -176,18 +173,15 @@ func (c *conversationDatabase) SyncPeerUserPrivateConversationTx(ctx context.Con
|
||||
newConversation.UserID = userID
|
||||
newConversation.ConversationID = conversation.ConversationID
|
||||
newConversation.IsPrivateChat = conversation.IsPrivateChat
|
||||
if err := conversationTx.Create(ctx, []*relationtb.ConversationModel{&newConversation}); err != nil {
|
||||
if err := c.conversationDB.Create(ctx, []*relationtb.ConversationModel{&newConversation}); err != nil {
|
||||
return err
|
||||
}
|
||||
cache = cache.DelConversationIDs(ownerUserID).DelUserConversationIDsHash(ownerUserID)
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
return cache.ExecDel(ctx)
|
||||
return cache.ExecDel(ctx)
|
||||
})
|
||||
}
|
||||
|
||||
func (c *conversationDatabase) FindConversations(ctx context.Context, ownerUserID string, conversationIDs []string) ([]*relationtb.ConversationModel, error) {
|
||||
@@ -203,28 +197,26 @@ func (c *conversationDatabase) GetUserAllConversation(ctx context.Context, owner
|
||||
}
|
||||
|
||||
func (c *conversationDatabase) SetUserConversations(ctx context.Context, ownerUserID string, conversations []*relationtb.ConversationModel) error {
|
||||
cache := c.cache.NewCache()
|
||||
|
||||
groupIDs := utils.Distinct(utils.Filter(conversations, func(e *relationtb.ConversationModel) (string, bool) {
|
||||
return e.GroupID, e.GroupID != ""
|
||||
}))
|
||||
for _, groupID := range groupIDs {
|
||||
cache = cache.DelSuperGroupRecvMsgNotNotifyUserIDs(groupID).DelSuperGroupRecvMsgNotNotifyUserIDsHash(groupID)
|
||||
}
|
||||
if err := c.tx.Transaction(func(tx any) error {
|
||||
return c.tx.Transaction(ctx, func(ctx context.Context) error {
|
||||
cache := c.cache.NewCache()
|
||||
groupIDs := utils.Distinct(utils.Filter(conversations, func(e *relationtb.ConversationModel) (string, bool) {
|
||||
return e.GroupID, e.GroupID != ""
|
||||
}))
|
||||
for _, groupID := range groupIDs {
|
||||
cache = cache.DelSuperGroupRecvMsgNotNotifyUserIDs(groupID).DelSuperGroupRecvMsgNotNotifyUserIDsHash(groupID)
|
||||
}
|
||||
var conversationIDs []string
|
||||
for _, conversation := range conversations {
|
||||
conversationIDs = append(conversationIDs, conversation.ConversationID)
|
||||
cache = cache.DelConversations(conversation.OwnerUserID, conversation.ConversationID)
|
||||
}
|
||||
conversationTx := c.conversationDB.NewTx(tx)
|
||||
existConversations, err := conversationTx.Find(ctx, ownerUserID, conversationIDs)
|
||||
existConversations, err := c.conversationDB.Find(ctx, ownerUserID, conversationIDs)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if len(existConversations) > 0 {
|
||||
for _, conversation := range conversations {
|
||||
err = conversationTx.Update(ctx, conversation)
|
||||
err = c.conversationDB.Update(ctx, conversation)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -246,23 +238,22 @@ func (c *conversationDatabase) SetUserConversations(ctx context.Context, ownerUs
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
cache = cache.DelConversationIDs(ownerUserID).DelUserConversationIDsHash(ownerUserID).DelConversationNotReceiveMessageUserIDs(utils.Slice(notExistConversations, func(e *relationtb.ConversationModel) string { return e.ConversationID })...)
|
||||
cache = cache.DelConversationIDs(ownerUserID).
|
||||
DelUserConversationIDsHash(ownerUserID).
|
||||
DelConversationNotReceiveMessageUserIDs(utils.Slice(notExistConversations, func(e *relationtb.ConversationModel) string { return e.ConversationID })...)
|
||||
}
|
||||
return nil
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
return cache.ExecDel(ctx)
|
||||
return cache.ExecDel(ctx)
|
||||
})
|
||||
}
|
||||
|
||||
func (c *conversationDatabase) FindRecvMsgNotNotifyUserIDs(ctx context.Context, groupID string) ([]string, error) {
|
||||
return c.cache.GetSuperGroupRecvMsgNotNotifyUserIDs(ctx, groupID)
|
||||
}
|
||||
//func (c *conversationDatabase) FindRecvMsgNotNotifyUserIDs(ctx context.Context, groupID string) ([]string, error) {
|
||||
// return c.cache.GetSuperGroupRecvMsgNotNotifyUserIDs(ctx, groupID)
|
||||
//}
|
||||
|
||||
func (c *conversationDatabase) CreateGroupChatConversation(ctx context.Context, groupID string, userIDs []string) error {
|
||||
cache := c.cache.NewCache()
|
||||
conversationID := msgprocessor.GetConversationIDBySessionType(constant.SuperGroupChatType, groupID)
|
||||
if err := c.tx.Transaction(func(tx any) error {
|
||||
return c.tx.Transaction(ctx, func(ctx context.Context) error {
|
||||
cache := c.cache.NewCache()
|
||||
conversationID := msgprocessor.GetConversationIDBySessionType(constant.SuperGroupChatType, groupID)
|
||||
existConversationUserIDs, err := c.conversationDB.FindUserID(ctx, userIDs, []string{conversationID})
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -281,18 +272,15 @@ func (c *conversationDatabase) CreateGroupChatConversation(ctx context.Context,
|
||||
return err
|
||||
}
|
||||
}
|
||||
_, err = c.conversationDB.UpdateByMap(ctx, existConversationUserIDs, conversationID, map[string]interface{}{"max_seq": 0})
|
||||
_, err = c.conversationDB.UpdateByMap(ctx, existConversationUserIDs, conversationID, map[string]any{"max_seq": 0})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, v := range existConversationUserIDs {
|
||||
cache = cache.DelConversations(v, conversationID)
|
||||
}
|
||||
return nil
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
return cache.ExecDel(ctx)
|
||||
return c.cache.ExecDel(ctx)
|
||||
})
|
||||
}
|
||||
|
||||
func (c *conversationDatabase) GetConversationIDs(ctx context.Context, userID string) ([]string, error) {
|
||||
@@ -311,14 +299,10 @@ func (c *conversationDatabase) GetAllConversationIDsNumber(ctx context.Context)
|
||||
return c.conversationDB.GetAllConversationIDsNumber(ctx)
|
||||
}
|
||||
|
||||
func (c *conversationDatabase) PageConversationIDs(ctx context.Context, pageNumber, showNumber int32) ([]string, error) {
|
||||
return c.conversationDB.PageConversationIDs(ctx, pageNumber, showNumber)
|
||||
func (c *conversationDatabase) PageConversationIDs(ctx context.Context, pagination pagination.Pagination) ([]string, error) {
|
||||
return c.conversationDB.PageConversationIDs(ctx, pagination)
|
||||
}
|
||||
|
||||
//func (c *conversationDatabase) GetUserAllHasReadSeqs(ctx context.Context, ownerUserID string) (map[string]int64, error) {
|
||||
// return c.cache.GetUserAllHasReadSeqs(ctx, ownerUserID)
|
||||
//}
|
||||
|
||||
func (c *conversationDatabase) GetConversationsByConversationID(ctx context.Context, conversationIDs []string) ([]*relationtb.ConversationModel, error) {
|
||||
return c.conversationDB.GetConversationsByConversationID(ctx, conversationIDs)
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"gorm.io/gorm"
|
||||
"github.com/OpenIMSDK/tools/pagination"
|
||||
|
||||
"github.com/OpenIMSDK/protocol/constant"
|
||||
"github.com/OpenIMSDK/tools/errs"
|
||||
@@ -47,35 +47,15 @@ type FriendDatabase interface {
|
||||
// 更新好友备注
|
||||
UpdateRemark(ctx context.Context, ownerUserID, friendUserID, remark string) (err error)
|
||||
// 获取ownerUserID的好友列表
|
||||
PageOwnerFriends(
|
||||
ctx context.Context,
|
||||
ownerUserID string,
|
||||
pageNumber, showNumber int32,
|
||||
) (friends []*relation.FriendModel, total int64, err error)
|
||||
PageOwnerFriends(ctx context.Context, ownerUserID string, pagination pagination.Pagination) (total int64, friends []*relation.FriendModel, err error)
|
||||
// friendUserID在哪些人的好友列表中
|
||||
PageInWhoseFriends(
|
||||
ctx context.Context,
|
||||
friendUserID string,
|
||||
pageNumber, showNumber int32,
|
||||
) (friends []*relation.FriendModel, total int64, err error)
|
||||
PageInWhoseFriends(ctx context.Context, friendUserID string, pagination pagination.Pagination) (total int64, friends []*relation.FriendModel, err error)
|
||||
// 获取我发出去的好友申请
|
||||
PageFriendRequestFromMe(
|
||||
ctx context.Context,
|
||||
userID string,
|
||||
pageNumber, showNumber int32,
|
||||
) (friends []*relation.FriendRequestModel, total int64, err error)
|
||||
PageFriendRequestFromMe(ctx context.Context, userID string, pagination pagination.Pagination) (total int64, friends []*relation.FriendRequestModel, err error)
|
||||
// 获取我收到的的好友申请
|
||||
PageFriendRequestToMe(
|
||||
ctx context.Context,
|
||||
userID string,
|
||||
pageNumber, showNumber int32,
|
||||
) (friends []*relation.FriendRequestModel, total int64, err error)
|
||||
PageFriendRequestToMe(ctx context.Context, userID string, pagination pagination.Pagination) (total int64, friends []*relation.FriendRequestModel, err error)
|
||||
// 获取某人指定好友的信息
|
||||
FindFriendsWithError(
|
||||
ctx context.Context,
|
||||
ownerUserID string,
|
||||
friendUserIDs []string,
|
||||
) (friends []*relation.FriendModel, err error)
|
||||
FindFriendsWithError(ctx context.Context, ownerUserID string, friendUserIDs []string) (friends []*relation.FriendModel, err error)
|
||||
FindFriendUserIDs(ctx context.Context, ownerUserID string) (friendUserIDs []string, err error)
|
||||
FindBothFriendRequests(ctx context.Context, fromUserID, toUserID string) (friends []*relation.FriendRequestModel, err error)
|
||||
}
|
||||
@@ -83,24 +63,16 @@ type FriendDatabase interface {
|
||||
type friendDatabase struct {
|
||||
friend relation.FriendModelInterface
|
||||
friendRequest relation.FriendRequestModelInterface
|
||||
tx tx.Tx
|
||||
tx tx.CtxTx
|
||||
cache cache.FriendCache
|
||||
}
|
||||
|
||||
func NewFriendDatabase(
|
||||
friend relation.FriendModelInterface,
|
||||
friendRequest relation.FriendRequestModelInterface,
|
||||
cache cache.FriendCache,
|
||||
tx tx.Tx,
|
||||
) FriendDatabase {
|
||||
func NewFriendDatabase(friend relation.FriendModelInterface, friendRequest relation.FriendRequestModelInterface, cache cache.FriendCache, tx tx.CtxTx) FriendDatabase {
|
||||
return &friendDatabase{friend: friend, friendRequest: friendRequest, cache: cache, tx: tx}
|
||||
}
|
||||
|
||||
// ok 检查user2是否在user1的好友列表中(inUser1Friends==true) 检查user1是否在user2的好友列表中(inUser2Friends==true).
|
||||
func (f *friendDatabase) CheckIn(
|
||||
ctx context.Context,
|
||||
userID1, userID2 string,
|
||||
) (inUser1Friends bool, inUser2Friends bool, err error) {
|
||||
func (f *friendDatabase) CheckIn(ctx context.Context, userID1, userID2 string) (inUser1Friends bool, inUser2Friends bool, err error) {
|
||||
userID1FriendIDs, err := f.cache.GetFriendIDs(ctx, userID1)
|
||||
if err != nil {
|
||||
return
|
||||
@@ -113,50 +85,35 @@ func (f *friendDatabase) CheckIn(
|
||||
}
|
||||
|
||||
// 增加或者更新好友申请 如果之前有记录则更新,没有记录则新增.
|
||||
func (f *friendDatabase) AddFriendRequest(
|
||||
ctx context.Context,
|
||||
fromUserID, toUserID string,
|
||||
reqMsg string,
|
||||
ex string,
|
||||
) (err error) {
|
||||
return f.tx.Transaction(func(tx any) error {
|
||||
_, err := f.friendRequest.NewTx(tx).Take(ctx, fromUserID, toUserID)
|
||||
// 有db错误
|
||||
if err != nil && errs.Unwrap(err) != gorm.ErrRecordNotFound {
|
||||
return err
|
||||
}
|
||||
// 无错误 则更新
|
||||
if err == nil {
|
||||
m := make(map[string]interface{}, 1)
|
||||
func (f *friendDatabase) AddFriendRequest(ctx context.Context, fromUserID, toUserID string, reqMsg string, ex string) (err error) {
|
||||
return f.tx.Transaction(ctx, func(ctx context.Context) error {
|
||||
_, err := f.friendRequest.Take(ctx, fromUserID, toUserID)
|
||||
switch {
|
||||
case err == nil:
|
||||
m := make(map[string]any, 1)
|
||||
m["handle_result"] = 0
|
||||
m["handle_msg"] = ""
|
||||
m["req_msg"] = reqMsg
|
||||
m["ex"] = ex
|
||||
m["create_time"] = time.Now()
|
||||
if err := f.friendRequest.NewTx(tx).UpdateByMap(ctx, fromUserID, toUserID, m); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
// gorm.ErrRecordNotFound 错误,则新增
|
||||
if err := f.friendRequest.NewTx(tx).Create(ctx, []*relation.FriendRequestModel{{FromUserID: fromUserID, ToUserID: toUserID, ReqMsg: reqMsg, Ex: ex, CreateTime: time.Now(), HandleTime: time.Unix(0, 0)}}); err != nil {
|
||||
return f.friendRequest.UpdateByMap(ctx, fromUserID, toUserID, m)
|
||||
case relation.IsNotFound(err):
|
||||
return f.friendRequest.Create(
|
||||
ctx,
|
||||
[]*relation.FriendRequestModel{{FromUserID: fromUserID, ToUserID: toUserID, ReqMsg: reqMsg, Ex: ex, CreateTime: time.Now(), HandleTime: time.Unix(0, 0)}},
|
||||
)
|
||||
default:
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
// (1)先判断是否在好友表 (在不在都不返回错误) (2)对于不在好友列表的 插入即可.
|
||||
func (f *friendDatabase) BecomeFriends(
|
||||
ctx context.Context,
|
||||
ownerUserID string,
|
||||
friendUserIDs []string,
|
||||
addSource int32,
|
||||
) (err error) {
|
||||
cache := f.cache.NewCache()
|
||||
if err := f.tx.Transaction(func(tx any) error {
|
||||
func (f *friendDatabase) BecomeFriends(ctx context.Context, ownerUserID string, friendUserIDs []string, addSource int32) (err error) {
|
||||
return f.tx.Transaction(ctx, func(ctx context.Context) error {
|
||||
cache := f.cache.NewCache()
|
||||
// 先find 找出重复的 去掉重复的
|
||||
fs1, err := f.friend.NewTx(tx).FindFriends(ctx, ownerUserID, friendUserIDs)
|
||||
fs1, err := f.friend.FindFriends(ctx, ownerUserID, friendUserIDs)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -168,11 +125,11 @@ func (f *friendDatabase) BecomeFriends(
|
||||
return e.FriendUserID
|
||||
})
|
||||
|
||||
err = f.friend.NewTx(tx).Create(ctx, fs11)
|
||||
err = f.friend.Create(ctx, fs11)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
fs2, err := f.friend.NewTx(tx).FindReversalFriends(ctx, ownerUserID, friendUserIDs)
|
||||
fs2, err := f.friend.FindReversalFriends(ctx, ownerUserID, friendUserIDs)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -184,24 +141,19 @@ func (f *friendDatabase) BecomeFriends(
|
||||
fs22 := utils.DistinctAny(fs2, func(e *relation.FriendModel) string {
|
||||
return e.OwnerUserID
|
||||
})
|
||||
err = f.friend.NewTx(tx).Create(ctx, fs22)
|
||||
err = f.friend.Create(ctx, fs22)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
newFriendIDs = append(newFriendIDs, ownerUserID)
|
||||
cache = cache.DelFriendIDs(newFriendIDs...)
|
||||
return nil
|
||||
}); err != nil {
|
||||
return nil
|
||||
}
|
||||
return cache.ExecDel(ctx)
|
||||
return cache.ExecDel(ctx)
|
||||
|
||||
})
|
||||
}
|
||||
|
||||
// 拒绝好友申请 (1)检查是否有申请记录且为未处理状态 (没有记录返回错误) (2)修改申请记录 已拒绝.
|
||||
func (f *friendDatabase) RefuseFriendRequest(
|
||||
ctx context.Context,
|
||||
friendRequest *relation.FriendRequestModel,
|
||||
) (err error) {
|
||||
func (f *friendDatabase) RefuseFriendRequest(ctx context.Context, friendRequest *relation.FriendRequestModel) (err error) {
|
||||
fr, err := f.friendRequest.Take(ctx, friendRequest.FromUserID, friendRequest.ToUserID)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -220,14 +172,11 @@ func (f *friendDatabase) RefuseFriendRequest(
|
||||
}
|
||||
|
||||
// AgreeFriendRequest 同意好友申请 (1)检查是否有申请记录且为未处理状态 (没有记录返回错误) (2)检查是否好友(不返回错误) (3) 建立双向好友关系(存在的忽略).
|
||||
func (f *friendDatabase) AgreeFriendRequest(
|
||||
ctx context.Context,
|
||||
friendRequest *relation.FriendRequestModel,
|
||||
) (err error) {
|
||||
return f.tx.Transaction(func(tx any) error {
|
||||
func (f *friendDatabase) AgreeFriendRequest(ctx context.Context, friendRequest *relation.FriendRequestModel) (err error) {
|
||||
return f.tx.Transaction(ctx, func(ctx context.Context) error {
|
||||
defer log.ZDebug(ctx, "return line")
|
||||
now := time.Now()
|
||||
fr, err := f.friendRequest.NewTx(tx).Take(ctx, friendRequest.FromUserID, friendRequest.ToUserID)
|
||||
fr, err := f.friendRequest.Take(ctx, friendRequest.FromUserID, friendRequest.ToUserID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -237,25 +186,25 @@ func (f *friendDatabase) AgreeFriendRequest(
|
||||
friendRequest.HandlerUserID = mcontext.GetOpUserID(ctx)
|
||||
friendRequest.HandleResult = constant.FriendResponseAgree
|
||||
friendRequest.HandleTime = now
|
||||
err = f.friendRequest.NewTx(tx).Update(ctx, friendRequest)
|
||||
err = f.friendRequest.Update(ctx, friendRequest)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
fr2, err := f.friendRequest.NewTx(tx).Take(ctx, friendRequest.ToUserID, friendRequest.FromUserID)
|
||||
fr2, err := f.friendRequest.Take(ctx, friendRequest.ToUserID, friendRequest.FromUserID)
|
||||
if err == nil && fr2.HandleResult == constant.FriendResponseNotHandle {
|
||||
fr2.HandlerUserID = mcontext.GetOpUserID(ctx)
|
||||
fr2.HandleResult = constant.FriendResponseAgree
|
||||
fr2.HandleTime = now
|
||||
err = f.friendRequest.NewTx(tx).Update(ctx, fr2)
|
||||
err = f.friendRequest.Update(ctx, fr2)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
} else if err != nil && errs.Unwrap(err) != gorm.ErrRecordNotFound {
|
||||
} else if err != nil && (!relation.IsNotFound(err)) {
|
||||
return err
|
||||
}
|
||||
|
||||
exists, err := f.friend.NewTx(tx).FindUserState(ctx, friendRequest.FromUserID, friendRequest.ToUserID)
|
||||
exists, err := f.friend.FindUserState(ctx, friendRequest.FromUserID, friendRequest.ToUserID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -286,7 +235,7 @@ func (f *friendDatabase) AgreeFriendRequest(
|
||||
)
|
||||
}
|
||||
if len(adds) > 0 {
|
||||
if err := f.friend.NewTx(tx).Create(ctx, adds); err != nil {
|
||||
if err := f.friend.Create(ctx, adds); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
@@ -311,47 +260,27 @@ func (f *friendDatabase) UpdateRemark(ctx context.Context, ownerUserID, friendUs
|
||||
}
|
||||
|
||||
// 获取ownerUserID的好友列表 无结果不返回错误.
|
||||
func (f *friendDatabase) PageOwnerFriends(
|
||||
ctx context.Context,
|
||||
ownerUserID string,
|
||||
pageNumber, showNumber int32,
|
||||
) (friends []*relation.FriendModel, total int64, err error) {
|
||||
return f.friend.FindOwnerFriends(ctx, ownerUserID, pageNumber, showNumber)
|
||||
func (f *friendDatabase) PageOwnerFriends(ctx context.Context, ownerUserID string, pagination pagination.Pagination) (total int64, friends []*relation.FriendModel, err error) {
|
||||
return f.friend.FindOwnerFriends(ctx, ownerUserID, pagination)
|
||||
}
|
||||
|
||||
// friendUserID在哪些人的好友列表中.
|
||||
func (f *friendDatabase) PageInWhoseFriends(
|
||||
ctx context.Context,
|
||||
friendUserID string,
|
||||
pageNumber, showNumber int32,
|
||||
) (friends []*relation.FriendModel, total int64, err error) {
|
||||
return f.friend.FindInWhoseFriends(ctx, friendUserID, pageNumber, showNumber)
|
||||
func (f *friendDatabase) PageInWhoseFriends(ctx context.Context, friendUserID string, pagination pagination.Pagination) (total int64, friends []*relation.FriendModel, err error) {
|
||||
return f.friend.FindInWhoseFriends(ctx, friendUserID, pagination)
|
||||
}
|
||||
|
||||
// 获取我发出去的好友申请 无结果不返回错误.
|
||||
func (f *friendDatabase) PageFriendRequestFromMe(
|
||||
ctx context.Context,
|
||||
userID string,
|
||||
pageNumber, showNumber int32,
|
||||
) (friends []*relation.FriendRequestModel, total int64, err error) {
|
||||
return f.friendRequest.FindFromUserID(ctx, userID, pageNumber, showNumber)
|
||||
func (f *friendDatabase) PageFriendRequestFromMe(ctx context.Context, userID string, pagination pagination.Pagination) (total int64, friends []*relation.FriendRequestModel, err error) {
|
||||
return f.friendRequest.FindFromUserID(ctx, userID, pagination)
|
||||
}
|
||||
|
||||
// 获取我收到的的好友申请 无结果不返回错误.
|
||||
func (f *friendDatabase) PageFriendRequestToMe(
|
||||
ctx context.Context,
|
||||
userID string,
|
||||
pageNumber, showNumber int32,
|
||||
) (friends []*relation.FriendRequestModel, total int64, err error) {
|
||||
return f.friendRequest.FindToUserID(ctx, userID, pageNumber, showNumber)
|
||||
func (f *friendDatabase) PageFriendRequestToMe(ctx context.Context, userID string, pagination pagination.Pagination) (total int64, friends []*relation.FriendRequestModel, err error) {
|
||||
return f.friendRequest.FindToUserID(ctx, userID, pagination)
|
||||
}
|
||||
|
||||
// 获取某人指定好友的信息 如果有好友不存在,也返回错误.
|
||||
func (f *friendDatabase) FindFriendsWithError(
|
||||
ctx context.Context,
|
||||
ownerUserID string,
|
||||
friendUserIDs []string,
|
||||
) (friends []*relation.FriendModel, err error) {
|
||||
func (f *friendDatabase) FindFriendsWithError(ctx context.Context, ownerUserID string, friendUserIDs []string) (friends []*relation.FriendModel, err error) {
|
||||
friends, err = f.friend.FindFriends(ctx, ownerUserID, friendUserIDs)
|
||||
if err != nil {
|
||||
return
|
||||
@@ -362,10 +291,7 @@ func (f *friendDatabase) FindFriendsWithError(
|
||||
return
|
||||
}
|
||||
|
||||
func (f *friendDatabase) FindFriendUserIDs(
|
||||
ctx context.Context,
|
||||
ownerUserID string,
|
||||
) (friendUserIDs []string, err error) {
|
||||
func (f *friendDatabase) FindFriendUserIDs(ctx context.Context, ownerUserID string) (friendUserIDs []string, err error) {
|
||||
return f.cache.GetFriendIDs(ctx, ownerUserID)
|
||||
}
|
||||
|
||||
|
||||
+157
-318
@@ -16,23 +16,18 @@ package controller
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/OpenIMSDK/tools/pagination"
|
||||
"github.com/dtm-labs/rockscache"
|
||||
"github.com/redis/go-redis/v9"
|
||||
"go.mongodb.org/mongo-driver/mongo"
|
||||
"gorm.io/gorm"
|
||||
|
||||
"github.com/OpenIMSDK/protocol/constant"
|
||||
"github.com/OpenIMSDK/tools/tx"
|
||||
"github.com/OpenIMSDK/tools/utils"
|
||||
"github.com/redis/go-redis/v9"
|
||||
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/common/db/cache"
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/common/db/relation"
|
||||
relationtb "github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation"
|
||||
unrelationtb "github.com/openimsdk/open-im-server/v3/pkg/common/db/table/unrelation"
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/common/db/unrelation"
|
||||
)
|
||||
|
||||
type GroupDatabase interface {
|
||||
@@ -40,23 +35,26 @@ type GroupDatabase interface {
|
||||
CreateGroup(ctx context.Context, groups []*relationtb.GroupModel, groupMembers []*relationtb.GroupMemberModel) error
|
||||
TakeGroup(ctx context.Context, groupID string) (group *relationtb.GroupModel, err error)
|
||||
FindGroup(ctx context.Context, groupIDs []string) (groups []*relationtb.GroupModel, err error)
|
||||
FindNotDismissedGroup(ctx context.Context, groupIDs []string) (groups []*relationtb.GroupModel, err error)
|
||||
SearchGroup(ctx context.Context, keyword string, pageNumber, showNumber int32) (uint32, []*relationtb.GroupModel, error)
|
||||
SearchGroup(ctx context.Context, keyword string, pagination pagination.Pagination) (int64, []*relationtb.GroupModel, error)
|
||||
UpdateGroup(ctx context.Context, groupID string, data map[string]any) error
|
||||
DismissGroup(ctx context.Context, groupID string, deleteMember bool) error // 解散群,并删除群成员
|
||||
GetGroupIDsByGroupType(ctx context.Context, groupType int) (groupIDs []string, err error)
|
||||
// GroupMember
|
||||
|
||||
TakeGroupMember(ctx context.Context, groupID string, userID string) (groupMember *relationtb.GroupMemberModel, err error)
|
||||
TakeGroupOwner(ctx context.Context, groupID string) (*relationtb.GroupMemberModel, error)
|
||||
FindGroupMember(ctx context.Context, groupIDs []string, userIDs []string, roleLevels []int32) ([]*relationtb.GroupMemberModel, error)
|
||||
FindGroupMembers(ctx context.Context, groupID string, userIDs []string) (groupMembers []*relationtb.GroupMemberModel, err error) // *
|
||||
FindGroupMemberUser(ctx context.Context, groupIDs []string, userID string) (groupMembers []*relationtb.GroupMemberModel, err error) // *
|
||||
FindGroupMemberRoleLevels(ctx context.Context, groupID string, roleLevels []int32) (groupMembers []*relationtb.GroupMemberModel, err error) // *
|
||||
FindGroupMemberAll(ctx context.Context, groupID string) (groupMembers []*relationtb.GroupMemberModel, err error) // *
|
||||
FindGroupsOwner(ctx context.Context, groupIDs []string) ([]*relationtb.GroupMemberModel, error)
|
||||
FindGroupMemberUserID(ctx context.Context, groupID string) ([]string, error)
|
||||
FindGroupMemberNum(ctx context.Context, groupID string) (uint32, error)
|
||||
FindUserManagedGroupID(ctx context.Context, userID string) (groupIDs []string, err error)
|
||||
PageGroupRequest(ctx context.Context, groupIDs []string, pageNumber, showNumber int32) (uint32, []*relationtb.GroupRequestModel, error)
|
||||
PageGroupRequest(ctx context.Context, groupIDs []string, pagination pagination.Pagination) (int64, []*relationtb.GroupRequestModel, error)
|
||||
GetGroupRoleLevelMemberIDs(ctx context.Context, groupID string, roleLevel int32) ([]string, error)
|
||||
|
||||
PageGetJoinGroup(ctx context.Context, userID string, pageNumber, showNumber int32) (total uint32, totalGroupMembers []*relationtb.GroupMemberModel, err error)
|
||||
PageGetGroupMember(ctx context.Context, groupID string, pageNumber, showNumber int32) (total uint32, totalGroupMembers []*relationtb.GroupMemberModel, err error)
|
||||
SearchGroupMember(ctx context.Context, keyword string, groupIDs []string, userIDs []string, roleLevels []int32, pageNumber, showNumber int32) (uint32, []*relationtb.GroupMemberModel, error)
|
||||
PageGetJoinGroup(ctx context.Context, userID string, pagination pagination.Pagination) (total int64, totalGroupMembers []*relationtb.GroupMemberModel, err error)
|
||||
PageGetGroupMember(ctx context.Context, groupID string, pagination pagination.Pagination) (total int64, totalGroupMembers []*relationtb.GroupMemberModel, err error)
|
||||
SearchGroupMember(ctx context.Context, keyword string, groupID string, pagination pagination.Pagination) (int64, []*relationtb.GroupMemberModel, error)
|
||||
HandlerGroupRequest(ctx context.Context, groupID string, userID string, handledMsg string, handleResult int32, member *relationtb.GroupMemberModel) error
|
||||
DeleteGroupMember(ctx context.Context, groupID string, userIDs []string) error
|
||||
MapGroupMemberUserID(ctx context.Context, groupIDs []string) (map[string]*relationtb.GroupSimpleUserID, error)
|
||||
@@ -67,15 +65,8 @@ type GroupDatabase interface {
|
||||
// GroupRequest
|
||||
CreateGroupRequest(ctx context.Context, requests []*relationtb.GroupRequestModel) error
|
||||
TakeGroupRequest(ctx context.Context, groupID string, userID string) (*relationtb.GroupRequestModel, error)
|
||||
FindGroupRequests(ctx context.Context, groupID string, userIDs []string) (int64, []*relationtb.GroupRequestModel, error)
|
||||
PageGroupRequestUser(ctx context.Context, userID string, pageNumber, showNumber int32) (uint32, []*relationtb.GroupRequestModel, error)
|
||||
// SuperGroupModelInterface
|
||||
FindSuperGroup(ctx context.Context, groupIDs []string) ([]*unrelationtb.SuperGroupModel, error)
|
||||
FindJoinSuperGroup(ctx context.Context, userID string) ([]string, error)
|
||||
CreateSuperGroup(ctx context.Context, groupID string, initMemberIDList []string) error
|
||||
DeleteSuperGroup(ctx context.Context, groupID string) error
|
||||
DeleteSuperGroupMember(ctx context.Context, groupID string, userIDs []string) error
|
||||
CreateSuperGroupMember(ctx context.Context, groupID string, userIDs []string) error
|
||||
FindGroupRequests(ctx context.Context, groupID string, userIDs []string) ([]*relationtb.GroupRequestModel, error)
|
||||
PageGroupRequestUser(ctx context.Context, userID string, pagination pagination.Pagination) (int64, []*relationtb.GroupRequestModel, error)
|
||||
|
||||
// 获取群总数
|
||||
CountTotal(ctx context.Context, before *time.Time) (count int64, err error)
|
||||
@@ -85,61 +76,91 @@ type GroupDatabase interface {
|
||||
}
|
||||
|
||||
func NewGroupDatabase(
|
||||
group relationtb.GroupModelInterface,
|
||||
member relationtb.GroupMemberModelInterface,
|
||||
request relationtb.GroupRequestModelInterface,
|
||||
tx tx.Tx,
|
||||
rdb redis.UniversalClient,
|
||||
groupDB relationtb.GroupModelInterface,
|
||||
groupMemberDB relationtb.GroupMemberModelInterface,
|
||||
groupRequestDB relationtb.GroupRequestModelInterface,
|
||||
ctxTx tx.CtxTx,
|
||||
superGroup unrelationtb.SuperGroupModelInterface,
|
||||
cache cache.GroupCache,
|
||||
groupHash cache.GroupHash,
|
||||
) GroupDatabase {
|
||||
database := &groupDatabase{
|
||||
groupDB: group,
|
||||
groupMemberDB: member,
|
||||
groupRequestDB: request,
|
||||
tx: tx,
|
||||
ctxTx: ctxTx,
|
||||
cache: cache,
|
||||
mongoDB: superGroup,
|
||||
}
|
||||
return database
|
||||
}
|
||||
|
||||
func InitGroupDatabase(db *gorm.DB, rdb redis.UniversalClient, database *mongo.Database, hashCode func(ctx context.Context, groupID string) (uint64, error)) GroupDatabase {
|
||||
rcOptions := rockscache.NewDefaultOptions()
|
||||
rcOptions.StrongConsistency = true
|
||||
rcOptions.RandomExpireAdjustment = 0.2
|
||||
return NewGroupDatabase(
|
||||
relation.NewGroupDB(db),
|
||||
relation.NewGroupMemberDB(db),
|
||||
relation.NewGroupRequest(db),
|
||||
tx.NewGorm(db),
|
||||
tx.NewMongo(database.Client()),
|
||||
unrelation.NewSuperGroupMongoDriver(database),
|
||||
cache.NewGroupCacheRedis(
|
||||
rdb,
|
||||
relation.NewGroupDB(db),
|
||||
relation.NewGroupMemberDB(db),
|
||||
relation.NewGroupRequest(db),
|
||||
unrelation.NewSuperGroupMongoDriver(database),
|
||||
hashCode,
|
||||
rcOptions,
|
||||
),
|
||||
)
|
||||
return &groupDatabase{
|
||||
groupDB: groupDB,
|
||||
groupMemberDB: groupMemberDB,
|
||||
groupRequestDB: groupRequestDB,
|
||||
ctxTx: ctxTx,
|
||||
cache: cache.NewGroupCacheRedis(rdb, groupDB, groupMemberDB, groupRequestDB, groupHash, rcOptions),
|
||||
}
|
||||
}
|
||||
|
||||
type groupDatabase struct {
|
||||
groupDB relationtb.GroupModelInterface
|
||||
groupMemberDB relationtb.GroupMemberModelInterface
|
||||
groupRequestDB relationtb.GroupRequestModelInterface
|
||||
tx tx.Tx
|
||||
ctxTx tx.CtxTx
|
||||
cache cache.GroupCache
|
||||
mongoDB unrelationtb.SuperGroupModelInterface
|
||||
}
|
||||
|
||||
func (g *groupDatabase) GetGroupIDsByGroupType(ctx context.Context, groupType int) (groupIDs []string, err error) {
|
||||
return g.groupDB.GetGroupIDsByGroupType(ctx, groupType)
|
||||
func (g *groupDatabase) FindGroupMembers(ctx context.Context, groupID string, userIDs []string) ([]*relationtb.GroupMemberModel, error) {
|
||||
return g.cache.GetGroupMembersInfo(ctx, groupID, userIDs)
|
||||
}
|
||||
|
||||
func (g *groupDatabase) FindGroupMemberUser(ctx context.Context, groupIDs []string, userID string) ([]*relationtb.GroupMemberModel, error) {
|
||||
return g.cache.FindGroupMemberUser(ctx, groupIDs, userID)
|
||||
}
|
||||
|
||||
func (g *groupDatabase) FindGroupMemberRoleLevels(ctx context.Context, groupID string, roleLevels []int32) ([]*relationtb.GroupMemberModel, error) {
|
||||
return g.cache.GetGroupRolesLevelMemberInfo(ctx, groupID, roleLevels)
|
||||
}
|
||||
|
||||
func (g *groupDatabase) FindGroupMemberAll(ctx context.Context, groupID string) ([]*relationtb.GroupMemberModel, error) {
|
||||
return g.cache.GetAllGroupMembersInfo(ctx, groupID)
|
||||
}
|
||||
|
||||
func (g *groupDatabase) FindGroupsOwner(ctx context.Context, groupIDs []string) ([]*relationtb.GroupMemberModel, error) {
|
||||
return g.cache.GetGroupsOwner(ctx, groupIDs)
|
||||
}
|
||||
|
||||
func (g *groupDatabase) GetGroupRoleLevelMemberIDs(ctx context.Context, groupID string, roleLevel int32) ([]string, error) {
|
||||
return g.cache.GetGroupRoleLevelMemberIDs(ctx, groupID, roleLevel)
|
||||
}
|
||||
|
||||
func (g *groupDatabase) CreateGroup(ctx context.Context, groups []*relationtb.GroupModel, groupMembers []*relationtb.GroupMemberModel) error {
|
||||
if len(groups)+len(groupMembers) == 0 {
|
||||
return nil
|
||||
}
|
||||
return g.ctxTx.Transaction(ctx, func(ctx context.Context) error {
|
||||
c := g.cache.NewCache()
|
||||
if len(groups) > 0 {
|
||||
if err := g.groupDB.Create(ctx, groups); err != nil {
|
||||
return err
|
||||
}
|
||||
for _, group := range groups {
|
||||
c = c.DelGroupsInfo(group.GroupID).
|
||||
DelGroupMembersHash(group.GroupID).
|
||||
DelGroupMembersHash(group.GroupID).
|
||||
DelGroupsMemberNum(group.GroupID).
|
||||
DelGroupMemberIDs(group.GroupID).
|
||||
DelGroupAllRoleLevel(group.GroupID)
|
||||
}
|
||||
}
|
||||
if len(groupMembers) > 0 {
|
||||
if err := g.groupMemberDB.Create(ctx, groupMembers); err != nil {
|
||||
return err
|
||||
}
|
||||
for _, groupMember := range groupMembers {
|
||||
c = c.DelGroupMembersHash(groupMember.GroupID).
|
||||
DelGroupsMemberNum(groupMember.GroupID).
|
||||
DelGroupMemberIDs(groupMember.GroupID).
|
||||
DelJoinedGroupID(groupMember.UserID).
|
||||
DelGroupMembersInfo(groupMember.GroupID, groupMember.UserID).
|
||||
DelGroupAllRoleLevel(groupMember.GroupID)
|
||||
}
|
||||
}
|
||||
return c.ExecDel(ctx, true)
|
||||
})
|
||||
}
|
||||
|
||||
func (g *groupDatabase) FindGroupMemberUserID(ctx context.Context, groupID string) ([]string, error) {
|
||||
@@ -154,57 +175,16 @@ func (g *groupDatabase) FindGroupMemberNum(ctx context.Context, groupID string)
|
||||
return uint32(num), nil
|
||||
}
|
||||
|
||||
func (g *groupDatabase) CreateGroup(
|
||||
ctx context.Context,
|
||||
groups []*relationtb.GroupModel,
|
||||
groupMembers []*relationtb.GroupMemberModel,
|
||||
) error {
|
||||
cache := g.cache.NewCache()
|
||||
if err := g.tx.Transaction(func(tx any) error {
|
||||
if len(groups) > 0 {
|
||||
if err := g.groupDB.NewTx(tx).Create(ctx, groups); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if len(groupMembers) > 0 {
|
||||
if err := g.groupMemberDB.NewTx(tx).Create(ctx, groupMembers); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
createGroupIDs := utils.DistinctAnyGetComparable(groups, func(group *relationtb.GroupModel) string {
|
||||
return group.GroupID
|
||||
})
|
||||
m := make(map[string]struct{})
|
||||
|
||||
for _, groupMember := range groupMembers {
|
||||
if _, ok := m[groupMember.GroupID]; !ok {
|
||||
m[groupMember.GroupID] = struct{}{}
|
||||
cache = cache.DelGroupMemberIDs(groupMember.GroupID).DelGroupMembersHash(groupMember.GroupID).DelGroupsMemberNum(groupMember.GroupID)
|
||||
}
|
||||
cache = cache.DelJoinedGroupID(groupMember.UserID).DelGroupMembersInfo(groupMember.GroupID, groupMember.UserID)
|
||||
}
|
||||
cache = cache.DelGroupsInfo(createGroupIDs...)
|
||||
return nil
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
return cache.ExecDel(ctx)
|
||||
}
|
||||
|
||||
func (g *groupDatabase) TakeGroup(ctx context.Context, groupID string) (group *relationtb.GroupModel, err error) {
|
||||
func (g *groupDatabase) TakeGroup(ctx context.Context, groupID string) (*relationtb.GroupModel, error) {
|
||||
return g.cache.GetGroupInfo(ctx, groupID)
|
||||
}
|
||||
|
||||
func (g *groupDatabase) FindGroup(ctx context.Context, groupIDs []string) (groups []*relationtb.GroupModel, err error) {
|
||||
func (g *groupDatabase) FindGroup(ctx context.Context, groupIDs []string) ([]*relationtb.GroupModel, error) {
|
||||
return g.cache.GetGroupsInfo(ctx, groupIDs)
|
||||
}
|
||||
|
||||
func (g *groupDatabase) SearchGroup(
|
||||
ctx context.Context,
|
||||
keyword string,
|
||||
pageNumber, showNumber int32,
|
||||
) (uint32, []*relationtb.GroupModel, error) {
|
||||
return g.groupDB.Search(ctx, keyword, pageNumber, showNumber)
|
||||
func (g *groupDatabase) SearchGroup(ctx context.Context, keyword string, pagination pagination.Pagination) (int64, []*relationtb.GroupModel, error) {
|
||||
return g.groupDB.Search(ctx, keyword, pagination)
|
||||
}
|
||||
|
||||
func (g *groupDatabase) UpdateGroup(ctx context.Context, groupID string, data map[string]any) error {
|
||||
@@ -215,166 +195,97 @@ func (g *groupDatabase) UpdateGroup(ctx context.Context, groupID string, data ma
|
||||
}
|
||||
|
||||
func (g *groupDatabase) DismissGroup(ctx context.Context, groupID string, deleteMember bool) error {
|
||||
cache := g.cache.NewCache()
|
||||
if err := g.tx.Transaction(func(tx any) error {
|
||||
if err := g.groupDB.NewTx(tx).UpdateStatus(ctx, groupID, constant.GroupStatusDismissed); err != nil {
|
||||
return g.ctxTx.Transaction(ctx, func(ctx context.Context) error {
|
||||
c := g.cache.NewCache()
|
||||
if err := g.groupDB.UpdateState(ctx, groupID, constant.GroupStatusDismissed); err != nil {
|
||||
return err
|
||||
}
|
||||
if deleteMember {
|
||||
if err := g.groupMemberDB.NewTx(tx).DeleteGroup(ctx, []string{groupID}); err != nil {
|
||||
return err
|
||||
}
|
||||
userIDs, err := g.cache.GetGroupMemberIDs(ctx, groupID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
cache = cache.DelJoinedGroupID(userIDs...).DelGroupMemberIDs(groupID).DelGroupsMemberNum(groupID).DelGroupMembersHash(groupID)
|
||||
if err := g.groupMemberDB.Delete(ctx, groupID, nil); err != nil {
|
||||
return err
|
||||
}
|
||||
c = c.DelJoinedGroupID(userIDs...).
|
||||
DelGroupMemberIDs(groupID).
|
||||
DelGroupsMemberNum(groupID).
|
||||
DelGroupMembersHash(groupID).
|
||||
DelGroupAllRoleLevel(groupID).
|
||||
DelGroupMembersInfo(groupID, userIDs...)
|
||||
}
|
||||
cache = cache.DelGroupsInfo(groupID)
|
||||
return nil
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
return cache.ExecDel(ctx)
|
||||
return c.DelGroupsInfo(groupID).ExecDel(ctx)
|
||||
})
|
||||
}
|
||||
|
||||
func (g *groupDatabase) TakeGroupMember(
|
||||
ctx context.Context,
|
||||
groupID string,
|
||||
userID string,
|
||||
) (groupMember *relationtb.GroupMemberModel, err error) {
|
||||
func (g *groupDatabase) TakeGroupMember(ctx context.Context, groupID string, userID string) (*relationtb.GroupMemberModel, error) {
|
||||
return g.cache.GetGroupMemberInfo(ctx, groupID, userID)
|
||||
}
|
||||
|
||||
func (g *groupDatabase) TakeGroupOwner(ctx context.Context, groupID string) (*relationtb.GroupMemberModel, error) {
|
||||
return g.groupMemberDB.TakeOwner(ctx, groupID) // todo cache group owner
|
||||
return g.cache.GetGroupOwner(ctx, groupID)
|
||||
}
|
||||
|
||||
func (g *groupDatabase) FindUserManagedGroupID(ctx context.Context, userID string) (groupIDs []string, err error) {
|
||||
return g.groupMemberDB.FindUserManagedGroupID(ctx, userID)
|
||||
}
|
||||
|
||||
func (g *groupDatabase) PageGroupRequest(
|
||||
ctx context.Context,
|
||||
groupIDs []string,
|
||||
pageNumber, showNumber int32,
|
||||
) (uint32, []*relationtb.GroupRequestModel, error) {
|
||||
return g.groupRequestDB.PageGroup(ctx, groupIDs, pageNumber, showNumber)
|
||||
func (g *groupDatabase) PageGroupRequest(ctx context.Context, groupIDs []string, pagination pagination.Pagination) (int64, []*relationtb.GroupRequestModel, error) {
|
||||
return g.groupRequestDB.PageGroup(ctx, groupIDs, pagination)
|
||||
}
|
||||
|
||||
func (g *groupDatabase) FindGroupMember(ctx context.Context, groupIDs []string, userIDs []string, roleLevels []int32) (totalGroupMembers []*relationtb.GroupMemberModel, err error) {
|
||||
if len(groupIDs) == 0 && len(roleLevels) == 0 && len(userIDs) == 1 {
|
||||
gIDs, err := g.cache.GetJoinedGroupIDs(ctx, userIDs[0])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var res []*relationtb.GroupMemberModel
|
||||
for _, groupID := range gIDs {
|
||||
v, err := g.cache.GetGroupMemberInfo(ctx, groupID, userIDs[0])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
res = append(res, v)
|
||||
}
|
||||
return res, nil
|
||||
}
|
||||
if len(roleLevels) == 0 {
|
||||
for _, groupID := range groupIDs {
|
||||
groupMembers, err := g.cache.GetGroupMembersInfo(ctx, groupID, userIDs)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
totalGroupMembers = append(totalGroupMembers, groupMembers...)
|
||||
}
|
||||
return totalGroupMembers, nil
|
||||
}
|
||||
return g.groupMemberDB.Find(ctx, groupIDs, userIDs, roleLevels)
|
||||
}
|
||||
|
||||
func (g *groupDatabase) PageGetJoinGroup(
|
||||
ctx context.Context,
|
||||
userID string,
|
||||
pageNumber, showNumber int32,
|
||||
) (total uint32, totalGroupMembers []*relationtb.GroupMemberModel, err error) {
|
||||
func (g *groupDatabase) PageGetJoinGroup(ctx context.Context, userID string, pagination pagination.Pagination) (total int64, totalGroupMembers []*relationtb.GroupMemberModel, err error) {
|
||||
groupIDs, err := g.cache.GetJoinedGroupIDs(ctx, userID)
|
||||
if err != nil {
|
||||
return 0, nil, err
|
||||
}
|
||||
for _, groupID := range utils.Paginate(groupIDs, int(pageNumber), int(showNumber)) {
|
||||
for _, groupID := range utils.Paginate(groupIDs, int(pagination.GetPageNumber()), int(pagination.GetShowNumber())) {
|
||||
groupMembers, err := g.cache.GetGroupMembersInfo(ctx, groupID, []string{userID})
|
||||
if err != nil {
|
||||
return 0, nil, err
|
||||
}
|
||||
totalGroupMembers = append(totalGroupMembers, groupMembers...)
|
||||
}
|
||||
return uint32(len(groupIDs)), totalGroupMembers, nil
|
||||
return int64(len(groupIDs)), totalGroupMembers, nil
|
||||
}
|
||||
|
||||
func (g *groupDatabase) PageGetGroupMember(
|
||||
ctx context.Context,
|
||||
groupID string,
|
||||
pageNumber, showNumber int32,
|
||||
) (total uint32, totalGroupMembers []*relationtb.GroupMemberModel, err error) {
|
||||
func (g *groupDatabase) PageGetGroupMember(ctx context.Context, groupID string, pagination pagination.Pagination) (total int64, totalGroupMembers []*relationtb.GroupMemberModel, err error) {
|
||||
groupMemberIDs, err := g.cache.GetGroupMemberIDs(ctx, groupID)
|
||||
if err != nil {
|
||||
return 0, nil, err
|
||||
}
|
||||
pageIDs := utils.Paginate(groupMemberIDs, int(pageNumber), int(showNumber))
|
||||
pageIDs := utils.Paginate(groupMemberIDs, int(pagination.GetPageNumber()), int(pagination.GetShowNumber()))
|
||||
if len(pageIDs) == 0 {
|
||||
return uint32(len(groupMemberIDs)), nil, nil
|
||||
return int64(len(groupMemberIDs)), nil, nil
|
||||
}
|
||||
members, err := g.cache.GetGroupMembersInfo(ctx, groupID, pageIDs)
|
||||
if err != nil {
|
||||
return 0, nil, err
|
||||
}
|
||||
return uint32(len(groupMemberIDs)), members, nil
|
||||
return int64(len(groupMemberIDs)), members, nil
|
||||
}
|
||||
|
||||
func (g *groupDatabase) SearchGroupMember(
|
||||
ctx context.Context,
|
||||
keyword string,
|
||||
groupIDs []string,
|
||||
userIDs []string,
|
||||
roleLevels []int32,
|
||||
pageNumber, showNumber int32,
|
||||
) (uint32, []*relationtb.GroupMemberModel, error) {
|
||||
return g.groupMemberDB.SearchMember(ctx, keyword, groupIDs, userIDs, roleLevels, pageNumber, showNumber)
|
||||
func (g *groupDatabase) SearchGroupMember(ctx context.Context, keyword string, groupID string, pagination pagination.Pagination) (int64, []*relationtb.GroupMemberModel, error) {
|
||||
return g.groupMemberDB.SearchMember(ctx, keyword, groupID, pagination)
|
||||
}
|
||||
|
||||
func (g *groupDatabase) HandlerGroupRequest(
|
||||
ctx context.Context,
|
||||
groupID string,
|
||||
userID string,
|
||||
handledMsg string,
|
||||
handleResult int32,
|
||||
member *relationtb.GroupMemberModel,
|
||||
) error {
|
||||
//cache := g.cache.NewCache()
|
||||
//if err := g.tx.Transaction(func(tx any) error {
|
||||
// if err := g.groupRequestDB.NewTx(tx).UpdateHandler(ctx, groupID, userID, handledMsg, handleResult); err != nil {
|
||||
// return err
|
||||
// }
|
||||
// if member != nil {
|
||||
// if err := g.groupMemberDB.NewTx(tx).Create(ctx, []*relationtb.GroupMemberModel{member}); err != nil {
|
||||
// return err
|
||||
// }
|
||||
// cache = cache.DelGroupMembersHash(groupID).DelGroupMemberIDs(groupID).DelGroupsMemberNum(groupID).DelJoinedGroupID(member.UserID)
|
||||
// }
|
||||
// return nil
|
||||
//}); err != nil {
|
||||
// return err
|
||||
//}
|
||||
//return cache.ExecDel(ctx)
|
||||
|
||||
return g.tx.Transaction(func(tx any) error {
|
||||
if err := g.groupRequestDB.NewTx(tx).UpdateHandler(ctx, groupID, userID, handledMsg, handleResult); err != nil {
|
||||
func (g *groupDatabase) HandlerGroupRequest(ctx context.Context, groupID string, userID string, handledMsg string, handleResult int32, member *relationtb.GroupMemberModel) error {
|
||||
return g.ctxTx.Transaction(ctx, func(ctx context.Context) error {
|
||||
if err := g.groupRequestDB.UpdateHandler(ctx, groupID, userID, handledMsg, handleResult); err != nil {
|
||||
return err
|
||||
}
|
||||
if member != nil {
|
||||
if err := g.groupMemberDB.NewTx(tx).Create(ctx, []*relationtb.GroupMemberModel{member}); err != nil {
|
||||
if err := g.groupMemberDB.Create(ctx, []*relationtb.GroupMemberModel{member}); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := g.cache.NewCache().DelGroupMembersHash(groupID).DelGroupMembersInfo(groupID, member.UserID).DelGroupMemberIDs(groupID).DelGroupsMemberNum(groupID).DelJoinedGroupID(member.UserID).ExecDel(ctx); err != nil {
|
||||
c := g.cache.DelGroupMembersHash(groupID).
|
||||
DelGroupMembersInfo(groupID, member.UserID).
|
||||
DelGroupMemberIDs(groupID).
|
||||
DelGroupsMemberNum(groupID).
|
||||
DelJoinedGroupID(member.UserID).
|
||||
DelGroupRoleLevel(groupID, []int32{member.RoleLevel})
|
||||
if err := c.ExecDel(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
@@ -391,13 +302,11 @@ func (g *groupDatabase) DeleteGroupMember(ctx context.Context, groupID string, u
|
||||
DelGroupsMemberNum(groupID).
|
||||
DelJoinedGroupID(userIDs...).
|
||||
DelGroupMembersInfo(groupID, userIDs...).
|
||||
DelGroupAllRoleLevel(groupID).
|
||||
ExecDel(ctx)
|
||||
}
|
||||
|
||||
func (g *groupDatabase) MapGroupMemberUserID(
|
||||
ctx context.Context,
|
||||
groupIDs []string,
|
||||
) (map[string]*relationtb.GroupSimpleUserID, error) {
|
||||
func (g *groupDatabase) MapGroupMemberUserID(ctx context.Context, groupIDs []string) (map[string]*relationtb.GroupSimpleUserID, error) {
|
||||
return g.cache.GetGroupMemberHashMap(ctx, groupIDs)
|
||||
}
|
||||
|
||||
@@ -414,62 +323,54 @@ func (g *groupDatabase) MapGroupMemberNum(ctx context.Context, groupIDs []string
|
||||
}
|
||||
|
||||
func (g *groupDatabase) TransferGroupOwner(ctx context.Context, groupID string, oldOwnerUserID, newOwnerUserID string, roleLevel int32) error {
|
||||
return g.tx.Transaction(func(tx any) error {
|
||||
rowsAffected, err := g.groupMemberDB.NewTx(tx).UpdateRoleLevel(ctx, groupID, oldOwnerUserID, roleLevel)
|
||||
if err != nil {
|
||||
return g.ctxTx.Transaction(ctx, func(ctx context.Context) error {
|
||||
if err := g.groupMemberDB.UpdateRoleLevel(ctx, groupID, oldOwnerUserID, roleLevel); err != nil {
|
||||
return err
|
||||
}
|
||||
if rowsAffected != 1 {
|
||||
return utils.Wrap(fmt.Errorf("oldOwnerUserID %s rowsAffected = %d", oldOwnerUserID, rowsAffected), "")
|
||||
}
|
||||
rowsAffected, err = g.groupMemberDB.NewTx(tx).UpdateRoleLevel(ctx, groupID, newOwnerUserID, constant.GroupOwner)
|
||||
if err != nil {
|
||||
if err := g.groupMemberDB.UpdateRoleLevel(ctx, groupID, newOwnerUserID, constant.GroupOwner); err != nil {
|
||||
return err
|
||||
}
|
||||
if rowsAffected != 1 {
|
||||
return utils.Wrap(fmt.Errorf("newOwnerUserID %s rowsAffected = %d", newOwnerUserID, rowsAffected), "")
|
||||
}
|
||||
return g.cache.DelGroupMembersInfo(groupID, oldOwnerUserID, newOwnerUserID).DelGroupMembersHash(groupID).ExecDel(ctx)
|
||||
return g.cache.DelGroupMembersInfo(groupID, oldOwnerUserID, newOwnerUserID).
|
||||
DelGroupAllRoleLevel(groupID).
|
||||
DelGroupMembersHash(groupID).ExecDel(ctx)
|
||||
})
|
||||
}
|
||||
|
||||
func (g *groupDatabase) UpdateGroupMember(
|
||||
ctx context.Context,
|
||||
groupID string,
|
||||
userID string,
|
||||
data map[string]any,
|
||||
) error {
|
||||
func (g *groupDatabase) UpdateGroupMember(ctx context.Context, groupID string, userID string, data map[string]any) error {
|
||||
if err := g.groupMemberDB.Update(ctx, groupID, userID, data); err != nil {
|
||||
return err
|
||||
}
|
||||
return g.cache.DelGroupMembersInfo(groupID, userID).ExecDel(ctx)
|
||||
c := g.cache.DelGroupMembersInfo(groupID, userID)
|
||||
if g.groupMemberDB.IsUpdateRoleLevel(data) {
|
||||
c = c.DelGroupAllRoleLevel(groupID)
|
||||
}
|
||||
return c.ExecDel(ctx)
|
||||
}
|
||||
|
||||
func (g *groupDatabase) UpdateGroupMembers(ctx context.Context, data []*relationtb.BatchUpdateGroupMember) error {
|
||||
cache := g.cache.NewCache()
|
||||
if err := g.tx.Transaction(func(tx any) error {
|
||||
return g.ctxTx.Transaction(ctx, func(ctx context.Context) error {
|
||||
c := g.cache.NewCache()
|
||||
for _, item := range data {
|
||||
if err := g.groupMemberDB.NewTx(tx).Update(ctx, item.GroupID, item.UserID, item.Map); err != nil {
|
||||
if err := g.groupMemberDB.Update(ctx, item.GroupID, item.UserID, item.Map); err != nil {
|
||||
return err
|
||||
}
|
||||
cache = cache.DelGroupMembersInfo(item.GroupID, item.UserID)
|
||||
if g.groupMemberDB.IsUpdateRoleLevel(item.Map) {
|
||||
c = c.DelGroupAllRoleLevel(item.GroupID)
|
||||
}
|
||||
c = c.DelGroupMembersInfo(item.GroupID, item.UserID).DelGroupMembersHash(item.GroupID)
|
||||
}
|
||||
return nil
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
return cache.ExecDel(ctx)
|
||||
return c.ExecDel(ctx, true)
|
||||
})
|
||||
}
|
||||
|
||||
func (g *groupDatabase) CreateGroupRequest(ctx context.Context, requests []*relationtb.GroupRequestModel) error {
|
||||
return g.tx.Transaction(func(tx any) error {
|
||||
db := g.groupRequestDB.NewTx(tx)
|
||||
return g.ctxTx.Transaction(ctx, func(ctx context.Context) error {
|
||||
for _, request := range requests {
|
||||
if err := db.Delete(ctx, request.GroupID, request.UserID); err != nil {
|
||||
if err := g.groupRequestDB.Delete(ctx, request.GroupID, request.UserID); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return db.Create(ctx, requests)
|
||||
return g.groupRequestDB.Create(ctx, requests)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -481,65 +382,8 @@ func (g *groupDatabase) TakeGroupRequest(
|
||||
return g.groupRequestDB.Take(ctx, groupID, userID)
|
||||
}
|
||||
|
||||
func (g *groupDatabase) PageGroupRequestUser(
|
||||
ctx context.Context,
|
||||
userID string,
|
||||
pageNumber, showNumber int32,
|
||||
) (uint32, []*relationtb.GroupRequestModel, error) {
|
||||
return g.groupRequestDB.Page(ctx, userID, pageNumber, showNumber)
|
||||
}
|
||||
|
||||
func (g *groupDatabase) FindSuperGroup(
|
||||
ctx context.Context,
|
||||
groupIDs []string,
|
||||
) (models []*unrelationtb.SuperGroupModel, err error) {
|
||||
return g.cache.GetSuperGroupMemberIDs(ctx, groupIDs...)
|
||||
}
|
||||
|
||||
func (g *groupDatabase) FindJoinSuperGroup(ctx context.Context, userID string) ([]string, error) {
|
||||
return g.cache.GetJoinedSuperGroupIDs(ctx, userID)
|
||||
}
|
||||
|
||||
func (g *groupDatabase) CreateSuperGroup(ctx context.Context, groupID string, initMemberIDs []string) error {
|
||||
if err := g.mongoDB.CreateSuperGroup(ctx, groupID, initMemberIDs); err != nil {
|
||||
return err
|
||||
}
|
||||
return g.cache.DelSuperGroupMemberIDs(groupID).DelJoinedSuperGroupIDs(initMemberIDs...).ExecDel(ctx)
|
||||
}
|
||||
|
||||
func (g *groupDatabase) DeleteSuperGroup(ctx context.Context, groupID string) error {
|
||||
cache := g.cache.NewCache()
|
||||
if err := g.ctxTx.Transaction(ctx, func(ctx context.Context) error {
|
||||
if err := g.mongoDB.DeleteSuperGroup(ctx, groupID); err != nil {
|
||||
return err
|
||||
}
|
||||
models, err := g.cache.GetSuperGroupMemberIDs(ctx, groupID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
cache = cache.DelSuperGroupMemberIDs(groupID)
|
||||
if len(models) > 0 {
|
||||
cache = cache.DelJoinedSuperGroupIDs(models[0].MemberIDs...)
|
||||
}
|
||||
return nil
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
return cache.ExecDel(ctx)
|
||||
}
|
||||
|
||||
func (g *groupDatabase) DeleteSuperGroupMember(ctx context.Context, groupID string, userIDs []string) error {
|
||||
if err := g.mongoDB.RemoverUserFromSuperGroup(ctx, groupID, userIDs); err != nil {
|
||||
return err
|
||||
}
|
||||
return g.cache.DelSuperGroupMemberIDs(groupID).DelJoinedSuperGroupIDs(userIDs...).ExecDel(ctx)
|
||||
}
|
||||
|
||||
func (g *groupDatabase) CreateSuperGroupMember(ctx context.Context, groupID string, userIDs []string) error {
|
||||
if err := g.mongoDB.AddUserToSuperGroup(ctx, groupID, userIDs); err != nil {
|
||||
return err
|
||||
}
|
||||
return g.cache.DelSuperGroupMemberIDs(groupID).DelJoinedSuperGroupIDs(userIDs...).ExecDel(ctx)
|
||||
func (g *groupDatabase) PageGroupRequestUser(ctx context.Context, userID string, pagination pagination.Pagination) (int64, []*relationtb.GroupRequestModel, error) {
|
||||
return g.groupRequestDB.Page(ctx, userID, pagination)
|
||||
}
|
||||
|
||||
func (g *groupDatabase) CountTotal(ctx context.Context, before *time.Time) (count int64, err error) {
|
||||
@@ -550,14 +394,10 @@ func (g *groupDatabase) CountRangeEverydayTotal(ctx context.Context, start time.
|
||||
return g.groupDB.CountRangeEverydayTotal(ctx, start, end)
|
||||
}
|
||||
|
||||
func (g *groupDatabase) FindGroupRequests(ctx context.Context, groupID string, userIDs []string) (int64, []*relationtb.GroupRequestModel, error) {
|
||||
func (g *groupDatabase) FindGroupRequests(ctx context.Context, groupID string, userIDs []string) ([]*relationtb.GroupRequestModel, error) {
|
||||
return g.groupRequestDB.FindGroupRequests(ctx, groupID, userIDs)
|
||||
}
|
||||
|
||||
func (g *groupDatabase) FindNotDismissedGroup(ctx context.Context, groupIDs []string) (groups []*relationtb.GroupModel, err error) {
|
||||
return g.groupDB.FindNotDismissedGroup(ctx, groupIDs)
|
||||
}
|
||||
|
||||
func (g *groupDatabase) DeleteGroupMemberHash(ctx context.Context, groupIDs []string) error {
|
||||
if len(groupIDs) == 0 {
|
||||
return nil
|
||||
@@ -566,6 +406,5 @@ func (g *groupDatabase) DeleteGroupMemberHash(ctx context.Context, groupIDs []st
|
||||
for _, groupID := range groupIDs {
|
||||
c = c.DelGroupMembersHash(groupID)
|
||||
}
|
||||
|
||||
return c.ExecDel(ctx)
|
||||
}
|
||||
|
||||
@@ -357,9 +357,7 @@ func (db *commonMsgDatabase) DelUserDeleteMsgsList(ctx context.Context, conversa
|
||||
}
|
||||
|
||||
func (db *commonMsgDatabase) BatchInsertChat2Cache(ctx context.Context, conversationID string, msgs []*sdkws.MsgData) (seq int64, isNew bool, err error) {
|
||||
cancelCtx, cancel := context.WithTimeout(ctx, 1*time.Minute)
|
||||
defer cancel()
|
||||
currentMaxSeq, err := db.cache.GetMaxSeq(cancelCtx, conversationID)
|
||||
currentMaxSeq, err := db.cache.GetMaxSeq(ctx, conversationID)
|
||||
if err != nil && errs.Unwrap(err) != redis.Nil {
|
||||
log.ZError(ctx, "db.cache.GetMaxSeq", err)
|
||||
return 0, false, err
|
||||
@@ -386,21 +384,19 @@ func (db *commonMsgDatabase) BatchInsertChat2Cache(ctx context.Context, conversa
|
||||
prommetrics.MsgInsertRedisFailedCounter.Add(float64(failedNum))
|
||||
log.ZError(ctx, "setMessageToCache error", err, "len", len(msgs), "conversationID", conversationID)
|
||||
} else {
|
||||
prommetrics.MsgInsertRedisSuccessCounter.Add(float64(len(msgs)))
|
||||
prommetrics.MsgInsertRedisSuccessCounter.Inc()
|
||||
}
|
||||
cancelCtx, cancel = context.WithTimeout(ctx, 1*time.Minute)
|
||||
defer cancel()
|
||||
err = db.cache.SetMaxSeq(cancelCtx, conversationID, currentMaxSeq)
|
||||
err = db.cache.SetMaxSeq(ctx, conversationID, currentMaxSeq)
|
||||
if err != nil {
|
||||
log.ZError(ctx, "db.cache.SetMaxSeq error", err, "conversationID", conversationID)
|
||||
prommetrics.SeqSetFailedCounter.Inc()
|
||||
}
|
||||
err2 := db.cache.SetHasReadSeqs(ctx, conversationID, userSeqMap)
|
||||
if err2 != nil {
|
||||
if err != nil {
|
||||
log.ZError(ctx, "SetHasReadSeqs error", err2, "userSeqMap", userSeqMap, "conversationID", conversationID)
|
||||
prommetrics.SeqSetFailedCounter.Inc()
|
||||
}
|
||||
return lastMaxSeq, isNew, errs.Wrap(err, "redis SetMaxSeq error")
|
||||
return lastMaxSeq, isNew, utils.Wrap(err, "")
|
||||
}
|
||||
|
||||
func (db *commonMsgDatabase) getMsgBySeqs(ctx context.Context, userID, conversationID string, seqs []int64) (totalMsgs []*sdkws.MsgData, err error) {
|
||||
@@ -658,26 +654,16 @@ func (db *commonMsgDatabase) GetMsgBySeqsRange(ctx context.Context, userID strin
|
||||
|
||||
func (db *commonMsgDatabase) GetMsgBySeqs(ctx context.Context, userID string, conversationID string, seqs []int64) (int64, int64, []*sdkws.MsgData, error) {
|
||||
userMinSeq, err := db.cache.GetConversationUserMinSeq(ctx, conversationID, userID)
|
||||
if err != nil {
|
||||
log.ZError(ctx, "cache.GetConversationUserMinSeq error", err)
|
||||
if errs.Unwrap(err) != redis.Nil {
|
||||
return 0, 0, nil, err
|
||||
}
|
||||
if err != nil && errs.Unwrap(err) != redis.Nil {
|
||||
return 0, 0, nil, err
|
||||
}
|
||||
minSeq, err := db.cache.GetMinSeq(ctx, conversationID)
|
||||
if err != nil {
|
||||
log.ZError(ctx, "cache.GetMinSeq error", err)
|
||||
if errs.Unwrap(err) != redis.Nil {
|
||||
return 0, 0, nil, err
|
||||
}
|
||||
if err != nil && errs.Unwrap(err) != redis.Nil {
|
||||
return 0, 0, nil, err
|
||||
}
|
||||
maxSeq, err := db.cache.GetMaxSeq(ctx, conversationID)
|
||||
if err != nil {
|
||||
log.ZError(ctx, "cache.GetMaxSeq error", err)
|
||||
if errs.Unwrap(err) != redis.Nil {
|
||||
return 0, 0, nil, err
|
||||
}
|
||||
|
||||
if err != nil && errs.Unwrap(err) != redis.Nil {
|
||||
return 0, 0, nil, err
|
||||
}
|
||||
if userMinSeq < minSeq {
|
||||
minSeq = userMinSeq
|
||||
@@ -690,16 +676,34 @@ func (db *commonMsgDatabase) GetMsgBySeqs(ctx context.Context, userID string, co
|
||||
}
|
||||
successMsgs, failedSeqs, err := db.cache.GetMessagesBySeq(ctx, conversationID, newSeqs)
|
||||
if err != nil {
|
||||
log.ZError(ctx, "get message from redis exception", err, "failedSeqs", failedSeqs, "conversationID", conversationID)
|
||||
if err != redis.Nil {
|
||||
log.ZError(ctx, "get message from redis exception", err, "failedSeqs", failedSeqs, "conversationID", conversationID)
|
||||
}
|
||||
}
|
||||
log.ZInfo(ctx, "db.cache.GetMessagesBySeq", "userID", userID, "conversationID", conversationID, "seqs", seqs, "successMsgs",
|
||||
len(successMsgs), "failedSeqs", failedSeqs, "conversationID", conversationID)
|
||||
log.ZInfo(
|
||||
ctx,
|
||||
"db.cache.GetMessagesBySeq",
|
||||
"userID",
|
||||
userID,
|
||||
"conversationID",
|
||||
conversationID,
|
||||
"seqs",
|
||||
seqs,
|
||||
"successMsgs",
|
||||
len(successMsgs),
|
||||
"failedSeqs",
|
||||
failedSeqs,
|
||||
"conversationID",
|
||||
conversationID,
|
||||
)
|
||||
|
||||
if len(failedSeqs) > 0 {
|
||||
mongoMsgs, err := db.getMsgBySeqs(ctx, userID, conversationID, failedSeqs)
|
||||
if err != nil {
|
||||
|
||||
return 0, 0, nil, err
|
||||
}
|
||||
|
||||
successMsgs = append(successMsgs, mongoMsgs...)
|
||||
}
|
||||
return minSeq, maxSeq, successMsgs, nil
|
||||
|
||||
@@ -235,7 +235,7 @@ func Test_FindBySeq(t *testing.T) {
|
||||
func TestName(t *testing.T) {
|
||||
db := GetDB()
|
||||
var seqs []int64
|
||||
for i := int64(1); i <= 4; i++ {
|
||||
for i := int64(1); i <= 50; i++ {
|
||||
seqs = append(seqs, i)
|
||||
}
|
||||
msgs, err := db.getMsgBySeqsRange(context.Background(), "4931176757", "si_3866692501_4931176757", seqs, seqs[0], seqs[len(seqs)-1])
|
||||
|
||||
@@ -72,14 +72,15 @@ func (s *s3Database) CompleteMultipartUpload(ctx context.Context, uploadID strin
|
||||
}
|
||||
|
||||
func (s *s3Database) SetObject(ctx context.Context, info *relation.ObjectModel) error {
|
||||
info.Engine = s.s3.Engine()
|
||||
if err := s.db.SetObject(ctx, info); err != nil {
|
||||
return err
|
||||
}
|
||||
return s.cache.DelObjectName(info.Name).ExecDel(ctx)
|
||||
return s.cache.DelObjectName(info.Engine, info.Name).ExecDel(ctx)
|
||||
}
|
||||
|
||||
func (s *s3Database) AccessURL(ctx context.Context, name string, expire time.Duration, opt *s3.AccessURLOption) (time.Time, string, error) {
|
||||
obj, err := s.cache.GetName(ctx, name)
|
||||
obj, err := s.cache.GetName(ctx, s.s3.Engine(), name)
|
||||
if err != nil {
|
||||
return time.Time{}, "", err
|
||||
}
|
||||
|
||||
@@ -18,10 +18,9 @@ import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"gorm.io/gorm"
|
||||
"github.com/OpenIMSDK/tools/pagination"
|
||||
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/common/db/cache"
|
||||
dbimpl "github.com/openimsdk/open-im-server/v3/pkg/common/db/relation"
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation"
|
||||
)
|
||||
|
||||
@@ -29,22 +28,15 @@ type ThirdDatabase interface {
|
||||
FcmUpdateToken(ctx context.Context, account string, platformID int, fcmToken string, expireTime int64) error
|
||||
SetAppBadge(ctx context.Context, userID string, value int) error
|
||||
// about log for debug
|
||||
UploadLogs(ctx context.Context, logs []*relation.Log) error
|
||||
UploadLogs(ctx context.Context, logs []*relation.LogModel) error
|
||||
DeleteLogs(ctx context.Context, logID []string, userID string) error
|
||||
SearchLogs(ctx context.Context, keyword string, start time.Time, end time.Time, pageNumber int32, showNumber int32) (uint32, []*relation.Log, error)
|
||||
GetLogs(ctx context.Context, LogIDs []string, userID string) ([]*relation.Log, error)
|
||||
FindUsers(ctx context.Context, userIDs []string) ([]*relation.UserModel, error)
|
||||
SearchLogs(ctx context.Context, keyword string, start time.Time, end time.Time, pagination pagination.Pagination) (int64, []*relation.LogModel, error)
|
||||
GetLogs(ctx context.Context, LogIDs []string, userID string) ([]*relation.LogModel, error)
|
||||
}
|
||||
|
||||
type thirdDatabase struct {
|
||||
cache cache.MsgModel
|
||||
logdb relation.LogInterface
|
||||
userdb relation.UserModelInterface
|
||||
}
|
||||
|
||||
// FindUsers implements ThirdDatabase.
|
||||
func (t *thirdDatabase) FindUsers(ctx context.Context, userIDs []string) ([]*relation.UserModel, error) {
|
||||
return t.userdb.Find(ctx, userIDs)
|
||||
cache cache.MsgModel
|
||||
logdb relation.LogInterface
|
||||
}
|
||||
|
||||
// DeleteLogs implements ThirdDatabase.
|
||||
@@ -53,22 +45,22 @@ func (t *thirdDatabase) DeleteLogs(ctx context.Context, logID []string, userID s
|
||||
}
|
||||
|
||||
// GetLogs implements ThirdDatabase.
|
||||
func (t *thirdDatabase) GetLogs(ctx context.Context, LogIDs []string, userID string) ([]*relation.Log, error) {
|
||||
func (t *thirdDatabase) GetLogs(ctx context.Context, LogIDs []string, userID string) ([]*relation.LogModel, error) {
|
||||
return t.logdb.Get(ctx, LogIDs, userID)
|
||||
}
|
||||
|
||||
// SearchLogs implements ThirdDatabase.
|
||||
func (t *thirdDatabase) SearchLogs(ctx context.Context, keyword string, start time.Time, end time.Time, pageNumber int32, showNumber int32) (uint32, []*relation.Log, error) {
|
||||
return t.logdb.Search(ctx, keyword, start, end, pageNumber, showNumber)
|
||||
func (t *thirdDatabase) SearchLogs(ctx context.Context, keyword string, start time.Time, end time.Time, pagination pagination.Pagination) (int64, []*relation.LogModel, error) {
|
||||
return t.logdb.Search(ctx, keyword, start, end, pagination)
|
||||
}
|
||||
|
||||
// UploadLogs implements ThirdDatabase.
|
||||
func (t *thirdDatabase) UploadLogs(ctx context.Context, logs []*relation.Log) error {
|
||||
func (t *thirdDatabase) UploadLogs(ctx context.Context, logs []*relation.LogModel) error {
|
||||
return t.logdb.Create(ctx, logs)
|
||||
}
|
||||
|
||||
func NewThirdDatabase(cache cache.MsgModel, db *gorm.DB) ThirdDatabase {
|
||||
return &thirdDatabase{cache: cache, logdb: dbimpl.NewLogGorm(db), userdb: dbimpl.NewUserGorm(db)}
|
||||
func NewThirdDatabase(cache cache.MsgModel, logdb relation.LogInterface) ThirdDatabase {
|
||||
return &thirdDatabase{cache: cache, logdb: logdb}
|
||||
}
|
||||
|
||||
func (t *thirdDatabase) FcmUpdateToken(
|
||||
|
||||
@@ -18,16 +18,19 @@ import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"github.com/OpenIMSDK/tools/pagination"
|
||||
"github.com/OpenIMSDK/tools/tx"
|
||||
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation"
|
||||
|
||||
"github.com/OpenIMSDK/protocol/user"
|
||||
|
||||
unrelationtb "github.com/openimsdk/open-im-server/v3/pkg/common/db/table/unrelation"
|
||||
|
||||
"github.com/OpenIMSDK/tools/errs"
|
||||
"github.com/OpenIMSDK/tools/tx"
|
||||
"github.com/OpenIMSDK/tools/utils"
|
||||
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/common/db/cache"
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation"
|
||||
)
|
||||
|
||||
type UserDatabase interface {
|
||||
@@ -38,15 +41,15 @@ type UserDatabase interface {
|
||||
// Create Insert multiple external guarantees that the userID is not repeated and does not exist in the db
|
||||
Create(ctx context.Context, users []*relation.UserModel) (err error)
|
||||
// Update update (non-zero value) external guarantee userID exists
|
||||
Update(ctx context.Context, user *relation.UserModel) (err error)
|
||||
//Update(ctx context.Context, user *relation.UserModel) (err error)
|
||||
// UpdateByMap update (zero value) external guarantee userID exists
|
||||
UpdateByMap(ctx context.Context, userID string, args map[string]interface{}) (err error)
|
||||
UpdateByMap(ctx context.Context, userID string, args map[string]any) (err error)
|
||||
// Page If not found, no error is returned
|
||||
Page(ctx context.Context, pageNumber, showNumber int32) (users []*relation.UserModel, count int64, err error)
|
||||
Page(ctx context.Context, 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
|
||||
GetAllUserID(ctx context.Context, pageNumber, showNumber int32) ([]string, error)
|
||||
GetAllUserID(ctx context.Context, pagination pagination.Pagination) (int64, []string, error)
|
||||
// InitOnce Inside the function, first query whether it exists in the db, if it exists, do nothing; if it does not exist, insert it
|
||||
InitOnce(ctx context.Context, users []*relation.UserModel) (err error)
|
||||
// CountTotal Get the total number of users
|
||||
@@ -68,28 +71,40 @@ type UserDatabase interface {
|
||||
}
|
||||
|
||||
type userDatabase struct {
|
||||
tx tx.CtxTx
|
||||
userDB relation.UserModelInterface
|
||||
cache cache.UserCache
|
||||
tx tx.Tx
|
||||
mongoDB unrelationtb.UserModelInterface
|
||||
}
|
||||
|
||||
func NewUserDatabase(userDB relation.UserModelInterface, cache cache.UserCache, tx tx.Tx, mongoDB unrelationtb.UserModelInterface) UserDatabase {
|
||||
func NewUserDatabase(userDB relation.UserModelInterface, cache cache.UserCache, tx tx.CtxTx, mongoDB unrelationtb.UserModelInterface) UserDatabase {
|
||||
return &userDatabase{userDB: userDB, cache: cache, tx: tx, mongoDB: mongoDB}
|
||||
}
|
||||
|
||||
func (u *userDatabase) InitOnce(ctx context.Context, users []*relation.UserModel) (err error) {
|
||||
func (u *userDatabase) InitOnce(ctx context.Context, users []*relation.UserModel) error {
|
||||
// Extract user IDs from the given user models.
|
||||
userIDs := utils.Slice(users, func(e *relation.UserModel) string {
|
||||
return e.UserID
|
||||
})
|
||||
result, err := u.userDB.Find(ctx, userIDs)
|
||||
|
||||
// Find existing users in the database.
|
||||
existingUsers, err := u.userDB.Find(ctx, userIDs)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
miss := utils.SliceAnySub(users, result, func(e *relation.UserModel) string { return e.UserID })
|
||||
if len(miss) > 0 {
|
||||
_ = u.userDB.Create(ctx, miss)
|
||||
|
||||
// Determine which users are missing from the database.
|
||||
missingUsers := utils.SliceAnySub(users, existingUsers, func(e *relation.UserModel) string {
|
||||
return e.UserID
|
||||
})
|
||||
|
||||
// Create records for missing users.
|
||||
if len(missingUsers) > 0 {
|
||||
if err := u.userDB.Create(ctx, missingUsers); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -107,50 +122,42 @@ func (u *userDatabase) FindWithError(ctx context.Context, userIDs []string) (use
|
||||
|
||||
// Find Get the information of the specified user. If the userID is not found, no error will be returned.
|
||||
func (u *userDatabase) Find(ctx context.Context, userIDs []string) (users []*relation.UserModel, err error) {
|
||||
users, err = u.cache.GetUsersInfo(ctx, userIDs)
|
||||
return
|
||||
return u.cache.GetUsersInfo(ctx, userIDs)
|
||||
}
|
||||
|
||||
// Create Insert multiple external guarantees that the userID is not repeated and does not exist in the db.
|
||||
func (u *userDatabase) Create(ctx context.Context, users []*relation.UserModel) (err error) {
|
||||
if err := u.tx.Transaction(func(tx any) error {
|
||||
err = u.userDB.Create(ctx, users)
|
||||
if err != nil {
|
||||
return u.tx.Transaction(ctx, func(ctx context.Context) error {
|
||||
if err = u.userDB.Create(ctx, users); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
var userIDs []string
|
||||
for _, user := range users {
|
||||
userIDs = append(userIDs, user.UserID)
|
||||
}
|
||||
return u.cache.DelUsersInfo(userIDs...).ExecDel(ctx)
|
||||
return u.cache.DelUsersInfo(utils.Slice(users, func(e *relation.UserModel) string {
|
||||
return e.UserID
|
||||
})...).ExecDel(ctx)
|
||||
})
|
||||
}
|
||||
|
||||
// Update (non-zero value) externally guarantees that userID exists.
|
||||
func (u *userDatabase) Update(ctx context.Context, user *relation.UserModel) (err error) {
|
||||
if err := u.userDB.Update(ctx, user); err != nil {
|
||||
return err
|
||||
}
|
||||
return u.cache.DelUsersInfo(user.UserID).ExecDel(ctx)
|
||||
}
|
||||
//// Update (non-zero value) externally guarantees that userID exists.
|
||||
//func (u *userDatabase) Update(ctx context.Context, user *relation.UserModel) (err error) {
|
||||
// if err := u.userDB.Update(ctx, user); err != nil {
|
||||
// return err
|
||||
// }
|
||||
// return u.cache.DelUsersInfo(user.UserID).ExecDel(ctx)
|
||||
//}
|
||||
|
||||
// UpdateByMap update (zero value) externally guarantees that userID exists.
|
||||
func (u *userDatabase) UpdateByMap(ctx context.Context, userID string, args map[string]interface{}) (err error) {
|
||||
if err := u.userDB.UpdateByMap(ctx, userID, args); err != nil {
|
||||
return err
|
||||
}
|
||||
return u.cache.DelUsersInfo(userID).ExecDel(ctx)
|
||||
func (u *userDatabase) UpdateByMap(ctx context.Context, userID string, args map[string]any) (err error) {
|
||||
return u.tx.Transaction(ctx, func(ctx context.Context) error {
|
||||
if err := u.userDB.UpdateByMap(ctx, userID, args); err != nil {
|
||||
return err
|
||||
}
|
||||
return u.cache.DelUsersInfo(userID).ExecDel(ctx)
|
||||
})
|
||||
}
|
||||
|
||||
// Page Gets, returns no error if not found.
|
||||
func (u *userDatabase) Page(
|
||||
ctx context.Context,
|
||||
pageNumber, showNumber int32,
|
||||
) (users []*relation.UserModel, count int64, err error) {
|
||||
return u.userDB.Page(ctx, pageNumber, showNumber)
|
||||
func (u *userDatabase) Page(ctx context.Context, pagination pagination.Pagination) (count int64, users []*relation.UserModel, err error) {
|
||||
return u.userDB.Page(ctx, pagination)
|
||||
}
|
||||
|
||||
// IsExist Does userIDs exist? As long as there is one, it will be true.
|
||||
@@ -166,8 +173,8 @@ func (u *userDatabase) IsExist(ctx context.Context, userIDs []string) (exist boo
|
||||
}
|
||||
|
||||
// GetAllUserID Get all user IDs.
|
||||
func (u *userDatabase) GetAllUserID(ctx context.Context, pageNumber, showNumber int32) (userIDs []string, err error) {
|
||||
return u.userDB.GetAllUserID(ctx, pageNumber, showNumber)
|
||||
func (u *userDatabase) GetAllUserID(ctx context.Context, pagination pagination.Pagination) (total int64, userIDs []string, err error) {
|
||||
return u.userDB.GetAllUserID(ctx, pagination)
|
||||
}
|
||||
|
||||
// CountTotal Get the total number of users.
|
||||
|
||||
@@ -0,0 +1,91 @@
|
||||
package mgo
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/OpenIMSDK/tools/mgoutil"
|
||||
"github.com/OpenIMSDK/tools/pagination"
|
||||
"go.mongodb.org/mongo-driver/bson"
|
||||
"go.mongodb.org/mongo-driver/mongo"
|
||||
"go.mongodb.org/mongo-driver/mongo/options"
|
||||
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation"
|
||||
)
|
||||
|
||||
func NewBlackMongo(db *mongo.Database) (relation.BlackModelInterface, error) {
|
||||
coll := db.Collection("black")
|
||||
_, err := coll.Indexes().CreateOne(context.Background(), mongo.IndexModel{
|
||||
Keys: bson.D{
|
||||
{Key: "owner_user_id", Value: 1},
|
||||
{Key: "block_user_id", Value: 1},
|
||||
},
|
||||
Options: options.Index().SetUnique(true),
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &BlackMgo{coll: coll}, nil
|
||||
}
|
||||
|
||||
type BlackMgo struct {
|
||||
coll *mongo.Collection
|
||||
}
|
||||
|
||||
func (b *BlackMgo) blackFilter(ownerUserID, blockUserID string) bson.M {
|
||||
return bson.M{
|
||||
"owner_user_id": ownerUserID,
|
||||
"block_user_id": blockUserID,
|
||||
}
|
||||
}
|
||||
|
||||
func (b *BlackMgo) blacksFilter(blacks []*relation.BlackModel) bson.M {
|
||||
if len(blacks) == 0 {
|
||||
return nil
|
||||
}
|
||||
or := make(bson.A, 0, len(blacks))
|
||||
for _, black := range blacks {
|
||||
or = append(or, b.blackFilter(black.OwnerUserID, black.BlockUserID))
|
||||
}
|
||||
return bson.M{"$or": or}
|
||||
}
|
||||
|
||||
func (b *BlackMgo) Create(ctx context.Context, blacks []*relation.BlackModel) (err error) {
|
||||
return mgoutil.InsertMany(ctx, b.coll, blacks)
|
||||
}
|
||||
|
||||
func (b *BlackMgo) Delete(ctx context.Context, blacks []*relation.BlackModel) (err error) {
|
||||
if len(blacks) == 0 {
|
||||
return nil
|
||||
}
|
||||
return mgoutil.DeleteMany(ctx, b.coll, b.blacksFilter(blacks))
|
||||
}
|
||||
|
||||
func (b *BlackMgo) UpdateByMap(ctx context.Context, ownerUserID, blockUserID string, args map[string]any) (err error) {
|
||||
if len(args) == 0 {
|
||||
return nil
|
||||
}
|
||||
return mgoutil.UpdateOne(ctx, b.coll, b.blackFilter(ownerUserID, blockUserID), bson.M{"$set": args}, false)
|
||||
}
|
||||
|
||||
func (b *BlackMgo) Find(ctx context.Context, blacks []*relation.BlackModel) (blackList []*relation.BlackModel, err error) {
|
||||
return mgoutil.Find[*relation.BlackModel](ctx, b.coll, b.blacksFilter(blacks))
|
||||
}
|
||||
|
||||
func (b *BlackMgo) Take(ctx context.Context, ownerUserID, blockUserID string) (black *relation.BlackModel, err error) {
|
||||
return mgoutil.FindOne[*relation.BlackModel](ctx, b.coll, b.blackFilter(ownerUserID, blockUserID))
|
||||
}
|
||||
|
||||
func (b *BlackMgo) FindOwnerBlacks(ctx context.Context, ownerUserID string, pagination pagination.Pagination) (total int64, blacks []*relation.BlackModel, err error) {
|
||||
return mgoutil.FindPage[*relation.BlackModel](ctx, b.coll, bson.M{"owner_user_id": ownerUserID}, pagination)
|
||||
}
|
||||
|
||||
func (b *BlackMgo) FindOwnerBlackInfos(ctx context.Context, ownerUserID string, userIDs []string) (blacks []*relation.BlackModel, err error) {
|
||||
if len(userIDs) == 0 {
|
||||
return mgoutil.Find[*relation.BlackModel](ctx, b.coll, bson.M{"owner_user_id": ownerUserID})
|
||||
}
|
||||
return mgoutil.Find[*relation.BlackModel](ctx, b.coll, bson.M{"owner_user_id": ownerUserID, "block_user_id": bson.M{"$in": userIDs}})
|
||||
}
|
||||
|
||||
func (b *BlackMgo) FindBlackUserIDs(ctx context.Context, ownerUserID string) (blackUserIDs []string, err error) {
|
||||
return mgoutil.Find[string](ctx, b.coll, bson.M{"owner_user_id": ownerUserID}, options.Find().SetProjection(bson.M{"_id": 0, "block_user_id": 1}))
|
||||
}
|
||||
@@ -0,0 +1,150 @@
|
||||
package mgo
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"github.com/OpenIMSDK/protocol/constant"
|
||||
"github.com/OpenIMSDK/tools/mgoutil"
|
||||
"github.com/OpenIMSDK/tools/pagination"
|
||||
"go.mongodb.org/mongo-driver/bson"
|
||||
"go.mongodb.org/mongo-driver/mongo"
|
||||
"go.mongodb.org/mongo-driver/mongo/options"
|
||||
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation"
|
||||
)
|
||||
|
||||
func NewConversationMongo(db *mongo.Database) (*ConversationMgo, error) {
|
||||
coll := db.Collection("conversation")
|
||||
_, err := coll.Indexes().CreateOne(context.Background(), mongo.IndexModel{
|
||||
Keys: bson.D{
|
||||
{Key: "owner_user_id", Value: 1},
|
||||
{Key: "conversation_id", Value: 1},
|
||||
},
|
||||
Options: options.Index().SetUnique(true),
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &ConversationMgo{coll: coll}, nil
|
||||
}
|
||||
|
||||
type ConversationMgo struct {
|
||||
coll *mongo.Collection
|
||||
}
|
||||
|
||||
func (c *ConversationMgo) Create(ctx context.Context, conversations []*relation.ConversationModel) (err error) {
|
||||
return mgoutil.InsertMany(ctx, c.coll, conversations)
|
||||
}
|
||||
|
||||
func (c *ConversationMgo) Delete(ctx context.Context, groupIDs []string) (err error) {
|
||||
return mgoutil.DeleteMany(ctx, c.coll, bson.M{"group_id": bson.M{"$in": groupIDs}})
|
||||
}
|
||||
|
||||
func (c *ConversationMgo) UpdateByMap(ctx context.Context, userIDs []string, conversationID string, args map[string]any) (rows int64, err error) {
|
||||
res, err := mgoutil.UpdateMany(ctx, c.coll, bson.M{"owner_user_id": bson.M{"$in": userIDs}, "conversation_id": conversationID}, bson.M{"$set": args})
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return res.ModifiedCount, nil
|
||||
}
|
||||
|
||||
func (c *ConversationMgo) Update(ctx context.Context, conversation *relation.ConversationModel) (err error) {
|
||||
return mgoutil.UpdateOne(ctx, c.coll, bson.M{"owner_user_id": conversation.OwnerUserID, "conversation_id": conversation.ConversationID}, bson.M{"$set": conversation}, true)
|
||||
}
|
||||
|
||||
func (c *ConversationMgo) Find(ctx context.Context, ownerUserID string, conversationIDs []string) (conversations []*relation.ConversationModel, err error) {
|
||||
return mgoutil.Find[*relation.ConversationModel](ctx, c.coll, bson.M{"owner_user_id": ownerUserID, "conversation_id": bson.M{"$in": conversationIDs}})
|
||||
}
|
||||
|
||||
func (c *ConversationMgo) FindUserID(ctx context.Context, userIDs []string, conversationIDs []string) ([]string, error) {
|
||||
return mgoutil.Find[string](
|
||||
ctx,
|
||||
c.coll,
|
||||
bson.M{"owner_user_id": bson.M{"$in": userIDs}, "conversation_id": bson.M{"$in": conversationIDs}},
|
||||
options.Find().SetProjection(bson.M{"_id": 0, "owner_user_id": 1}),
|
||||
)
|
||||
}
|
||||
|
||||
func (c *ConversationMgo) FindUserIDAllConversationID(ctx context.Context, userID string) ([]string, error) {
|
||||
return mgoutil.Find[string](ctx, c.coll, bson.M{"owner_user_id": userID}, options.Find().SetProjection(bson.M{"_id": 0, "conversation_id": 1}))
|
||||
}
|
||||
|
||||
func (c *ConversationMgo) Take(ctx context.Context, userID, conversationID string) (conversation *relation.ConversationModel, err error) {
|
||||
return mgoutil.FindOne[*relation.ConversationModel](ctx, c.coll, bson.M{"owner_user_id": userID, "conversation_id": conversationID})
|
||||
}
|
||||
|
||||
func (c *ConversationMgo) FindConversationID(ctx context.Context, userID string, conversationIDs []string) (existConversationID []string, err error) {
|
||||
return mgoutil.Find[string](ctx, c.coll, bson.M{"owner_user_id": userID, "conversation_id": bson.M{"$in": conversationIDs}}, options.Find().SetProjection(bson.M{"_id": 0, "conversation_id": 1}))
|
||||
}
|
||||
|
||||
func (c *ConversationMgo) FindUserIDAllConversations(ctx context.Context, userID string) (conversations []*relation.ConversationModel, err error) {
|
||||
return mgoutil.Find[*relation.ConversationModel](ctx, c.coll, bson.M{"owner_user_id": userID})
|
||||
}
|
||||
|
||||
func (c *ConversationMgo) FindRecvMsgNotNotifyUserIDs(ctx context.Context, groupID string) ([]string, error) {
|
||||
return mgoutil.Find[string](ctx, c.coll, bson.M{"group_id": groupID, "recv_msg_opt": constant.ReceiveNotNotifyMessage}, options.Find().SetProjection(bson.M{"_id": 0, "owner_user_id": 1}))
|
||||
}
|
||||
|
||||
func (c *ConversationMgo) GetUserRecvMsgOpt(ctx context.Context, ownerUserID, conversationID string) (opt int, err error) {
|
||||
return mgoutil.FindOne[int](ctx, c.coll, bson.M{"owner_user_id": ownerUserID, "conversation_id": conversationID}, options.FindOne().SetProjection(bson.M{"recv_msg_opt": 1}))
|
||||
}
|
||||
|
||||
func (c *ConversationMgo) GetAllConversationIDs(ctx context.Context) ([]string, error) {
|
||||
return mgoutil.Aggregate[string](ctx, c.coll, []bson.M{
|
||||
{"$group": bson.M{"_id": "$conversation_id"}},
|
||||
{"$project": bson.M{"_id": 0, "conversation_id": "$_id"}},
|
||||
})
|
||||
}
|
||||
|
||||
func (c *ConversationMgo) GetAllConversationIDsNumber(ctx context.Context) (int64, error) {
|
||||
counts, err := mgoutil.Aggregate[int64](ctx, c.coll, []bson.M{
|
||||
{"$group": bson.M{"_id": "$conversation_id"}},
|
||||
{"$project": bson.M{"_id": 0, "conversation_id": "$_id"}},
|
||||
})
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
if len(counts) == 0 {
|
||||
return 0, nil
|
||||
}
|
||||
return counts[0], nil
|
||||
}
|
||||
|
||||
func (c *ConversationMgo) PageConversationIDs(ctx context.Context, pagination pagination.Pagination) (conversationIDs []string, err error) {
|
||||
return mgoutil.FindPageOnly[string](ctx, c.coll, bson.M{}, pagination, options.Find().SetProjection(bson.M{"conversation_id": 1}))
|
||||
}
|
||||
|
||||
func (c *ConversationMgo) GetConversationsByConversationID(ctx context.Context, conversationIDs []string) ([]*relation.ConversationModel, error) {
|
||||
return mgoutil.Find[*relation.ConversationModel](ctx, c.coll, bson.M{"conversation_id": bson.M{"$in": conversationIDs}})
|
||||
}
|
||||
|
||||
func (c *ConversationMgo) GetConversationIDsNeedDestruct(ctx context.Context) ([]*relation.ConversationModel, error) {
|
||||
//"is_msg_destruct = 1 && msg_destruct_time != 0 && (UNIX_TIMESTAMP(NOW()) > (msg_destruct_time + UNIX_TIMESTAMP(latest_msg_destruct_time)) || latest_msg_destruct_time is NULL)"
|
||||
return mgoutil.Find[*relation.ConversationModel](ctx, c.coll, bson.M{
|
||||
"is_msg_destruct": 1,
|
||||
"msg_destruct_time": bson.M{"$ne": 0},
|
||||
"$or": []bson.M{
|
||||
{
|
||||
"$expr": bson.M{
|
||||
"$gt": []any{
|
||||
time.Now(),
|
||||
bson.M{"$add": []any{"$msg_destruct_time", "$latest_msg_destruct_time"}},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
"latest_msg_destruct_time": nil,
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func (c *ConversationMgo) GetConversationNotReceiveMessageUserIDs(ctx context.Context, conversationID string) ([]string, error) {
|
||||
return mgoutil.Find[string](
|
||||
ctx,
|
||||
c.coll,
|
||||
bson.M{"conversation_id": conversationID, "recv_msg_opt": bson.M{"$ne": constant.ReceiveMessage}},
|
||||
options.Find().SetProjection(bson.M{"_id": 0, "owner_user_id": 1}),
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,131 @@
|
||||
package mgo
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/OpenIMSDK/tools/mgoutil"
|
||||
"github.com/OpenIMSDK/tools/pagination"
|
||||
"go.mongodb.org/mongo-driver/mongo/options"
|
||||
|
||||
"go.mongodb.org/mongo-driver/bson"
|
||||
"go.mongodb.org/mongo-driver/mongo"
|
||||
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation"
|
||||
)
|
||||
|
||||
// FriendMgo implements FriendModelInterface using MongoDB as the storage backend.
|
||||
type FriendMgo struct {
|
||||
coll *mongo.Collection
|
||||
}
|
||||
|
||||
// NewFriendMongo creates a new instance of FriendMgo with the provided MongoDB database.
|
||||
func NewFriendMongo(db *mongo.Database) (relation.FriendModelInterface, error) {
|
||||
coll := db.Collection("friend")
|
||||
_, err := coll.Indexes().CreateOne(context.Background(), mongo.IndexModel{
|
||||
Keys: bson.D{
|
||||
{Key: "owner_user_id", Value: 1},
|
||||
{Key: "friend_user_id", Value: 1},
|
||||
},
|
||||
Options: options.Index().SetUnique(true),
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &FriendMgo{coll: coll}, nil
|
||||
}
|
||||
|
||||
// Create inserts multiple friend records.
|
||||
func (f *FriendMgo) Create(ctx context.Context, friends []*relation.FriendModel) error {
|
||||
return mgoutil.InsertMany(ctx, f.coll, friends)
|
||||
}
|
||||
|
||||
// Delete removes specified friends of the owner user.
|
||||
func (f *FriendMgo) Delete(ctx context.Context, ownerUserID string, friendUserIDs []string) error {
|
||||
filter := bson.M{
|
||||
"owner_user_id": ownerUserID,
|
||||
"friend_user_id": bson.M{"$in": friendUserIDs},
|
||||
}
|
||||
return mgoutil.DeleteOne(ctx, f.coll, filter)
|
||||
}
|
||||
|
||||
// UpdateByMap updates specific fields of a friend document using a map.
|
||||
func (f *FriendMgo) UpdateByMap(ctx context.Context, ownerUserID string, friendUserID string, args map[string]interface{}) error {
|
||||
if len(args) == 0 {
|
||||
return nil
|
||||
}
|
||||
filter := bson.M{
|
||||
"owner_user_id": ownerUserID,
|
||||
"friend_user_id": friendUserID,
|
||||
}
|
||||
return mgoutil.UpdateOne(ctx, f.coll, filter, bson.M{"$set": args}, true)
|
||||
}
|
||||
|
||||
// Update modifies multiple friend documents.
|
||||
// func (f *FriendMgo) Update(ctx context.Context, friends []*relation.FriendModel) error {
|
||||
// filter := bson.M{
|
||||
// "owner_user_id": ownerUserID,
|
||||
// "friend_user_id": friendUserID,
|
||||
// }
|
||||
// return mgotool.UpdateMany(ctx, f.coll, filter, friends)
|
||||
// }
|
||||
|
||||
// UpdateRemark updates the remark for a specific friend.
|
||||
func (f *FriendMgo) UpdateRemark(ctx context.Context, ownerUserID, friendUserID, remark string) error {
|
||||
return f.UpdateByMap(ctx, ownerUserID, friendUserID, map[string]any{"remark": remark})
|
||||
}
|
||||
|
||||
// Take retrieves a single friend document. Returns an error if not found.
|
||||
func (f *FriendMgo) Take(ctx context.Context, ownerUserID, friendUserID string) (*relation.FriendModel, error) {
|
||||
filter := bson.M{
|
||||
"owner_user_id": ownerUserID,
|
||||
"friend_user_id": friendUserID,
|
||||
}
|
||||
return mgoutil.FindOne[*relation.FriendModel](ctx, f.coll, filter)
|
||||
}
|
||||
|
||||
// FindUserState finds the friendship status between two users.
|
||||
func (f *FriendMgo) FindUserState(ctx context.Context, userID1, userID2 string) ([]*relation.FriendModel, error) {
|
||||
filter := bson.M{
|
||||
"$or": []bson.M{
|
||||
{"owner_user_id": userID1, "friend_user_id": userID2},
|
||||
{"owner_user_id": userID2, "friend_user_id": userID1},
|
||||
},
|
||||
}
|
||||
return mgoutil.Find[*relation.FriendModel](ctx, f.coll, filter)
|
||||
}
|
||||
|
||||
// FindFriends retrieves a list of friends for a given owner. Missing friends do not cause an error.
|
||||
func (f *FriendMgo) FindFriends(ctx context.Context, ownerUserID string, friendUserIDs []string) ([]*relation.FriendModel, error) {
|
||||
filter := bson.M{
|
||||
"owner_user_id": ownerUserID,
|
||||
"friend_user_id": bson.M{"$in": friendUserIDs},
|
||||
}
|
||||
return mgoutil.Find[*relation.FriendModel](ctx, f.coll, filter)
|
||||
}
|
||||
|
||||
// FindReversalFriends finds users who have added the specified user as a friend.
|
||||
func (f *FriendMgo) FindReversalFriends(ctx context.Context, friendUserID string, ownerUserIDs []string) ([]*relation.FriendModel, error) {
|
||||
filter := bson.M{
|
||||
"owner_user_id": bson.M{"$in": ownerUserIDs},
|
||||
"friend_user_id": friendUserID,
|
||||
}
|
||||
return mgoutil.Find[*relation.FriendModel](ctx, f.coll, filter)
|
||||
}
|
||||
|
||||
// FindOwnerFriends retrieves a paginated list of friends for a given owner.
|
||||
func (f *FriendMgo) FindOwnerFriends(ctx context.Context, ownerUserID string, pagination pagination.Pagination) (int64, []*relation.FriendModel, error) {
|
||||
filter := bson.M{"owner_user_id": ownerUserID}
|
||||
return mgoutil.FindPage[*relation.FriendModel](ctx, f.coll, filter, pagination)
|
||||
}
|
||||
|
||||
// FindInWhoseFriends finds users who have added the specified user as a friend, with pagination.
|
||||
func (f *FriendMgo) FindInWhoseFriends(ctx context.Context, friendUserID string, pagination pagination.Pagination) (int64, []*relation.FriendModel, error) {
|
||||
filter := bson.M{"friend_user_id": friendUserID}
|
||||
return mgoutil.FindPage[*relation.FriendModel](ctx, f.coll, filter, pagination)
|
||||
}
|
||||
|
||||
// FindFriendUserIDs retrieves a list of friend user IDs for a given owner.
|
||||
func (f *FriendMgo) FindFriendUserIDs(ctx context.Context, ownerUserID string) ([]string, error) {
|
||||
filter := bson.M{"owner_user_id": ownerUserID}
|
||||
return mgoutil.Find[string](ctx, f.coll, filter, options.Find().SetProjection(bson.M{"_id": 0, "friend_user_id": 1}))
|
||||
}
|
||||
@@ -0,0 +1,99 @@
|
||||
package mgo
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/OpenIMSDK/tools/mgoutil"
|
||||
"github.com/OpenIMSDK/tools/pagination"
|
||||
"go.mongodb.org/mongo-driver/mongo/options"
|
||||
|
||||
"go.mongodb.org/mongo-driver/bson"
|
||||
"go.mongodb.org/mongo-driver/mongo"
|
||||
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation"
|
||||
)
|
||||
|
||||
func NewFriendRequestMongo(db *mongo.Database) (relation.FriendRequestModelInterface, error) {
|
||||
coll := db.Collection("friend_request")
|
||||
_, err := coll.Indexes().CreateOne(context.Background(), mongo.IndexModel{
|
||||
Keys: bson.D{
|
||||
{Key: "from_user_id", Value: 1},
|
||||
{Key: "to_user_id", Value: 1},
|
||||
},
|
||||
Options: options.Index().SetUnique(true),
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &FriendRequestMgo{coll: coll}, nil
|
||||
}
|
||||
|
||||
type FriendRequestMgo struct {
|
||||
coll *mongo.Collection
|
||||
}
|
||||
|
||||
func (f *FriendRequestMgo) FindToUserID(ctx context.Context, toUserID string, pagination pagination.Pagination) (total int64, friendRequests []*relation.FriendRequestModel, err error) {
|
||||
return mgoutil.FindPage[*relation.FriendRequestModel](ctx, f.coll, bson.M{"to_user_id": toUserID}, pagination)
|
||||
}
|
||||
|
||||
func (f *FriendRequestMgo) FindFromUserID(ctx context.Context, fromUserID string, pagination pagination.Pagination) (total int64, friendRequests []*relation.FriendRequestModel, err error) {
|
||||
return mgoutil.FindPage[*relation.FriendRequestModel](ctx, f.coll, bson.M{"from_user_id": fromUserID}, pagination)
|
||||
}
|
||||
|
||||
func (f *FriendRequestMgo) FindBothFriendRequests(ctx context.Context, fromUserID, toUserID string) (friends []*relation.FriendRequestModel, err error) {
|
||||
filter := bson.M{"$or": []bson.M{
|
||||
{"from_user_id": fromUserID, "to_user_id": toUserID},
|
||||
{"from_user_id": toUserID, "to_user_id": fromUserID},
|
||||
}}
|
||||
return mgoutil.Find[*relation.FriendRequestModel](ctx, f.coll, filter)
|
||||
}
|
||||
|
||||
func (f *FriendRequestMgo) Create(ctx context.Context, friendRequests []*relation.FriendRequestModel) error {
|
||||
return mgoutil.InsertMany(ctx, f.coll, friendRequests)
|
||||
}
|
||||
|
||||
func (f *FriendRequestMgo) Delete(ctx context.Context, fromUserID, toUserID string) (err error) {
|
||||
return mgoutil.DeleteOne(ctx, f.coll, bson.M{"from_user_id": fromUserID, "to_user_id": toUserID})
|
||||
}
|
||||
|
||||
func (f *FriendRequestMgo) UpdateByMap(ctx context.Context, formUserID, toUserID string, args map[string]any) (err error) {
|
||||
if len(args) == 0 {
|
||||
return nil
|
||||
}
|
||||
return mgoutil.UpdateOne(ctx, f.coll, bson.M{"from_user_id": formUserID, "to_user_id": toUserID}, bson.M{"$set": args}, true)
|
||||
}
|
||||
|
||||
func (f *FriendRequestMgo) Update(ctx context.Context, friendRequest *relation.FriendRequestModel) (err error) {
|
||||
updater := bson.M{}
|
||||
if friendRequest.HandleResult != 0 {
|
||||
updater["handle_result"] = friendRequest.HandleResult
|
||||
}
|
||||
if friendRequest.ReqMsg != "" {
|
||||
updater["req_msg"] = friendRequest.ReqMsg
|
||||
}
|
||||
if friendRequest.HandlerUserID != "" {
|
||||
updater["handler_user_id"] = friendRequest.HandlerUserID
|
||||
}
|
||||
if friendRequest.HandleMsg != "" {
|
||||
updater["handle_msg"] = friendRequest.HandleMsg
|
||||
}
|
||||
if !friendRequest.HandleTime.IsZero() {
|
||||
updater["handle_time"] = friendRequest.HandleTime
|
||||
}
|
||||
if friendRequest.Ex != "" {
|
||||
updater["ex"] = friendRequest.Ex
|
||||
}
|
||||
if len(updater) == 0 {
|
||||
return nil
|
||||
}
|
||||
filter := bson.M{"from_user_id": friendRequest.FromUserID, "to_user_id": friendRequest.ToUserID}
|
||||
return mgoutil.UpdateOne(ctx, f.coll, filter, bson.M{"$set": updater}, true)
|
||||
}
|
||||
|
||||
func (f *FriendRequestMgo) Find(ctx context.Context, fromUserID, toUserID string) (friendRequest *relation.FriendRequestModel, err error) {
|
||||
return mgoutil.FindOne[*relation.FriendRequestModel](ctx, f.coll, bson.M{"from_user_id": fromUserID, "to_user_id": toUserID})
|
||||
}
|
||||
|
||||
func (f *FriendRequestMgo) Take(ctx context.Context, fromUserID, toUserID string) (friendRequest *relation.FriendRequestModel, err error) {
|
||||
return f.Find(ctx, fromUserID, toUserID)
|
||||
}
|
||||
@@ -0,0 +1,105 @@
|
||||
package mgo
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"github.com/OpenIMSDK/tools/mgoutil"
|
||||
"github.com/OpenIMSDK/tools/pagination"
|
||||
"go.mongodb.org/mongo-driver/bson"
|
||||
"go.mongodb.org/mongo-driver/mongo"
|
||||
"go.mongodb.org/mongo-driver/mongo/options"
|
||||
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation"
|
||||
)
|
||||
|
||||
func NewGroupMongo(db *mongo.Database) (relation.GroupModelInterface, error) {
|
||||
coll := db.Collection("group")
|
||||
_, err := coll.Indexes().CreateOne(context.Background(), mongo.IndexModel{
|
||||
Keys: bson.D{
|
||||
{Key: "group_id", Value: 1},
|
||||
},
|
||||
Options: options.Index().SetUnique(true),
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &GroupMgo{coll: coll}, nil
|
||||
}
|
||||
|
||||
type GroupMgo struct {
|
||||
coll *mongo.Collection
|
||||
}
|
||||
|
||||
func (g *GroupMgo) Create(ctx context.Context, groups []*relation.GroupModel) (err error) {
|
||||
return mgoutil.InsertMany(ctx, g.coll, groups)
|
||||
}
|
||||
|
||||
func (g *GroupMgo) UpdateState(ctx context.Context, groupID string, state int32) (err error) {
|
||||
return g.UpdateMap(ctx, groupID, map[string]any{"state": state})
|
||||
}
|
||||
|
||||
func (g *GroupMgo) UpdateMap(ctx context.Context, groupID string, args map[string]any) (err error) {
|
||||
if len(args) == 0 {
|
||||
return nil
|
||||
}
|
||||
return mgoutil.UpdateOne(ctx, g.coll, bson.M{"group_id": groupID}, bson.M{"$set": args}, true)
|
||||
}
|
||||
|
||||
func (g *GroupMgo) Find(ctx context.Context, groupIDs []string) (groups []*relation.GroupModel, err error) {
|
||||
return mgoutil.Find[*relation.GroupModel](ctx, g.coll, bson.M{"group_id": bson.M{"$in": groupIDs}})
|
||||
}
|
||||
|
||||
func (g *GroupMgo) Take(ctx context.Context, groupID string) (group *relation.GroupModel, err error) {
|
||||
return mgoutil.FindOne[*relation.GroupModel](ctx, g.coll, bson.M{"group_id": groupID})
|
||||
}
|
||||
|
||||
func (g *GroupMgo) Search(ctx context.Context, keyword string, pagination pagination.Pagination) (total int64, groups []*relation.GroupModel, err error) {
|
||||
return mgoutil.FindPage[*relation.GroupModel](ctx, g.coll, bson.M{"group_name": bson.M{"$regex": keyword}}, pagination)
|
||||
}
|
||||
|
||||
func (g *GroupMgo) CountTotal(ctx context.Context, before *time.Time) (count int64, err error) {
|
||||
if before == nil {
|
||||
return mgoutil.Count(ctx, g.coll, bson.M{})
|
||||
}
|
||||
return mgoutil.Count(ctx, g.coll, bson.M{"create_time": bson.M{"$lt": before}})
|
||||
}
|
||||
|
||||
func (g *GroupMgo) CountRangeEverydayTotal(ctx context.Context, start time.Time, end time.Time) (map[string]int64, error) {
|
||||
pipeline := bson.A{
|
||||
bson.M{
|
||||
"$match": bson.M{
|
||||
"create_time": bson.M{
|
||||
"$gte": start,
|
||||
"$lt": end,
|
||||
},
|
||||
},
|
||||
},
|
||||
bson.M{
|
||||
"$group": bson.M{
|
||||
"_id": bson.M{
|
||||
"$dateToString": bson.M{
|
||||
"format": "%Y-%m-%d",
|
||||
"date": "$create_time",
|
||||
},
|
||||
},
|
||||
"count": bson.M{
|
||||
"$sum": 1,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
type Item struct {
|
||||
Date string `bson:"_id"`
|
||||
Count int64 `bson:"count"`
|
||||
}
|
||||
items, err := mgoutil.Aggregate[Item](ctx, g.coll, pipeline)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
res := make(map[string]int64, len(items))
|
||||
for _, item := range items {
|
||||
res[item.Date] = item.Count
|
||||
}
|
||||
return res, nil
|
||||
}
|
||||
@@ -0,0 +1,101 @@
|
||||
package mgo
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/OpenIMSDK/protocol/constant"
|
||||
"github.com/OpenIMSDK/tools/mgoutil"
|
||||
"github.com/OpenIMSDK/tools/pagination"
|
||||
"go.mongodb.org/mongo-driver/bson"
|
||||
"go.mongodb.org/mongo-driver/mongo"
|
||||
"go.mongodb.org/mongo-driver/mongo/options"
|
||||
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation"
|
||||
)
|
||||
|
||||
func NewGroupMember(db *mongo.Database) (relation.GroupMemberModelInterface, error) {
|
||||
coll := db.Collection("group_member")
|
||||
_, err := coll.Indexes().CreateOne(context.Background(), mongo.IndexModel{
|
||||
Keys: bson.D{
|
||||
{Key: "group_id", Value: 1},
|
||||
{Key: "user_id", Value: 1},
|
||||
},
|
||||
Options: options.Index().SetUnique(true),
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &GroupMemberMgo{coll: coll}, nil
|
||||
}
|
||||
|
||||
type GroupMemberMgo struct {
|
||||
coll *mongo.Collection
|
||||
}
|
||||
|
||||
func (g *GroupMemberMgo) Create(ctx context.Context, groupMembers []*relation.GroupMemberModel) (err error) {
|
||||
return mgoutil.InsertMany(ctx, g.coll, groupMembers)
|
||||
}
|
||||
|
||||
func (g *GroupMemberMgo) Delete(ctx context.Context, groupID string, userIDs []string) (err error) {
|
||||
return mgoutil.DeleteMany(ctx, g.coll, bson.M{"group_id": groupID, "user_id": bson.M{"$in": userIDs}})
|
||||
}
|
||||
|
||||
func (g *GroupMemberMgo) UpdateRoleLevel(ctx context.Context, groupID string, userID string, roleLevel int32) error {
|
||||
return g.Update(ctx, groupID, userID, bson.M{"role_level": roleLevel})
|
||||
}
|
||||
|
||||
func (g *GroupMemberMgo) Update(ctx context.Context, groupID string, userID string, data map[string]any) (err error) {
|
||||
return mgoutil.UpdateOne(ctx, g.coll, bson.M{"group_id": groupID, "user_id": userID}, bson.M{"$set": data}, true)
|
||||
}
|
||||
|
||||
func (g *GroupMemberMgo) Find(ctx context.Context, groupIDs []string, userIDs []string, roleLevels []int32) (groupMembers []*relation.GroupMemberModel, err error) {
|
||||
//TODO implement me
|
||||
panic("implement me")
|
||||
}
|
||||
|
||||
func (g *GroupMemberMgo) FindMemberUserID(ctx context.Context, groupID string) (userIDs []string, err error) {
|
||||
return mgoutil.Find[string](ctx, g.coll, bson.M{"group_id": groupID}, options.Find().SetProjection(bson.M{"_id": 0, "user_id": 1}))
|
||||
}
|
||||
|
||||
func (g *GroupMemberMgo) Take(ctx context.Context, groupID string, userID string) (groupMember *relation.GroupMemberModel, err error) {
|
||||
return mgoutil.FindOne[*relation.GroupMemberModel](ctx, g.coll, bson.M{"group_id": groupID, "user_id": userID})
|
||||
}
|
||||
|
||||
func (g *GroupMemberMgo) TakeOwner(ctx context.Context, groupID string) (groupMember *relation.GroupMemberModel, err error) {
|
||||
return mgoutil.FindOne[*relation.GroupMemberModel](ctx, g.coll, bson.M{"group_id": groupID, "role_level": constant.GroupOwner})
|
||||
}
|
||||
|
||||
func (g *GroupMemberMgo) FindRoleLevelUserIDs(ctx context.Context, groupID string, roleLevel int32) ([]string, error) {
|
||||
return mgoutil.Find[string](ctx, g.coll, bson.M{"group_id": groupID, "role_level": roleLevel}, options.Find().SetProjection(bson.M{"_id": 0, "user_id": 1}))
|
||||
}
|
||||
|
||||
func (g *GroupMemberMgo) SearchMember(ctx context.Context, keyword string, groupID string, pagination pagination.Pagination) (total int64, groupList []*relation.GroupMemberModel, err error) {
|
||||
//TODO implement me
|
||||
panic("implement me")
|
||||
}
|
||||
|
||||
func (g *GroupMemberMgo) FindUserJoinedGroupID(ctx context.Context, userID string) (groupIDs []string, err error) {
|
||||
return mgoutil.Find[string](ctx, g.coll, bson.M{"user_id": userID}, options.Find().SetProjection(bson.M{"_id": 0, "group_id": 1}))
|
||||
}
|
||||
|
||||
func (g *GroupMemberMgo) TakeGroupMemberNum(ctx context.Context, groupID string) (count int64, err error) {
|
||||
return mgoutil.Count(ctx, g.coll, bson.M{"group_id": groupID})
|
||||
}
|
||||
|
||||
func (g *GroupMemberMgo) FindUserManagedGroupID(ctx context.Context, userID string) (groupIDs []string, err error) {
|
||||
filter := bson.M{
|
||||
"user_id": userID,
|
||||
"role_level": bson.M{
|
||||
"$in": []int{constant.GroupOwner, constant.GroupAdmin},
|
||||
},
|
||||
}
|
||||
return mgoutil.Find[string](ctx, g.coll, filter, options.Find().SetProjection(bson.M{"_id": 0, "group_id": 1}))
|
||||
}
|
||||
|
||||
func (g *GroupMemberMgo) IsUpdateRoleLevel(data map[string]any) bool {
|
||||
if len(data) == 0 {
|
||||
return false
|
||||
}
|
||||
_, ok := data["role_level"]
|
||||
return ok
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
package mgo
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/OpenIMSDK/tools/mgoutil"
|
||||
"github.com/OpenIMSDK/tools/pagination"
|
||||
"go.mongodb.org/mongo-driver/bson"
|
||||
"go.mongodb.org/mongo-driver/mongo"
|
||||
"go.mongodb.org/mongo-driver/mongo/options"
|
||||
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation"
|
||||
)
|
||||
|
||||
func NewGroupRequestMgo(db *mongo.Database) (relation.GroupRequestModelInterface, error) {
|
||||
coll := db.Collection("group_request")
|
||||
_, err := coll.Indexes().CreateOne(context.Background(), mongo.IndexModel{
|
||||
Keys: bson.D{
|
||||
{Key: "group_id", Value: 1},
|
||||
{Key: "user_id", Value: 1},
|
||||
},
|
||||
Options: options.Index().SetUnique(true),
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &GroupRequestMgo{coll: coll}, nil
|
||||
}
|
||||
|
||||
type GroupRequestMgo struct {
|
||||
coll *mongo.Collection
|
||||
}
|
||||
|
||||
func (g *GroupRequestMgo) Create(ctx context.Context, groupRequests []*relation.GroupRequestModel) (err error) {
|
||||
return mgoutil.InsertMany(ctx, g.coll, groupRequests)
|
||||
}
|
||||
|
||||
func (g *GroupRequestMgo) Delete(ctx context.Context, groupID string, userID string) (err error) {
|
||||
return mgoutil.DeleteOne(ctx, g.coll, bson.M{"group_id": groupID, "user_id": userID})
|
||||
}
|
||||
|
||||
func (g *GroupRequestMgo) UpdateHandler(ctx context.Context, groupID string, userID string, handledMsg string, handleResult int32) (err error) {
|
||||
return mgoutil.UpdateOne(ctx, g.coll, bson.M{"group_id": groupID, "user_id": userID}, bson.M{"$set": bson.M{"handle_msg": handledMsg, "handle_result": handleResult}}, true)
|
||||
}
|
||||
|
||||
func (g *GroupRequestMgo) Take(ctx context.Context, groupID string, userID string) (groupRequest *relation.GroupRequestModel, err error) {
|
||||
return mgoutil.FindOne[*relation.GroupRequestModel](ctx, g.coll, bson.M{"group_id": groupID, "user_id": userID})
|
||||
}
|
||||
|
||||
func (g *GroupRequestMgo) FindGroupRequests(ctx context.Context, groupID string, userIDs []string) ([]*relation.GroupRequestModel, error) {
|
||||
return mgoutil.Find[*relation.GroupRequestModel](ctx, g.coll, bson.M{"group_id": groupID, "user_id": bson.M{"$in": userIDs}})
|
||||
}
|
||||
|
||||
func (g *GroupRequestMgo) Page(ctx context.Context, userID string, pagination pagination.Pagination) (total int64, groups []*relation.GroupRequestModel, err error) {
|
||||
return mgoutil.FindPage[*relation.GroupRequestModel](ctx, g.coll, bson.M{"user_id": userID}, pagination)
|
||||
}
|
||||
|
||||
func (g *GroupRequestMgo) PageGroup(ctx context.Context, groupIDs []string, pagination pagination.Pagination) (total int64, groups []*relation.GroupRequestModel, err error) {
|
||||
return mgoutil.FindPage[*relation.GroupRequestModel](ctx, g.coll, bson.M{"group_id": bson.M{"$in": groupIDs}}, pagination)
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
package mgo
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"github.com/OpenIMSDK/tools/mgoutil"
|
||||
"github.com/OpenIMSDK/tools/pagination"
|
||||
"go.mongodb.org/mongo-driver/bson"
|
||||
"go.mongodb.org/mongo-driver/mongo"
|
||||
"go.mongodb.org/mongo-driver/mongo/options"
|
||||
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation"
|
||||
)
|
||||
|
||||
func NewLogMongo(db *mongo.Database) (relation.LogInterface, error) {
|
||||
coll := db.Collection("log")
|
||||
_, err := coll.Indexes().CreateMany(context.Background(), []mongo.IndexModel{
|
||||
{
|
||||
Keys: bson.D{
|
||||
{Key: "log_id", Value: 1},
|
||||
},
|
||||
Options: options.Index().SetUnique(true),
|
||||
},
|
||||
{
|
||||
Keys: bson.D{
|
||||
{Key: "user_id", Value: 1},
|
||||
},
|
||||
},
|
||||
{
|
||||
Keys: bson.D{
|
||||
{Key: "create_time", Value: -1},
|
||||
},
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &LogMgo{coll: coll}, nil
|
||||
}
|
||||
|
||||
type LogMgo struct {
|
||||
coll *mongo.Collection
|
||||
}
|
||||
|
||||
func (l *LogMgo) Create(ctx context.Context, log []*relation.LogModel) error {
|
||||
return mgoutil.InsertMany(ctx, l.coll, log)
|
||||
}
|
||||
|
||||
func (l *LogMgo) Search(ctx context.Context, keyword string, start time.Time, end time.Time, pagination pagination.Pagination) (int64, []*relation.LogModel, error) {
|
||||
filter := bson.M{"create_time": bson.M{"$gte": start, "$lte": end}}
|
||||
if keyword != "" {
|
||||
filter["user_id"] = bson.M{"$regex": keyword}
|
||||
}
|
||||
return mgoutil.FindPage[*relation.LogModel](ctx, l.coll, filter, pagination, options.Find().SetSort(bson.M{"create_time": -1}))
|
||||
}
|
||||
|
||||
func (l *LogMgo) Delete(ctx context.Context, logID []string, userID string) error {
|
||||
if userID == "" {
|
||||
return mgoutil.DeleteMany(ctx, l.coll, bson.M{"log_id": bson.M{"$in": logID}})
|
||||
}
|
||||
return mgoutil.DeleteMany(ctx, l.coll, bson.M{"log_id": bson.M{"$in": logID}, "user_id": userID})
|
||||
}
|
||||
|
||||
func (l *LogMgo) Get(ctx context.Context, logIDs []string, userID string) ([]*relation.LogModel, error) {
|
||||
if userID == "" {
|
||||
return mgoutil.Find[*relation.LogModel](ctx, l.coll, bson.M{"log_id": bson.M{"$in": logIDs}})
|
||||
}
|
||||
return mgoutil.Find[*relation.LogModel](ctx, l.coll, bson.M{"log_id": bson.M{"$in": logIDs}, "user_id": userID})
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
package mgo
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/OpenIMSDK/tools/mgoutil"
|
||||
"go.mongodb.org/mongo-driver/bson"
|
||||
"go.mongodb.org/mongo-driver/mongo"
|
||||
"go.mongodb.org/mongo-driver/mongo/options"
|
||||
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation"
|
||||
)
|
||||
|
||||
func NewS3Mongo(db *mongo.Database) (relation.ObjectInfoModelInterface, error) {
|
||||
coll := db.Collection("s3")
|
||||
_, err := coll.Indexes().CreateOne(context.Background(), mongo.IndexModel{
|
||||
Keys: bson.D{
|
||||
{Key: "name", Value: 1},
|
||||
},
|
||||
Options: options.Index().SetUnique(true),
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &S3Mongo{coll: coll}, nil
|
||||
}
|
||||
|
||||
type S3Mongo struct {
|
||||
coll *mongo.Collection
|
||||
}
|
||||
|
||||
func (o *S3Mongo) SetObject(ctx context.Context, obj *relation.ObjectModel) error {
|
||||
filter := bson.M{"name": obj.Name, "engine": obj.Engine}
|
||||
update := bson.M{
|
||||
"name": obj.Name,
|
||||
"engine": obj.Engine,
|
||||
"key": obj.Key,
|
||||
"size": obj.Size,
|
||||
"content_type": obj.ContentType,
|
||||
"group": obj.Group,
|
||||
"create_time": obj.CreateTime,
|
||||
}
|
||||
return mgoutil.UpdateOne(ctx, o.coll, filter, bson.M{"$set": update}, false, options.Update().SetUpsert(true))
|
||||
}
|
||||
|
||||
func (o *S3Mongo) Take(ctx context.Context, engine string, name string) (*relation.ObjectModel, error) {
|
||||
if engine == "" {
|
||||
return mgoutil.FindOne[*relation.ObjectModel](ctx, o.coll, bson.M{"name": name})
|
||||
}
|
||||
return mgoutil.FindOne[*relation.ObjectModel](ctx, o.coll, bson.M{"name": name, "engine": engine})
|
||||
}
|
||||
|
||||
func (o *S3Mongo) Delete(ctx context.Context, engine string, name string) error {
|
||||
return mgoutil.DeleteOne(ctx, o.coll, bson.M{"name": name, "engine": engine})
|
||||
}
|
||||
@@ -0,0 +1,113 @@
|
||||
package mgo
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"github.com/OpenIMSDK/tools/mgoutil"
|
||||
"github.com/OpenIMSDK/tools/pagination"
|
||||
"go.mongodb.org/mongo-driver/bson"
|
||||
"go.mongodb.org/mongo-driver/mongo"
|
||||
"go.mongodb.org/mongo-driver/mongo/options"
|
||||
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation"
|
||||
)
|
||||
|
||||
func NewUserMongo(db *mongo.Database) (relation.UserModelInterface, error) {
|
||||
coll := db.Collection("user")
|
||||
_, err := coll.Indexes().CreateOne(context.Background(), mongo.IndexModel{
|
||||
Keys: bson.D{
|
||||
{Key: "user_id", Value: 1},
|
||||
},
|
||||
Options: options.Index().SetUnique(true),
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &UserMgo{coll: coll}, nil
|
||||
}
|
||||
|
||||
type UserMgo struct {
|
||||
coll *mongo.Collection
|
||||
}
|
||||
|
||||
func (u *UserMgo) Create(ctx context.Context, users []*relation.UserModel) error {
|
||||
return mgoutil.InsertMany(ctx, u.coll, users)
|
||||
}
|
||||
|
||||
func (u *UserMgo) UpdateByMap(ctx context.Context, userID string, args map[string]any) (err error) {
|
||||
if len(args) == 0 {
|
||||
return nil
|
||||
}
|
||||
return mgoutil.UpdateOne(ctx, u.coll, bson.M{"user_id": userID}, bson.M{"$set": args}, true)
|
||||
}
|
||||
|
||||
func (u *UserMgo) Find(ctx context.Context, userIDs []string) (users []*relation.UserModel, err error) {
|
||||
return mgoutil.Find[*relation.UserModel](ctx, u.coll, bson.M{"user_id": bson.M{"$in": userIDs}})
|
||||
}
|
||||
|
||||
func (u *UserMgo) Take(ctx context.Context, userID string) (user *relation.UserModel, err error) {
|
||||
return mgoutil.FindOne[*relation.UserModel](ctx, u.coll, bson.M{"user_id": userID})
|
||||
}
|
||||
|
||||
func (u *UserMgo) Page(ctx context.Context, pagination pagination.Pagination) (count int64, users []*relation.UserModel, err error) {
|
||||
return mgoutil.FindPage[*relation.UserModel](ctx, u.coll, bson.M{}, 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}))
|
||||
}
|
||||
|
||||
func (u *UserMgo) Exist(ctx context.Context, userID string) (exist bool, err error) {
|
||||
return mgoutil.Exist(ctx, u.coll, bson.M{"user_id": userID})
|
||||
}
|
||||
|
||||
func (u *UserMgo) GetUserGlobalRecvMsgOpt(ctx context.Context, userID string) (opt int, err error) {
|
||||
return mgoutil.FindOne[int](ctx, u.coll, bson.M{"user_id": userID}, options.FindOne().SetProjection(bson.M{"global_recv_msg_opt": 1}))
|
||||
}
|
||||
|
||||
func (u *UserMgo) CountTotal(ctx context.Context, before *time.Time) (count int64, err error) {
|
||||
if before == nil {
|
||||
return mgoutil.Count(ctx, u.coll, bson.M{})
|
||||
}
|
||||
return mgoutil.Count(ctx, u.coll, bson.M{"create_time": bson.M{"$lt": before}})
|
||||
}
|
||||
|
||||
func (u *UserMgo) CountRangeEverydayTotal(ctx context.Context, start time.Time, end time.Time) (map[string]int64, error) {
|
||||
pipeline := bson.A{
|
||||
bson.M{
|
||||
"$match": bson.M{
|
||||
"create_time": bson.M{
|
||||
"$gte": start,
|
||||
"$lt": end,
|
||||
},
|
||||
},
|
||||
},
|
||||
bson.M{
|
||||
"$group": bson.M{
|
||||
"_id": bson.M{
|
||||
"$dateToString": bson.M{
|
||||
"format": "%Y-%m-%d",
|
||||
"date": "$create_time",
|
||||
},
|
||||
},
|
||||
"count": bson.M{
|
||||
"$sum": 1,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
type Item struct {
|
||||
Date string `bson:"_id"`
|
||||
Count int64 `bson:"count"`
|
||||
}
|
||||
items, err := mgoutil.Aggregate[Item](ctx, u.coll, pipeline)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
res := make(map[string]int64, len(items))
|
||||
for _, item := range items {
|
||||
res[item.Date] = item.Count
|
||||
}
|
||||
return res, nil
|
||||
}
|
||||
@@ -1,111 +0,0 @@
|
||||
// Copyright © 2023 OpenIM. All rights reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package relation
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/OpenIMSDK/tools/errs"
|
||||
|
||||
"github.com/OpenIMSDK/tools/ormutil"
|
||||
|
||||
"gorm.io/gorm"
|
||||
|
||||
"github.com/OpenIMSDK/tools/utils"
|
||||
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation"
|
||||
)
|
||||
|
||||
type BlackGorm struct {
|
||||
*MetaDB
|
||||
}
|
||||
|
||||
func NewBlackGorm(db *gorm.DB) relation.BlackModelInterface {
|
||||
return &BlackGorm{NewMetaDB(db, &relation.BlackModel{})}
|
||||
}
|
||||
|
||||
func (b *BlackGorm) Create(ctx context.Context, blacks []*relation.BlackModel) (err error) {
|
||||
return utils.Wrap(b.db(ctx).Create(&blacks).Error, "")
|
||||
}
|
||||
|
||||
func (b *BlackGorm) Delete(ctx context.Context, blacks []*relation.BlackModel) (err error) {
|
||||
return utils.Wrap(b.db(ctx).Delete(blacks).Error, "")
|
||||
}
|
||||
|
||||
func (b *BlackGorm) UpdateByMap(
|
||||
ctx context.Context,
|
||||
ownerUserID, blockUserID string,
|
||||
args map[string]interface{},
|
||||
) (err error) {
|
||||
return utils.Wrap(
|
||||
b.db(ctx).Where("block_user_id = ? and block_user_id = ?", ownerUserID, blockUserID).Updates(args).Error,
|
||||
"",
|
||||
)
|
||||
}
|
||||
|
||||
func (b *BlackGorm) Update(ctx context.Context, blacks []*relation.BlackModel) (err error) {
|
||||
return utils.Wrap(b.db(ctx).Updates(&blacks).Error, "")
|
||||
}
|
||||
|
||||
func (b *BlackGorm) Find(
|
||||
ctx context.Context,
|
||||
blacks []*relation.BlackModel,
|
||||
) (blackList []*relation.BlackModel, err error) {
|
||||
var where [][]interface{}
|
||||
for _, black := range blacks {
|
||||
where = append(where, []interface{}{black.OwnerUserID, black.BlockUserID})
|
||||
}
|
||||
return blackList, utils.Wrap(
|
||||
b.db(ctx).Where("(owner_user_id, block_user_id) in ?", where).Find(&blackList).Error,
|
||||
"",
|
||||
)
|
||||
}
|
||||
|
||||
func (b *BlackGorm) Take(ctx context.Context, ownerUserID, blockUserID string) (black *relation.BlackModel, err error) {
|
||||
black = &relation.BlackModel{}
|
||||
return black, utils.Wrap(
|
||||
b.db(ctx).Where("owner_user_id = ? and block_user_id = ?", ownerUserID, blockUserID).Take(black).Error,
|
||||
"",
|
||||
)
|
||||
}
|
||||
|
||||
func (b *BlackGorm) FindOwnerBlacks(
|
||||
ctx context.Context,
|
||||
ownerUserID string,
|
||||
pageNumber, showNumber int32,
|
||||
) (blacks []*relation.BlackModel, total int64, err error) {
|
||||
err = b.db(ctx).Count(&total).Error
|
||||
if err != nil {
|
||||
return nil, 0, utils.Wrap(err, "")
|
||||
}
|
||||
totalUint32, blacks, err := ormutil.GormPage[relation.BlackModel](
|
||||
b.db(ctx).Where("owner_user_id = ?", ownerUserID),
|
||||
pageNumber,
|
||||
showNumber,
|
||||
)
|
||||
total = int64(totalUint32)
|
||||
return
|
||||
}
|
||||
|
||||
func (b *BlackGorm) FindBlackUserIDs(ctx context.Context, ownerUserID string) (blackUserIDs []string, err error) {
|
||||
return blackUserIDs, utils.Wrap(
|
||||
b.db(ctx).Where("owner_user_id = ?", ownerUserID).Pluck("block_user_id", &blackUserIDs).Error,
|
||||
"",
|
||||
)
|
||||
}
|
||||
|
||||
func (b *BlackGorm) FindOwnerBlackInfos(ctx context.Context, ownerUserID string, userIDs []string) (blacks []*relation.BlackModel, err error) {
|
||||
return blacks, errs.Wrap(b.db(ctx).Where("owner_user_id = ? and block_user_id in ?", ownerUserID, userIDs).Find(&blacks).Error)
|
||||
}
|
||||
@@ -1,63 +0,0 @@
|
||||
// Copyright © 2023 OpenIM. All rights reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package relation
|
||||
|
||||
import (
|
||||
"github.com/golang/protobuf/jsonpb"
|
||||
"github.com/jinzhu/copier"
|
||||
"google.golang.org/protobuf/proto"
|
||||
"gorm.io/gorm"
|
||||
|
||||
"github.com/OpenIMSDK/protocol/constant"
|
||||
pbmsg "github.com/OpenIMSDK/protocol/msg"
|
||||
sdkws "github.com/OpenIMSDK/protocol/sdkws"
|
||||
"github.com/OpenIMSDK/tools/utils"
|
||||
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation"
|
||||
)
|
||||
|
||||
type ChatLogGorm struct {
|
||||
*MetaDB
|
||||
}
|
||||
|
||||
func NewChatLogGorm(db *gorm.DB) relation.ChatLogModelInterface {
|
||||
return &ChatLogGorm{NewMetaDB(db, &relation.ChatLogModel{})}
|
||||
}
|
||||
|
||||
func (c *ChatLogGorm) Create(msg *pbmsg.MsgDataToMQ) error {
|
||||
chatLog := new(relation.ChatLogModel)
|
||||
copier.Copy(chatLog, msg.MsgData)
|
||||
switch msg.MsgData.SessionType {
|
||||
case constant.GroupChatType, constant.SuperGroupChatType:
|
||||
chatLog.RecvID = msg.MsgData.GroupID
|
||||
case constant.SingleChatType:
|
||||
chatLog.RecvID = msg.MsgData.RecvID
|
||||
}
|
||||
if msg.MsgData.ContentType >= constant.NotificationBegin && msg.MsgData.ContentType <= constant.NotificationEnd {
|
||||
var tips sdkws.TipsComm
|
||||
_ = proto.Unmarshal(msg.MsgData.Content, &tips)
|
||||
marshaler := jsonpb.Marshaler{
|
||||
OrigName: true,
|
||||
EnumsAsInts: false,
|
||||
EmitDefaults: false,
|
||||
}
|
||||
chatLog.Content, _ = marshaler.MarshalToString(&tips)
|
||||
} else {
|
||||
chatLog.Content = string(msg.MsgData.Content)
|
||||
}
|
||||
chatLog.CreateTime = utils.UnixMillSecondToTime(msg.MsgData.CreateTime)
|
||||
chatLog.SendTime = utils.UnixMillSecondToTime(msg.MsgData.SendTime)
|
||||
return c.DB.Create(chatLog).Error
|
||||
}
|
||||
@@ -1,250 +0,0 @@
|
||||
// Copyright © 2023 OpenIM. All rights reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package relation
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/OpenIMSDK/tools/errs"
|
||||
"gorm.io/gorm"
|
||||
|
||||
"github.com/OpenIMSDK/protocol/constant"
|
||||
"github.com/OpenIMSDK/tools/utils"
|
||||
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation"
|
||||
)
|
||||
|
||||
type ConversationGorm struct {
|
||||
*MetaDB
|
||||
}
|
||||
|
||||
func NewConversationGorm(db *gorm.DB) relation.ConversationModelInterface {
|
||||
return &ConversationGorm{NewMetaDB(db, &relation.ConversationModel{})}
|
||||
}
|
||||
|
||||
func (c *ConversationGorm) NewTx(tx any) relation.ConversationModelInterface {
|
||||
return &ConversationGorm{NewMetaDB(tx.(*gorm.DB), &relation.ConversationModel{})}
|
||||
}
|
||||
|
||||
func (c *ConversationGorm) Create(ctx context.Context, conversations []*relation.ConversationModel) (err error) {
|
||||
return utils.Wrap(c.db(ctx).Create(&conversations).Error, "")
|
||||
}
|
||||
|
||||
func (c *ConversationGorm) Delete(ctx context.Context, groupIDs []string) (err error) {
|
||||
return utils.Wrap(c.db(ctx).Where("group_id in (?)", groupIDs).Delete(&relation.ConversationModel{}).Error, "")
|
||||
}
|
||||
|
||||
func (c *ConversationGorm) UpdateByMap(
|
||||
ctx context.Context,
|
||||
userIDList []string,
|
||||
conversationID string,
|
||||
args map[string]interface{},
|
||||
) (rows int64, err error) {
|
||||
result := c.db(ctx).Where("owner_user_id IN (?) and conversation_id=?", userIDList, conversationID).Updates(args)
|
||||
return result.RowsAffected, utils.Wrap(result.Error, "")
|
||||
}
|
||||
|
||||
func (c *ConversationGorm) Update(ctx context.Context, conversation *relation.ConversationModel) (err error) {
|
||||
return utils.Wrap(
|
||||
c.db(ctx).
|
||||
Where("owner_user_id = ? and conversation_id = ?", conversation.OwnerUserID, conversation.ConversationID).
|
||||
Updates(conversation).
|
||||
Error,
|
||||
"",
|
||||
)
|
||||
}
|
||||
|
||||
func (c *ConversationGorm) Find(
|
||||
ctx context.Context,
|
||||
ownerUserID string,
|
||||
conversationIDs []string,
|
||||
) (conversations []*relation.ConversationModel, err error) {
|
||||
err = utils.Wrap(
|
||||
c.db(ctx).
|
||||
Where("owner_user_id=? and conversation_id IN (?)", ownerUserID, conversationIDs).
|
||||
Find(&conversations).
|
||||
Error,
|
||||
"",
|
||||
)
|
||||
return conversations, err
|
||||
}
|
||||
|
||||
func (c *ConversationGorm) Take(
|
||||
ctx context.Context,
|
||||
userID, conversationID string,
|
||||
) (conversation *relation.ConversationModel, err error) {
|
||||
cc := &relation.ConversationModel{}
|
||||
return cc, utils.Wrap(
|
||||
c.db(ctx).Where("conversation_id = ? And owner_user_id = ?", conversationID, userID).Take(cc).Error,
|
||||
"",
|
||||
)
|
||||
}
|
||||
|
||||
func (c *ConversationGorm) FindUserID(
|
||||
ctx context.Context,
|
||||
userIDs []string,
|
||||
conversationIDs []string,
|
||||
) (existUserID []string, err error) {
|
||||
return existUserID, utils.Wrap(
|
||||
c.db(ctx).
|
||||
Where(" owner_user_id IN (?) and conversation_id in (?)", userIDs, conversationIDs).
|
||||
Pluck("owner_user_id", &existUserID).
|
||||
Error,
|
||||
"",
|
||||
)
|
||||
}
|
||||
|
||||
func (c *ConversationGorm) FindConversationID(
|
||||
ctx context.Context,
|
||||
userID string,
|
||||
conversationIDList []string,
|
||||
) (existConversationID []string, err error) {
|
||||
return existConversationID, utils.Wrap(
|
||||
c.db(ctx).
|
||||
Where(" conversation_id IN (?) and owner_user_id=?", conversationIDList, userID).
|
||||
Pluck("conversation_id", &existConversationID).
|
||||
Error,
|
||||
"",
|
||||
)
|
||||
}
|
||||
|
||||
func (c *ConversationGorm) FindUserIDAllConversationID(
|
||||
ctx context.Context,
|
||||
userID string,
|
||||
) (conversationIDList []string, err error) {
|
||||
return conversationIDList, utils.Wrap(
|
||||
c.db(ctx).Where("owner_user_id=?", userID).Pluck("conversation_id", &conversationIDList).Error,
|
||||
"",
|
||||
)
|
||||
}
|
||||
|
||||
func (c *ConversationGorm) FindUserIDAllConversations(
|
||||
ctx context.Context,
|
||||
userID string,
|
||||
) (conversations []*relation.ConversationModel, err error) {
|
||||
return conversations, utils.Wrap(c.db(ctx).Where("owner_user_id=?", userID).Find(&conversations).Error, "")
|
||||
}
|
||||
|
||||
func (c *ConversationGorm) FindRecvMsgNotNotifyUserIDs(
|
||||
ctx context.Context,
|
||||
groupID string,
|
||||
) (userIDs []string, err error) {
|
||||
return userIDs, utils.Wrap(
|
||||
c.db(ctx).
|
||||
Where("group_id = ? and recv_msg_opt = ?", groupID, constant.ReceiveNotNotifyMessage).
|
||||
Pluck("owner_user_id", &userIDs).
|
||||
Error,
|
||||
"",
|
||||
)
|
||||
}
|
||||
|
||||
func (c *ConversationGorm) FindSuperGroupRecvMsgNotNotifyUserIDs(
|
||||
ctx context.Context,
|
||||
groupID string,
|
||||
) (userIDs []string, err error) {
|
||||
return userIDs, utils.Wrap(
|
||||
c.db(ctx).
|
||||
Where("group_id = ? and recv_msg_opt = ? and conversation_type = ?", groupID, constant.ReceiveNotNotifyMessage, constant.SuperGroupChatType).
|
||||
Pluck("owner_user_id", &userIDs).
|
||||
Error,
|
||||
"",
|
||||
)
|
||||
}
|
||||
|
||||
func (c *ConversationGorm) GetUserRecvMsgOpt(
|
||||
ctx context.Context,
|
||||
ownerUserID, conversationID string,
|
||||
) (opt int, err error) {
|
||||
var conversation relation.ConversationModel
|
||||
return int(
|
||||
conversation.RecvMsgOpt,
|
||||
), utils.Wrap(
|
||||
c.db(ctx).
|
||||
Where("conversation_id = ? And owner_user_id = ?", conversationID, ownerUserID).
|
||||
Select("recv_msg_opt").
|
||||
Find(&conversation).
|
||||
Error,
|
||||
"",
|
||||
)
|
||||
}
|
||||
|
||||
func (c *ConversationGorm) GetAllConversationIDs(ctx context.Context) (conversationIDs []string, err error) {
|
||||
return conversationIDs, utils.Wrap(
|
||||
c.db(ctx).Distinct("conversation_id").Pluck("conversation_id", &conversationIDs).Error,
|
||||
"",
|
||||
)
|
||||
}
|
||||
|
||||
func (c *ConversationGorm) GetAllConversationIDsNumber(ctx context.Context) (int64, error) {
|
||||
var num int64
|
||||
err := c.db(ctx).Select("COUNT(DISTINCT conversation_id)").Model(&relation.ConversationModel{}).Count(&num).Error
|
||||
return num, errs.Wrap(err)
|
||||
}
|
||||
|
||||
func (c *ConversationGorm) PageConversationIDs(ctx context.Context, pageNumber, showNumber int32) (conversationIDs []string, err error) {
|
||||
err = c.db(ctx).Distinct("conversation_id").Limit(int(showNumber)).Offset(int((pageNumber-1)*showNumber)).Pluck("conversation_id", &conversationIDs).Error
|
||||
err = errs.Wrap(err)
|
||||
return
|
||||
}
|
||||
|
||||
func (c *ConversationGorm) GetUserAllHasReadSeqs(
|
||||
ctx context.Context,
|
||||
ownerUserID string,
|
||||
) (hasReadSeqs map[string]int64, err error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (c *ConversationGorm) GetConversationsByConversationID(
|
||||
ctx context.Context,
|
||||
conversationIDs []string,
|
||||
) (conversations []*relation.ConversationModel, err error) {
|
||||
return conversations, utils.Wrap(
|
||||
c.db(ctx).Where("conversation_id IN (?)", conversationIDs).Find(&conversations).Error,
|
||||
"",
|
||||
)
|
||||
}
|
||||
|
||||
func (c *ConversationGorm) GetConversationIDsNeedDestruct(
|
||||
ctx context.Context,
|
||||
) (conversations []*relation.ConversationModel, err error) {
|
||||
return conversations, utils.Wrap(
|
||||
c.db(ctx).
|
||||
Where("is_msg_destruct = 1 && msg_destruct_time != 0 && (UNIX_TIMESTAMP(NOW()) > (msg_destruct_time + UNIX_TIMESTAMP(latest_msg_destruct_time)) || latest_msg_destruct_time is NULL)").
|
||||
Find(&conversations).
|
||||
Error,
|
||||
"",
|
||||
)
|
||||
}
|
||||
|
||||
func (c *ConversationGorm) GetConversationRecvMsgOpt(ctx context.Context, userID string, conversationID string) (int32, error) {
|
||||
var recvMsgOpt int32
|
||||
return recvMsgOpt, errs.Wrap(
|
||||
c.db(ctx).
|
||||
Model(&relation.ConversationModel{}).
|
||||
Where("conversation_id = ? and owner_user_id in ?", conversationID, userID).
|
||||
Pluck("recv_msg_opt", &recvMsgOpt).
|
||||
Error,
|
||||
)
|
||||
}
|
||||
|
||||
func (c *ConversationGorm) GetConversationNotReceiveMessageUserIDs(ctx context.Context, conversationID string) ([]string, error) {
|
||||
var userIDs []string
|
||||
return userIDs, errs.Wrap(
|
||||
c.db(ctx).
|
||||
Model(&relation.ConversationModel{}).
|
||||
Where("conversation_id = ? and recv_msg_opt <> ?", conversationID, constant.ReceiveMessage).
|
||||
Pluck("owner_user_id", &userIDs).Error,
|
||||
)
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
// Copyright © 2023 OpenIM. All rights reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package relation // import "github.com/openimsdk/open-im-server/v3/pkg/common/db/relation"
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user