diff --git a/.gitmodules b/.gitmodules
new file mode 100644
index 0000000..38e1b7c
--- /dev/null
+++ b/.gitmodules
@@ -0,0 +1,15 @@
+[submodule "ImRn"]
+ path = ImRn
+ url = https://gitea.51trust.net/xuqinmin/ImRn.git
+[submodule "ImWx"]
+ path = ImWx
+ url = https://gitea.51trust.net/xuqinmin/ImWx.git
+[submodule "ImJs"]
+ path = ImJs
+ url = https://gitea.51trust.net/xuqinmin/ImJs.git
+[submodule "ImServer"]
+ path = ImServer
+ url = https://gitea.51trust.net/xuqinmin/ImServer.git
+[submodule "ImAndroid"]
+ path = ImAndroid
+ url = https://gitea.51trust.net/xuqinmin/ImAndroid.git
diff --git a/ImAndroid b/ImAndroid
new file mode 160000
index 0000000..6d410f6
--- /dev/null
+++ b/ImAndroid
@@ -0,0 +1 @@
+Subproject commit 6d410f67a82344cd57763ead07a864447455258f
diff --git a/ImJs b/ImJs
new file mode 160000
index 0000000..e9a2271
--- /dev/null
+++ b/ImJs
@@ -0,0 +1 @@
+Subproject commit e9a227130643f13dc09955327fb5a2ee57b84ee0
diff --git a/ImRn b/ImRn
new file mode 160000
index 0000000..79256fb
--- /dev/null
+++ b/ImRn
@@ -0,0 +1 @@
+Subproject commit 79256fbb1b3a4fad1132ee149f4ab0e100067247
diff --git a/ImServer b/ImServer
new file mode 160000
index 0000000..2825898
--- /dev/null
+++ b/ImServer
@@ -0,0 +1 @@
+Subproject commit 282589852347d1155a84217a229a871c6f5ace6e
diff --git a/ImWx b/ImWx
new file mode 160000
index 0000000..94c9f58
--- /dev/null
+++ b/ImWx
@@ -0,0 +1 @@
+Subproject commit 94c9f58904fa665ea6d456166acc5d97ba870e9e
diff --git a/推送+IM(服务端).md b/推送+IM(服务端).md
new file mode 100644
index 0000000..b5a90d0
--- /dev/null
+++ b/推送+IM(服务端).md
@@ -0,0 +1,208 @@
+# 接口列表
+
+## 注册(register)
+
+### 请求参数
+
+```json
+{
+ "uuid": "设备唯一码,第一次安装应用时,生成存储与用户存储,后续开启查找该文档,如果存在则直接使用,不存在则重新生成存储。该方案可避免出现获取设备信息权限。",
+ "device": "Android、ios、pc、web、小程序...",
+ "username": "用户标识,该服务不对接用户体系,所以改标识作为用户唯一码使用。",
+ "pushToken": "厂商通道的推送id。"
+}
+
+```
+
+> 注册推送服务时`username`是否可以保证唯一。
+
+
+
+### 返回参数
+
+```json
+{
+ "account": "根据请求参数生成,用于登录im和声网"
+}
+```
+
+## 注销(logout)
+
+> 服务端删除(假)该uuid对应的account以及pushToken
+>
+> 保证当前设备不再收到消息,但是其它设备可以
+
+### 关闭随送
+
+> 关闭后,所有消息只走im,不再走厂商推送。
+>
+> 直观表现在与,app端如果不打开应用,则无法收到消息。
+
+
+
+## 离线消息转发与缓存
+
+> 其实可以理解为过滤,也是和谐功能的入口。
+>
+> 也是群消息的重组转发所在。
+>
+> ```json
+> {
+> "id": "bukjsafabsj4541536$#@",
+> "from": "user001",
+> "to": "推送开发组",
+> "target": "user001",
+> "type": "text",
+> "content": {
+> "text": ""
+> },
+> "timestamp": 1675416709033,
+> "isBackground": false
+> }
+>
+> ```
+>
+> ```json
+> {
+> "id": "bukjsafabsj4541536$#@",
+> "from": "推送开发组",
+> "to": "user002",
+> "target": "user001",
+> "type": "text",
+> "content": {
+> "text": ""
+> },
+> "timestamp": 1675416709033,
+> "isBackground": false
+> }
+>
+> ```
+>
+>
+>
+> 这里需要考虑,怎么能把account和username等信息关联起来,保证查询离线消息时候,可以把其它设备的消息同步查询出来,并且不会出现错乱。
+>
+> 注册推送服务时`username`是否可以保证唯一。
+
+
+
+## 和谐词配置
+
+>
+
+
+
+## 离线消息
+
+### 请求参数
+
+```json
+{
+ "timeStamp": "",
+ "account": ""
+}
+```
+
+> 返回所有缓存的离线消息,自`timeStamp`开始至当前消息
+>
+> 返回消息的方式,是直接走接口返回值携带,还是通过im发送。
+
+
+
+## 历史消息
+
+### 请求参数
+
+```json
+{
+ "startTimeStamp": "",
+ "endTimeStamp": "",
+ "account": "",
+ "target":""
+}
+```
+
+> `target`非必传,区分单个用户的消息,还是全部消息
+
+```json
+{
+ "timeStamp": "当前时间戳",
+ "account": "",
+ "target":"",
+ "start":1,
+ "end":10
+}
+```
+
+>从当前时间戳开始,向上查找第1到10条数据。
+>
+>使用场景,单聊上滑查看历史消息。
+
+
+
+
+
+## 发送消息
+
+> 应用对接,直接调用接口发消息
+>
+> 系统通知
+>
+> 部分业务变更通知
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/推送+IM.md b/推送+IM.md
new file mode 100644
index 0000000..251e29f
--- /dev/null
+++ b/推送+IM.md
@@ -0,0 +1,366 @@
+[TOC]
+
+> 消息协议需要调研一下,需求可以服务端转发消息
+
+
+
+# 消息体
+
+## 基础结构
+
+```json
+{
+ "id": "",
+ "from": "",
+ "to": "",
+ "tenantNo": "",
+ "target": "",
+ "type": "Type",
+ "content": {
+
+ },
+ "timestamp": 1675416709033,
+ "isBackground": false
+}
+
+```
+
+> 部分说明
+>
+> id 为发送端随机数,用来去重
+>
+> `单聊` -> from 发送者 to 接收者 服务器直接转发
+>
+> `群聊`-> 发送消息体:from发送者、to群、target接收者;接收消息体:from群、to接收者、target发送者
+
+
+
+### Type
+
+```java
+public enum MsgType {
+ UNKNOWN(-1), // 未知消息
+ TEXT(0), // 文本消息
+}
+```
+
+
+
+### 异常上报
+
+
+
+### 文本(text)
+
+```json
+{
+ "text": ""
+}
+```
+
+### 图片(image)
+
+```json
+{
+ "storageId": "",
+ "thumbnail": "",
+ "thumbnailWidth": 100,
+ "thumbnailHeight": 100
+}
+```
+
+### 语音(audio)
+
+```json
+{
+ "storageId": "",
+ "duration": 152
+}
+
+```
+
+### 视频
+
+```json
+{
+ "storageId": "",
+ "fileName": "",
+ "fileSize": "",
+ "duration": 100,
+ "thumbnail": "",
+ "thumbnailWidth": 100,
+ "thumbnailHeight": 100
+}
+
+```
+
+### 文件
+
+```json
+{
+ "storageId": "",
+ "fileName": "",
+ "fileSize": "",
+ "duration": 100,
+ "mimeType": "video/3gpp" // 非必须
+}
+
+```
+
+### 位置
+
+```json
+```
+
+### 通知
+
+```json
+{
+ "title": "",
+ "content": "",
+ "action": "",
+ "appid": "",
+ "appName": "",
+ "appLogo": "",
+ "url": ""
+}
+
+```
+
+### 后台运行
+
+> 组织架构类,大数据,后台更新
+>
+> 视频通话邀请
+
+```json
+{
+ "type": "",
+ "content": {}
+}
+```
+
+
+
+### 音视频通话
+
+
+```json
+{
+ "status": "",
+ "avType": "",
+ "uid": "",
+ "roomId": "",
+ "timestamp": 1675416709033,
+ "useTime": 1675416709033,
+ "agoraKey": 1675416709033
+}
+```
+
+>
+>status
+>
+> //邀请invite 拒绝refuse 取消cancel 超时timeout 占线busy
+>
+> // 已在其他设备接听other_answer(256推送消息)
+>
+> // 已在其他设备拒绝other_refuse(根据fromid == account判断)
+>
+> uid // 前端展示邀请人所用
+>
+> useTime //本地纪录的用时,单位秒
+>
+> agoraKey //声网key
+
+```java
+enum OsType {
+ IOS(1),
+ ANDROID(2),
+ WEB(3),
+ WINDOWS(4),
+ UNKNOWN(-1);
+}
+```
+
+
+
+### 应用消息
+
+> 区分子应用,提高分配效率
+>
+> 处方单
+
+```json
+{
+ "title": "",
+ "content": "",
+ "action": "",
+ "appid": "",
+ "appName": "",
+ "appLogo": "",
+ "url": ""
+}
+
+```
+
+
+
+### 扩展
+
+> 应对未定义消息,细微拓展。
+>
+
+```json
+{}
+```
+
+
+
+## 消息收发机制
+
+
+
+```mermaid
+sequenceDiagram
+Title: 基础流程(MQTT)
+actor APP
+actor SDK
+actor 服务端
+actor 厂商
+
+critical 启动
+ SDK -->> SDK: 获取设备信息、生成唯一码、获取对应厂商的pushTOken,缓存本地
+ APP ->> SDK: 服务初始化,提供userId
+ SDK ->> 服务端: 提供设备信息、唯一码、pushToken以及userId,注册im服务
+ 服务端 -->> 服务端: 保证每一个唯一码只有一个对应的pushToken等信息(历史唯一码标识只为注销),生成account。
+ 服务端 ->> SDK: 返回account,im服务器信息(域名,端口等)
+ SDK -->> SDK: 连接im服务,订阅account
+end
+
+critical 发送消息
+ APP ->> SDK: 发送消息api
+ SDK ->> 服务端: 整理消息发送
+ alt 单聊
+ 服务端->>服务端: 原消息留档后发送
+ else 群聊
+ 服务端->>服务端: 原消息留档后,重构消息,发送给群里所有人。
+ end
+ 服务端 ->> SDK: 消息送达
+ 服务端 ->> 厂商: 根据是否开启推送以及sdk是否在线,决定是否需要厂商推送
+ 厂商 ->> APP: 厂商推送
+ SDK ->> SDK: 去重(?修改状态,是同id消息,还是消息体体现)
、存表
+ SDK ->> APP: 通知消息送达
+ alt im推送
+ APP ->> APP: 根据实际情况,决定是直接使用通知里的消息,还是查表获取。
+ else 厂商推送
+ APP ->> APP: 点击通知栏动作(服务端可以配置)
+ end
+end
+
+critical 应用消息
+ Note right of 服务端: 第三方服务获取token(权限认证,类似有appId获取autoTOken之类)
+ Note right of 服务端: 设置群组api、标签api等
+ Note right of 服务端: 调用发送消息api
+ alt 单聊、群聊
+ 服务端->>服务端: 原消息留档后发送指定人员或者群组
+ else 所有人
+ 服务端->>服务端: 原消息留档后,发送到所有用户
+ end
+ 服务端 ->> SDK: 消息送达
+ 服务端 ->> 厂商: 根据是否开启推送以及sdk是否在线,决定是否需要厂商推送
+ 厂商 ->> APP: 厂商推送
+ SDK ->> SDK: 去重(?修改状态,是同id消息,还是消息体体现)
、存表
+ SDK ->> APP: 通知消息送达
+ alt im推送
+ APP ->> APP: 根据实际情况,决定是直接使用通知里的消息,还是查表获取。
+ else 厂商推送
+ APP ->> APP: 点击通知栏动作(服务端可以配置)
+ end
+end
+
+critical 历史消息、离线消息
+
+ alt 历史消息
+ APP ->> SDK: 获取离线消息api
+ SDK ->> 服务端: 获取离线消息(开始时间)
+ 服务端 ->> SDK: 消息送达
+ SDK ->> APP: 通知消息送达
+ APP ->> APP: 查表获取
+ else 离线消息
+ APP ->> SDK: 获取历史消息api
+ SDK ->> 服务端: 获取离线消息
+ 服务端 ->> 服务端: 根据target判断是获取所有还是单人
+ 服务端 ->> SDK: 消息送达
+ SDK ->> APP: 通知消息送达
+ APP ->> APP: 查表获取
+ end
+end
+
+critical 注销、停用推送
+ par 停用推送
+ APP ->> SDK: 请求关闭推送
+ SDK ->> 服务端: 请求关闭推送
+ 服务端 -->> 服务端: 关闭推送标识(或者直接删除pushtoken?)
+ and 注销
+ APP ->> SDK: 注销
+ SDK ->> 服务端: 注销
+ 服务端 -->> 服务端: 针对这个account对应的唯一码,修改状态为已注销
+ end
+end
+
+```
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/推送+IM.pdf b/推送+IM.pdf
new file mode 100644
index 0000000..a1b975e
Binary files /dev/null and b/推送+IM.pdf differ
diff --git a/推送速览.png b/推送速览.png
new file mode 100644
index 0000000..446fb5e
Binary files /dev/null and b/推送速览.png differ
diff --git a/条件结构流程图.pdf b/条件结构流程图.pdf
new file mode 100644
index 0000000..802e5a3
Binary files /dev/null and b/条件结构流程图.pdf differ