Full Code of danmuking/DiTing-Go for AI

main 2187d3b9da23 cached
147 files
412.3 KB
134.6k tokens
864 symbols
1 requests
Download .txt
Showing preview only (478K chars total). Download the full file or copy to clipboard to get everything.
Repository: danmuking/DiTing-Go
Branch: main
Commit: 2187d3b9da23
Files: 147
Total size: 412.3 KB

Directory structure:
gitextract_mkmm_a5b/

├── .github/
│   └── workflows/
│       └── reademe-contributors.yml
├── .gitignore
├── LICENSE
├── README.md
├── cmd/
│   └── gen/
│       └── generate.go
├── conf/
│   └── config_example.yml
├── controller/
│   ├── captcha_controller.go
│   ├── chat_controller.go
│   ├── contact_controller.go
│   ├── friend_controller.go
│   └── user_controller.go
├── dal/
│   ├── db.go
│   ├── model/
│   │   ├── contact.gen.go
│   │   ├── group_member.gen.go
│   │   ├── message.gen.go
│   │   ├── room.gen.go
│   │   ├── room_friend.gen.go
│   │   ├── room_group.gen.go
│   │   ├── user.gen.go
│   │   ├── user_apply.gen.go
│   │   └── user_friend.gen.go
│   └── query/
│       ├── contact.gen.go
│       ├── gen.go
│       ├── group_member.gen.go
│       ├── message.gen.go
│       ├── room.gen.go
│       ├── room_friend.gen.go
│       ├── room_group.gen.go
│       ├── user.gen.go
│       ├── user_apply.gen.go
│       └── user_friend.gen.go
├── docs/
│   ├── docs.go
│   └── swagger.json
├── domain/
│   ├── dto/
│   │   ├── contact_dto.go
│   │   ├── delete_friend_dto.go
│   │   ├── group_dto.go
│   │   └── msg_dto.go
│   ├── enum/
│   │   ├── event_bus.go
│   │   ├── login.go
│   │   ├── message.go
│   │   ├── redis.go
│   │   ├── redsync.go
│   │   ├── rocketmq.go
│   │   ├── room.go
│   │   └── user.go
│   ├── model/
│   │   └── message.go
│   └── vo/
│       ├── req/
│       │   ├── agree_friend_req.go
│       │   ├── captcha_req.go
│       │   ├── create_group_req.go
│       │   ├── delete_friend_req.go
│       │   ├── delete_group_req.go
│       │   ├── get_group_member_list_req.go
│       │   ├── get_message_list_req.go
│       │   ├── get_new_content_list_req.go
│       │   ├── get_new_msg_list_req.go
│       │   ├── get_user_info_batch_req.go
│       │   ├── get_user_info_by_name_req.go
│       │   ├── grant_administrator_req.go
│       │   ├── is_friend_req.go
│       │   ├── join_group_req.go
│       │   ├── message_req.go
│       │   ├── quit_group_req.go
│       │   ├── remove_administrator_req.go
│       │   ├── uid_req.go
│       │   ├── user_apply_req.go
│       │   ├── user_cancle_req.go
│       │   ├── user_login_req.go
│       │   └── user_register_req.go
│       └── resp/
│           ├── get_user_info_batch_resp.go
│           ├── get_user_info_by_name_resp.go
│           ├── message_resp.go
│           ├── page_list_resp.go
│           ├── pre_signed_resp.go
│           ├── user_apply_resp.go
│           ├── user_contact_resp.go
│           └── user_login_resp.go
├── event/
│   └── listener/
│       ├── friend_apply_event.go
│       ├── friend_delete_event.go
│       ├── friend_new_event.go
│       ├── new_msg_event.go
│       └── user_login_event.go
├── global/
│   ├── init_db.go
│   ├── init_distribute_lock.go
│   ├── init_evenbus.go
│   ├── init_log.go
│   ├── init_minio.go
│   ├── init_redis.go
│   ├── init_rocketmq.go
│   └── init_time.go
├── go.mod
├── go.sum
├── logic/
│   ├── captcha.go
│   ├── login.go
│   ├── register.go
│   ├── user.go
│   └── user_cancle.go
├── main.go
├── pkg/
│   ├── domain/
│   │   ├── enum/
│   │   │   ├── code.go
│   │   │   ├── common_enum.go
│   │   │   └── msg.go
│   │   └── vo/
│   │       ├── req/
│   │       │   └── page_req.go
│   │       └── resp/
│   │           ├── page_resp.go
│   │           └── response.go
│   └── utils/
│       ├── cursor_utils.go
│       ├── redis.go
│       ├── redis_lock.go
│       └── sort.go
├── routes/
│   └── init_router.go
├── service/
│   ├── adapter/
│   │   ├── build_contact_dao_list.go
│   │   ├── build_message_resp.go
│   │   └── build_user_info_by_name_resp.go
│   ├── captcha_service.go
│   ├── contact_service.go
│   ├── friend_service.go
│   ├── group_service.go
│   ├── message_service.go
│   ├── upload_service.go
│   ├── user_service.go
│   ├── user_service_integration_test.go
│   └── user_service_test.go
├── sql/
│   └── sql.sql
├── tests/
│   ├── README.md
│   ├── e2e/
│   │   └── user_workflow_e2e_test.go
│   ├── init_test.go
│   ├── integration/
│   │   └── user_integration_test.go
│   ├── performance/
│   │   └── user_performance_test.go
│   ├── scripts/
│   │   ├── run_e2e_test.sh
│   │   ├── run_tests.bat
│   │   ├── run_tests.sh
│   │   └── setup_test_env.sh
│   └── unit/
│       └── user_service_test.go
├── utils/
│   ├── jsonUtils/
│   │   └── json.go
│   ├── jwt/
│   │   ├── jwt.go
│   │   └── jwt_test.go
│   ├── middleware/
│   │   ├── cors.go
│   │   ├── jwt.go
│   │   └── log.go
│   ├── mysqlUtils.go
│   ├── passwordUtils.go
│   ├── redisCache/
│   │   └── remove_cache.go
│   ├── redisUtils.go
│   ├── setting/
│   │   └── setting.go
│   └── time_utils.go
└── websocket/
    ├── domain/
    │   ├── enum/
    │   │   └── ws_type.go
    │   └── vo/
    │       └── resp/
    │           └── new_message_resp.go
    ├── global/
    │   └── global.go
    └── service/
        └── websocket_service.go

================================================
FILE CONTENTS
================================================

================================================
FILE: .github/workflows/reademe-contributors.yml
================================================
on:
  push:
    branches:
      - main

name: Generate a list of contributors

jobs:
  contrib-readme-en-job:
    runs-on: ubuntu-latest
    name: A job to automate contrib in readme
    steps:
      - name: Contribute List
        uses: akhilmhdh/contributors-readme-action@v2.3.4
        env:
          GITHUB_TOKEN: ${{ secrets.CONTRIBUTORS_TOKEN }}


================================================
FILE: .gitignore
================================================
# If you prefer the allow list template instead of the deny list, see community template:
# https://github.com/github/gitignore/blob/main/community/Golang/Go.AllowList.gitignore
#
# Binaries for programs and plugins
/.idea/
*.exe
*.exe~
*.dll
*.so
*.dylib

# Test binary, built with `go test -c`
*.test

# Output of the go coverage tool, specifically when used with LiteIDE
*.out

# Dependency directories (remove the comment below to include it)
# vendor/

# Go workspace file
go.work
*.yml
*.yaml
*.log
/conf/config.yml
!/conf/config_example.yml
!/.github/workflows/reademe-contributors.yml


================================================
FILE: LICENSE
================================================
                                 Apache License
                           Version 2.0, January 2004
                        http://www.apache.org/licenses/

   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION

   1. Definitions.

      "License" shall mean the terms and conditions for use, reproduction,
      and distribution as defined by Sections 1 through 9 of this document.

      "Licensor" shall mean the copyright owner or entity authorized by
      the copyright owner that is granting the License.

      "Legal Entity" shall mean the union of the acting entity and all
      other entities that control, are controlled by, or are under common
      control with that entity. For the purposes of this definition,
      "control" means (i) the power, direct or indirect, to cause the
      direction or management of such entity, whether by contract or
      otherwise, or (ii) ownership of fifty percent (50%) or more of the
      outstanding shares, or (iii) beneficial ownership of such entity.

      "You" (or "Your") shall mean an individual or Legal Entity
      exercising permissions granted by this License.

      "Source" form shall mean the preferred form for making modifications,
      including but not limited to software source code, documentation
      source, and configuration files.

      "Object" form shall mean any form resulting from mechanical
      transformation or translation of a Source form, including but
      not limited to compiled object code, generated documentation,
      and conversions to other media types.

      "Work" shall mean the work of authorship, whether in Source or
      Object form, made available under the License, as indicated by a
      copyright notice that is included in or attached to the work
      (an example is provided in the Appendix below).

      "Derivative Works" shall mean any work, whether in Source or Object
      form, that is based on (or derived from) the Work and for which the
      editorial revisions, annotations, elaborations, or other modifications
      represent, as a whole, an original work of authorship. For the purposes
      of this License, Derivative Works shall not include works that remain
      separable from, or merely link (or bind by name) to the interfaces of,
      the Work and Derivative Works thereof.

      "Contribution" shall mean any work of authorship, including
      the original version of the Work and any modifications or additions
      to that Work or Derivative Works thereof, that is intentionally
      submitted to Licensor for inclusion in the Work by the copyright owner
      or by an individual or Legal Entity authorized to submit on behalf of
      the copyright owner. For the purposes of this definition, "submitted"
      means any form of electronic, verbal, or written communication sent
      to the Licensor or its representatives, including but not limited to
      communication on electronic mailing lists, source code control systems,
      and issue tracking systems that are managed by, or on behalf of, the
      Licensor for the purpose of discussing and improving the Work, but
      excluding communication that is conspicuously marked or otherwise
      designated in writing by the copyright owner as "Not a Contribution."

      "Contributor" shall mean Licensor and any individual or Legal Entity
      on behalf of whom a Contribution has been received by Licensor and
      subsequently incorporated within the Work.

   2. Grant of Copyright License. Subject to the terms and conditions of
      this License, each Contributor hereby grants to You a perpetual,
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
      copyright license to reproduce, prepare Derivative Works of,
      publicly display, publicly perform, sublicense, and distribute the
      Work and such Derivative Works in Source or Object form.

   3. Grant of Patent License. Subject to the terms and conditions of
      this License, each Contributor hereby grants to You a perpetual,
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
      (except as stated in this section) patent license to make, have made,
      use, offer to sell, sell, import, and otherwise transfer the Work,
      where such license applies only to those patent claims licensable
      by such Contributor that are necessarily infringed by their
      Contribution(s) alone or by combination of their Contribution(s)
      with the Work to which such Contribution(s) was submitted. If You
      institute patent litigation against any entity (including a
      cross-claim or counterclaim in a lawsuit) alleging that the Work
      or a Contribution incorporated within the Work constitutes direct
      or contributory patent infringement, then any patent licenses
      granted to You under this License for that Work shall terminate
      as of the date such litigation is filed.

   4. Redistribution. You may reproduce and distribute copies of the
      Work or Derivative Works thereof in any medium, with or without
      modifications, and in Source or Object form, provided that You
      meet the following conditions:

      (a) You must give any other recipients of the Work or
          Derivative Works a copy of this License; and

      (b) You must cause any modified files to carry prominent notices
          stating that You changed the files; and

      (c) You must retain, in the Source form of any Derivative Works
          that You distribute, all copyright, patent, trademark, and
          attribution notices from the Source form of the Work,
          excluding those notices that do not pertain to any part of
          the Derivative Works; and

      (d) If the Work includes a "NOTICE" text file as part of its
          distribution, then any Derivative Works that You distribute must
          include a readable copy of the attribution notices contained
          within such NOTICE file, excluding those notices that do not
          pertain to any part of the Derivative Works, in at least one
          of the following places: within a NOTICE text file distributed
          as part of the Derivative Works; within the Source form or
          documentation, if provided along with the Derivative Works; or,
          within a display generated by the Derivative Works, if and
          wherever such third-party notices normally appear. The contents
          of the NOTICE file are for informational purposes only and
          do not modify the License. You may add Your own attribution
          notices within Derivative Works that You distribute, alongside
          or as an addendum to the NOTICE text from the Work, provided
          that such additional attribution notices cannot be construed
          as modifying the License.

      You may add Your own copyright statement to Your modifications and
      may provide additional or different license terms and conditions
      for use, reproduction, or distribution of Your modifications, or
      for any such Derivative Works as a whole, provided Your use,
      reproduction, and distribution of the Work otherwise complies with
      the conditions stated in this License.

   5. Submission of Contributions. Unless You explicitly state otherwise,
      any Contribution intentionally submitted for inclusion in the Work
      by You to the Licensor shall be under the terms and conditions of
      this License, without any additional terms or conditions.
      Notwithstanding the above, nothing herein shall supersede or modify
      the terms of any separate license agreement you may have executed
      with Licensor regarding such Contributions.

   6. Trademarks. This License does not grant permission to use the trade
      names, trademarks, service marks, or product names of the Licensor,
      except as required for reasonable and customary use in describing the
      origin of the Work and reproducing the content of the NOTICE file.

   7. Disclaimer of Warranty. Unless required by applicable law or
      agreed to in writing, Licensor provides the Work (and each
      Contributor provides its Contributions) on an "AS IS" BASIS,
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
      implied, including, without limitation, any warranties or conditions
      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
      PARTICULAR PURPOSE. You are solely responsible for determining the
      appropriateness of using or redistributing the Work and assume any
      risks associated with Your exercise of permissions under this License.

   8. Limitation of Liability. In no event and under no legal theory,
      whether in tort (including negligence), contract, or otherwise,
      unless required by applicable law (such as deliberate and grossly
      negligent acts) or agreed to in writing, shall any Contributor be
      liable to You for damages, including any direct, indirect, special,
      incidental, or consequential damages of any character arising as a
      result of this License or out of the use or inability to use the
      Work (including but not limited to damages for loss of goodwill,
      work stoppage, computer failure or malfunction, or any and all
      other commercial damages or losses), even if such Contributor
      has been advised of the possibility of such damages.

   9. Accepting Warranty or Additional Liability. While redistributing
      the Work or Derivative Works thereof, You may choose to offer,
      and charge a fee for, acceptance of support, warranty, indemnity,
      or other liability obligations and/or rights consistent with this
      License. However, in accepting such obligations, You may act only
      on Your own behalf and on Your sole responsibility, not on behalf
      of any other Contributor, and only if You agree to indemnify,
      defend, and hold each Contributor harmless for any liability
      incurred by, or claims asserted against, such Contributor by reason
      of your accepting any such warranty or additional liability.

   END OF TERMS AND CONDITIONS

   APPENDIX: How to apply the Apache License to your work.

      To apply the Apache License to your work, attach the following
      boilerplate notice, with the fields enclosed by brackets "[]"
      replaced with your own identifying information. (Don't include
      the brackets!)  The text should be enclosed in the appropriate
      comment syntax for the file format. We also recommend that a
      file or class name and description of purpose be included on the
      same "printed page" as the copyright notice for easier
      identification within third-party archives.

   Copyright [yyyy] [name of copyright owner]

   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.


================================================
FILE: README.md
================================================
<div align=center>
<img src="./assets/logo.png"  width="40%"/>
</div>

![Static Badge](https://img.shields.io/badge/%E4%BA%A4%E6%B5%81%E7%BE%A4-%E5%8A%A0%E5%85%A5%E4%BA%A4%E6%B5%81-blue)
![Static Badge](https://img.shields.io/badge/github-%E9%A1%B9%E7%9B%AE%E5%9C%B0%E5%9D%80-blue)
![Static Badge](https://img.shields.io/badge/%E7%A0%81%E4%BA%91-%E9%A1%B9%E7%9B%AE%E5%9C%B0%E5%9D%80-blue)
![Static Badge](https://img.shields.io/badge/Issues-0_open-blue)
![Static Badge](https://img.shields.io/badge/License-Apache_License_2.0-blue)
# DiTing:初学者的第一个 IM 项目
欢迎来到 DiTing!这是一个简单、轻量级的即时通讯(IM)开源项目,采用 Go 编写,严格遵守互联网开发标准。致力于为初学者提供一个友好、易于上手的 IM 解决方案,让你可以轻松入门并开始构建自己的即时通讯应用。

## 项目导航
- 学习文档:[DiTing文档](https://danmuking.github.io/)
- 项目交流群:🎉 欢迎加入 DiTing 交流群!这是一个与其他开发者交流、分享经验和获取项目相关支持的地方。在这里你可以不仅可以提出遇到的任何问题,同时欢迎你与其他开发者交流并且对DiTing提出任何建议!
- 码云仓库:[Gitee](https://gitee.com/danmuking/DiTing-Go)
- Github仓库:[Github](https://github.com/danmuking/DiTing-Go)
- 前端地址:[Github](https://github.com/danmuking/DiTingWeb)

### 界面展示
![app_1.png](./assets/app_1.png)
![app_1.png](./assets/app_2.png)
![app_1.png](./assets/app_3.png)
![app_1.png](./assets/app_4.png)

### 技术选型
| 技术          | 说明               | 官网 |
|-------------|------------------| ----------- |
| Gin         | web开发必备框架        |https://gin-gonic.com/|
| GORM        | ORM框架            |https://gorm.io/docs/index.html|
| GEN         | ORM自动生成工作        |https://gorm.io/docs/index.html|
| Redis       | 缓存加速,多数据结构支持业务功能 |https://redis.io|
| Jwt         | 用户登录,认证方案        |https://jwt.io|
| Swagger-UI	 | API文档生成工具        |https://github.com/swagger-api/swagger-ui|
| Redsync	    | GO的分布式锁工具        |https://github.com/go-redsync/redsync|
| RocketMQ	   | 低延迟、高并发、高可用、高可靠的分布式消息中间件        |https://rocketmq.apache.org/|

### Star 趋势
<img alt="Star History Chart" src="https://api.star-history.com/svg?repos=danmuking/DiTing-Go&type=Date"/>

### 贡献者

<!-- readme: collaborators,contributors -start -->
<table>
<tr>
    <td align="center">
        <a href="https://github.com/danmuking">
            <img src="https://avatars.githubusercontent.com/u/47711726?v=4" width="100;" alt="danmuking"/>
            <br />
            <sub><b>LinYi</b></sub>
        </a>
    </td>
    <td align="center">
        <a href="https://github.com/Soce1lo">
            <img src="https://avatars.githubusercontent.com/u/53263452?v=4" width="100;" alt="Soce1lo"/>
            <br />
            <sub><b>Soce1lo</b></sub>
        </a>
    </td>
    <td align="center">
        <a href="https://github.com/wangQuanYaa">
            <img src="https://avatars.githubusercontent.com/u/161594079?v=4" width="100;" alt="wangQuanYaa"/>
            <br />
            <sub><b>WangQuanYaa</b></sub>
        </a>
    </td></tr>
</table>
<!-- readme: collaborators,contributors -end -->

### 共建邀请
DiTing 项目不仅是一个简单的即时通讯解决方案,更是一个汇聚了热爱技术、追求卓越的开发者们的大家庭。我们拥有完整的社群体系,以及积极、友好的交流氛围,让每一位参与者都能在这里找到归属感,收获成长与快乐。

如果你对 DiTing 项目感兴趣,愿意贡献你的智慧和力量,我们非常欢迎你的加入!无论你是前端、后端、测试还是其他领域的开发者,都能在 DiTing 项目中找到你的舞台。你可以参与代码编写、功能优化、文档完善等各个方面的工作,与我们一起共同推动项目的进步。

同时,我们也非常欢迎非技术领域的朋友们加入我们的社群,分享你的想法和建议,帮助我们更好地完善项目和服务。

为了更好地联系和交流,你可以尝试添加我的微信,共同为 DiTing 项目的发展贡献力量。

### 作者
DanMu
如果你需要帮助,可以尝试添加我的微信,我会尽力帮助你。

<img alt="微信图片_20240328224833.jpg" src="./assets/微信图片_20240328230919.jpg" height="300"/>

### 捐赠
如果你觉得这个项目对你有帮助,你可以请作者喝一杯咖啡。

<img alt="微信图片_20240328224833.jpg" src="./assets/微信图片_20240328224833.jpg" height="300"/>
<img alt="微信图片_20240328224851.jpg" src="./assets/微信图片_20240328224851.jpg" height="300"/>

### 版权说明

该项目签署了MIT 授权许可,详情请参阅 [LICENSE.txt](./LICENSE)

### 鸣谢


[//]: # (- [GitHub Emoji Cheat Sheet]&#40;https://www.webpagefx.com/tools/emoji-cheat-sheet&#41;)

[//]: # (- [Img Shields]&#40;https://shields.io&#41;)

[//]: # (- [Choose an Open Source License]&#40;https://choosealicense.com&#41;)

[//]: # (- [GitHub Pages]&#40;https://pages.github.com&#41;)

[//]: # (- [Animate.css]&#40;https://daneden.github.io/animate.css&#41;)

[//]: # (- [xxxxxxxxxxxxxx]&#40;https://connoratherton.com/loaders&#41;)


================================================
FILE: cmd/gen/generate.go
================================================
package main

// gorm gen configure

import (
	_ "DiTing-Go/pkg/setting"
	"fmt"
	"github.com/spf13/viper"
	"gorm.io/driver/mysql"
	"gorm.io/gen"
	"gorm.io/gorm"
)

var MySQLDSN = fmt.Sprintf("%s:%s@tcp(%s:%s)/DiTing?charset=utf8mb4&parseTime=True", viper.GetString("mysql.username"), viper.GetString("mysql.password"), viper.GetString("mysql.host"), viper.GetString("mysql.port"))

func connectDB(dsn string) *gorm.DB {
	db, err := gorm.Open(mysql.Open(dsn))
	if err != nil {
		panic(fmt.Errorf("connect db fail: %w", err))
	}
	return db
}

func main() {
	println(MySQLDSN)
	// 指定生成代码的具体相对目录(相对当前文件),默认为:./query
	// 默认生成需要使用WithContext之后才可以查询的代码,但可以通过设置gen.WithoutContext禁用该模式
	g := gen.NewGenerator(gen.Config{
		// 默认会在 OutPath 目录生成CRUD代码,并且同目录下生成 model 包
		// 所以OutPath最终package不能设置为model,在有数据库表同步的情况下会产生冲突
		// 若一定要使用可以通过ModelPkgPath单独指定model package的名称
		OutPath: "./dal/query",
		/* ModelPkgPath: "dal/model"*/

		// gen.WithoutContext:禁用WithContext模式
		// gen.WithDefaultQuery:生成一个全局Query对象Q
		// gen.WithQueryInterface:生成Query接口
		Mode: gen.WithDefaultQuery | gen.WithQueryInterface,
	})

	// 通常复用项目中已有的SQL连接配置db(*gorm.DB)
	// 非必需,但如果需要复用连接时的gorm.Config或需要连接数据库同步表信息则必须设置
	g.UseDB(connectDB(MySQLDSN))

	// 从连接的数据库为所有表生成Model结构体和CRUD代码
	// 也可以手动指定需要生成代码的数据表
	g.ApplyBasic(g.GenerateAllTable()...)

	// 执行并生成代码
	g.Execute()
}


================================================
FILE: conf/config_example.yml
================================================
mysql:
  host: xxx.xxx.xxx.xx
  port: 3306
  username: diting
  password: diting
jwt:
  secret: diting
log:
  log_file_path: ./logs
  log_file_name: diting.log
minio:
  accessKey: xxx
  accessSecret: xxx
  endPoint: xxx.xxx.xxx.xxx:9000
  useSSL: false
redis:
  host: xxxx
  password: xxxxx
rocketmq:
  host: xxx.xxx.xxx.xxx:9000
  group: diting

================================================
FILE: controller/captcha_controller.go
================================================
package controller

import (
	"DiTing-Go/domain/vo/req"
	"DiTing-Go/pkg/domain/vo/resp"
	"DiTing-Go/service"
	"github.com/gin-gonic/gin"
)

func CaptchaController(c *gin.Context) {
	captchaReq := req.CaptchaReq{}
	if err := c.ShouldBind(&captchaReq); err != nil {
		resp.ErrorResponse(c, "参数错误")
		c.Abort()
		return
	}
	response, err := service.CaptchaService(captchaReq)
	if err != nil {
		c.Abort()
		resp.ReturnErrorResponse(c, response)
		return
	}
	resp.ReturnSuccessResponse(c, response)
}


================================================
FILE: controller/chat_controller.go
================================================
package controller

//
//import (
//	"DiTing-Go/domain/vo/req"
//	"DiTing-Go/pkg/domain/vo/resp"
//	"DiTing-Go/service"
//	"github.com/gin-gonic/gin"
//)
//
//func SendMessageController(c *gin.Context) {
//	uid := c.GetInt64("uid")
//	messageReq := req.MessageReq{}
//	if err := c.ShouldBind(&messageReq); err != nil { //ShouldBind()会自动推导
//		resp.ErrorResponse(c, "参数错误")
//		c.Abort()
//		return
//	}
//	response, err := service.SendTextMsgService(uid, messageReq)
//	if err != nil {
//		c.Abort()
//		resp.ReturnErrorResponse(c, response)
//		return
//	}
//	resp.ReturnSuccessResponse(c, response)
//}


================================================
FILE: controller/contact_controller.go
================================================
package controller

//
//import (
//	"DiTing-Go/domain/vo/req"
//	"DiTing-Go/global"
//	pkgReq "DiTing-Go/pkg/domain/vo/req"
//	"DiTing-Go/pkg/domain/vo/resp"
//	"DiTing-Go/service"
//	"github.com/gin-gonic/gin"
//)
//
//func GetUserInfoBatchController(c *gin.Context) {
//	getUserInfoBatchReq := req.GetUserInfoBatchReq{}
//	if err := c.ShouldBind(&getUserInfoBatchReq); err != nil {
//		resp.ErrorResponse(c, "参数错误")
//		c.Abort()
//		return
//	}
//	response, err := service.GetUserInfoBatchService(getUserInfoBatchReq)
//	if err != nil {
//		c.Abort()
//		resp.ReturnErrorResponse(c, response)
//		return
//	}
//	resp.ReturnSuccessResponse(c, response)
//	return
//}
//
//func GetContactListController(c *gin.Context) {
//	uid := c.GetInt64("uid")
//	// 游标翻页
//	// 默认值
//	var cursor *string = nil
//	var pageSize int = 20
//	pageRequest := pkgReq.PageReq{
//		Cursor:   cursor,
//		PageSize: pageSize,
//	}
//	if err := c.ShouldBindQuery(&pageRequest); err != nil { //ShouldBind()会自动推导
//		resp.ErrorResponse(c, "参数错误")
//		c.Abort()
//		return
//	}
//	response, err := service.GetContactListService(uid, pageRequest)
//	if err != nil {
//		c.Abort()
//		resp.ReturnErrorResponse(c, response)
//		return
//	}
//	resp.ReturnSuccessResponse(c, response)
//}
//
//func GetNewContactListController(c *gin.Context) {
//	uid := c.GetInt64("uid")
//
//	getNewContentListReq := req.GetNewContentListReq{}
//	if err := c.ShouldBindQuery(&getNewContentListReq); err != nil { //ShouldBind()会自动推导
//		resp.ErrorResponse(c, "参数错误")
//		c.Abort()
//		return
//	}
//	response, err := service.GetNewContactListService(uid, getNewContentListReq.Timestamp)
//	if err != nil {
//		c.Abort()
//		resp.ReturnErrorResponse(c, response)
//		return
//	}
//	resp.ReturnSuccessResponse(c, response)
//}
//
//func GetNewMsgListController(c *gin.Context) {
//
//	getNewMsgListReq := req.GetNewMsgListReq{}
//	if err := c.ShouldBindQuery(&getNewMsgListReq); err != nil { //ShouldBind()会自动推导
//		resp.ErrorResponse(c, "参数错误")
//		c.Abort()
//		return
//	}
//	response, err := service.GetNewMsgService(getNewMsgListReq.MsgId, getNewMsgListReq.RoomId)
//	if err != nil {
//		c.Abort()
//		resp.ReturnErrorResponse(c, response)
//		return
//	}
//	resp.ReturnSuccessResponse(c, response)
//}
//
//func CreateGroupController(c *gin.Context) {
//	uid := c.GetInt64("uid")
//	creatGroupReq := req.CreateGroupReq{}
//	if err := c.ShouldBind(&creatGroupReq); err != nil { //ShouldBind()会自动推导
//		resp.ErrorResponse(c, "参数错误")
//		global.Logger.Errorf("参数错误: %v", err)
//		c.Abort()
//		return
//	}
//	response, err := service.CreateGroupService(uid, creatGroupReq.UidList)
//	if err != nil {
//		c.Abort()
//		resp.ReturnErrorResponse(c, response)
//		return
//	}
//	resp.ReturnSuccessResponse(c, response)
//}


================================================
FILE: controller/friend_controller.go
================================================
package controller

//
//import (
//	"DiTing-Go/domain/vo/req"
//	pkgReq "DiTing-Go/pkg/domain/vo/req"
//	"DiTing-Go/pkg/domain/vo/resp"
//	"DiTing-Go/service"
//	"github.com/gin-gonic/gin"
//)
//
//// ApplyFriendController 添加好友
////
////	@Summary	添加好友
////	@Produce	json
////	@Param		uid	body		int					true	"好友uid"
////	@Param		msg	body		string				true	"验证消息"
////	@Success	200	{object}	resp.ResponseData	"成功"
////	@Failure	500	{object}	resp.ResponseData	"内部错误"
////	@Router		/api/user/add [post]
//func ApplyFriendController(c *gin.Context) {
//	uid := c.GetInt64("uid")
//	applyReq := req.UserApplyReq{}
//	if err := c.ShouldBind(&applyReq); err != nil {
//		resp.ErrorResponse(c, "参数错误")
//		c.Abort()
//		return
//	}
//	response, err := service.ApplyFriendService(uid, applyReq)
//	if err != nil {
//		c.Abort()
//		resp.ReturnErrorResponse(c, response)
//		return
//	}
//	resp.ReturnSuccessResponse(c, response)
//	return
//}
//
//// DeleteFriendController 删除好友
////
////	@Summary	删除好友
////	@Produce	json
////	@Param		uid	body		int					true	"好友uid"
////	@Success	200	{object}	resp.ResponseData	"成功"
////	@Failure	500	{object}	resp.ResponseData	"内部错误"
////	@Router		/api/user/delete/:uid [delete]
//func DeleteFriendController(c *gin.Context) {
//	uid := c.GetInt64("uid")
//	deleteFriendReq := req.DeleteFriendReq{}
//	if err := c.ShouldBind(&deleteFriendReq); err != nil {
//		resp.ErrorResponse(c, "参数错误")
//		return
//	}
//	response, err := service.DeleteFriendService(uid, deleteFriendReq)
//	if err != nil {
//		c.Abort()
//		resp.ReturnErrorResponse(c, response)
//		return
//	}
//	resp.ReturnSuccessResponse(c, response)
//}
//
//// AgreeFriendController 同意好友申请
////
////	@Summary	同意好友申请
////	@Produce	json
////	@Param		uid	body		int					true	"好友uid"
////	@Success	200	{object}	resp.ResponseData	"成功"
////	@Failure	500	{object}	resp.ResponseData	"内部错误"
////	@Router		/api/user/agree [put]
//func AgreeFriendController(c *gin.Context) {
//	uid := c.GetInt64("uid")
//	agreeFriendReq := req.AgreeFriendReq{}
//	if err := c.ShouldBind(&agreeFriendReq); err != nil { //ShouldBind()会自动推导
//		resp.ErrorResponse(c, "参数错误")
//		c.Abort()
//		return
//	}
//	response, err := service.AgreeFriendService(uid, agreeFriendReq.Uid)
//	if err != nil {
//		c.Abort()
//		resp.ReturnErrorResponse(c, response)
//		return
//	}
//	resp.ReturnSuccessResponse(c, response)
//}
//
//// GetUserApplyController 同意好友申请
////
////	@Summary	同意好友申请
////	@Produce	json
////	@Param		uid	body		int					true	"好友uid"
////	@Success	200	{object}	resp.ResponseData	"成功"
////	@Failure	500	{object}	resp.ResponseData	"内部错误"
////	@Router		/api/user/getApplyList [get]
//func GetUserApplyController(c *gin.Context) {
//	uid := c.GetInt64("uid")
//	pageRequest := pkgReq.PageReq{}
//	if err := c.ShouldBindQuery(&pageRequest); err != nil { //ShouldBind()会自动推导
//		resp.ErrorResponse(c, "参数错误")
//		return
//	}
//	response, err := service.GetUserApplyService(uid, pageRequest)
//	if err != nil {
//		c.Abort()
//		resp.ReturnErrorResponse(c, response)
//		return
//	}
//
//	resp.ReturnSuccessResponse(c, response)
//}
//
//// IsFriendController 是否为好友关系
////
////	@Summary	是否为好友关系
////	@Produce	json
////	@Param		uid	body		int					true	"好友uid"
////	@Success	200	{object}	resp.ResponseData	"成功"
////	@Failure	500	{object}	resp.ResponseData	"内部错误"
////	@Router		/api/user/isFriend/:friendUid [get]
//func IsFriendController(c *gin.Context) {
//	uid := c.GetInt64("uid")
//	isFriendReq := req.IsFriendReq{}
//	if err := c.ShouldBindUri(&isFriendReq); err != nil {
//		resp.ErrorResponse(c, "参数错误")
//		return
//	}
//	response, err := service.IsFriendService(uid, isFriendReq.FriendUid)
//	if err != nil {
//		c.Abort()
//		resp.ReturnErrorResponse(c, response)
//		return
//	}
//	resp.ReturnSuccessResponse(c, response)
//}
//
//// UnreadApplyNumController 好友申请未读数量
////
////	@Summary	好友申请未读数量
////	@Success	200			{object}	resp.ResponseData	"成功"
////	@Failure	500			{object}	resp.ResponseData	"内部错误"
////	@Router		/api/user/unreadApplyNum [get]
//func UnreadApplyNumController(c *gin.Context) {
//	uid := c.GetInt64("uid")
//
//	response, err := service.UnreadApplyNumService(uid)
//	if err != nil {
//		c.Abort()
//		resp.ReturnErrorResponse(c, response)
//		return
//	}
//	resp.ReturnSuccessResponse(c, response)
//}
//
//func GetFriendListController(c *gin.Context) {
//	uid := c.GetInt64("uid")
//	pageRequest := pkgReq.PageReq{}
//	if err := c.ShouldBindQuery(&pageRequest); err != nil { //ShouldBind()会自动推导
//		resp.ErrorResponse(c, "参数错误")
//		return
//	}
//	response, err := service.GetFriendListService(uid, pageRequest)
//	if err != nil {
//		c.Abort()
//		resp.ReturnErrorResponse(c, response)
//		return
//	}
//	resp.ReturnSuccessResponse(c, response)
//}
//
//// GetUserInfoByNameController 根据好友昵称搜索好友
//func GetUserInfoByNameController(c *gin.Context) {
//	uid := c.GetInt64("uid")
//	getUserInfoByNameReq := req.GetUserInfoByNameReq{}
//	if err := c.ShouldBindQuery(&getUserInfoByNameReq); err != nil { //ShouldBind()会自动推导
//		resp.ErrorResponse(c, "参数错误")
//		return
//	}
//	response, err := service.GetUserInfoByNameService(uid, getUserInfoByNameReq.Name)
//	if err != nil {
//		c.Abort()
//		resp.ReturnErrorResponse(c, response)
//		return
//	}
//	resp.ReturnSuccessResponse(c, response)
//}


================================================
FILE: controller/user_controller.go
================================================
package controller

import (
	"DiTing-Go/domain/vo/req"
	"DiTing-Go/pkg/domain/vo/resp"
	"DiTing-Go/service"
	"github.com/gin-gonic/gin"
)

// RegisterController 用户注册
//
//	@Summary	用户注册
//	@Produce	json
//	@Param		name		body		string				true	"用户名"
//	@Param		password	body		string				true	"密码"
//	@Param		phone		body		string				true	"手机号"
//	@Param		captcha		body		string				true	"验证码"
//	@Success	200			{object}	resp.ResponseData	"成功"
//	@Failure	500			{object}	resp.ResponseData	"内部错误"
//	@Router		/api/public/register [post]
func RegisterController(c *gin.Context) {
	userReq := req.UserRegisterReq{}
	if err := c.ShouldBind(&userReq); err != nil {
		resp.ErrorResponse(c, "参数错误")
		c.Abort()
		return
	}
	response, err := service.RegisterService(userReq)
	if err != nil {
		c.Abort()
		resp.ReturnErrorResponse(c, response)
		return
	}
	resp.ReturnSuccessResponse(c, response)
}

// LoginController 用户登录
//
//	@Summary	用户登录
//	@Produce	json
//	@Param		name		body		string				true	"用户名"
//	@Param		password	body		string				true	"密码"
//	@Success	200			{object}	resp.ResponseData	"成功"
//	@Failure	500			{object}	resp.ResponseData	"内部错误"
//	@Router		/api/public/login [post]
func LoginController(c *gin.Context) {
	userLogin := req.UserLoginReq{}
	if err := c.ShouldBind(&userLogin); err != nil { //ShouldBind()会自动推导
		resp.ErrorResponse(c, "参数错误")
		c.Abort()
		return
	}
	response, err := service.LoginService(userLogin)
	if err != nil {
		c.Abort()
		resp.ReturnErrorResponse(c, response)
		return
	}
	resp.ReturnSuccessResponse(c, response)
}

// CancelController 注销账户
//
//	@Summary	注销账户
//	@Produce	json
//	@Param		phone		body		string				true	"手机号"
//	@Success	200			{object}	resp.ResponseData	"成功"
//	@Failure	500			{object}	resp.ResponseData	"内部错误"
//	@Router		/api/public/login [post]
func CancelController(ctx *gin.Context) {
	userCancel := req.UserCancelReq{}
	if err := ctx.ShouldBind(&userCancel); err != nil {
		resp.ErrorResponse(ctx, "参数错误")
		ctx.Abort()
		return
	}
	response, err := service.CancelService(ctx, userCancel)
	if err != nil {
		ctx.Abort()
		resp.ReturnErrorResponse(ctx, response)
		return
	}
	resp.ReturnSuccessResponse(ctx, response)
}


================================================
FILE: dal/db.go
================================================
package dal

import (
	"fmt"
	"gorm.io/driver/mysql"
	"gorm.io/gorm"
)

var DB *gorm.DB

// ConnectDB 初始化数据库连接
func ConnectDB(dsn string) *gorm.DB {
	db, err := gorm.Open(mysql.Open(dsn))
	sqlDB, err := db.DB()
	// SetMaxIdleConns sets the maximum number of connections in the idle connection pool.
	sqlDB.SetMaxIdleConns(10)
	sqlDB.SetMaxOpenConns(100)
	if err != nil {
		panic(fmt.Errorf("connect db fail: %w", err))
	}
	return db
}


================================================
FILE: dal/model/contact.gen.go
================================================
// Code generated by gorm.io/gen. DO NOT EDIT.
// Code generated by gorm.io/gen. DO NOT EDIT.
// Code generated by gorm.io/gen. DO NOT EDIT.

package model

import (
	"time"
)

const TableNameContact = "contact"

// Contact 会话列表
type Contact struct {
	ID         int64     `gorm:"column:id;primaryKey;autoIncrement:true;comment:id" json:"id"`                             // id
	UID        int64     `gorm:"column:uid;not null;comment:uid" json:"uid"`                                               // uid
	RoomID     int64     `gorm:"column:room_id;not null;comment:房间id" json:"room_id"`                                      // 房间id
	ReadTime   time.Time `gorm:"column:read_time;not null;default:CURRENT_TIMESTAMP(3);comment:阅读到的时间" json:"read_time"`   // 阅读到的时间
	ActiveTime time.Time `gorm:"column:active_time;comment:会话内消息最后更新的时间(只有普通会话需要维护,全员会话不需要维护)" json:"active_time"`         // 会话内消息最后更新的时间(只有普通会话需要维护,全员会话不需要维护)
	LastMsgID  int64     `gorm:"column:last_msg_id;comment:会话最新消息id" json:"last_msg_id"`                                   // 会话最新消息id
	CreateTime time.Time `gorm:"column:create_time;not null;default:CURRENT_TIMESTAMP(3);comment:创建时间" json:"create_time"` // 创建时间
	UpdateTime time.Time `gorm:"column:update_time;not null;default:CURRENT_TIMESTAMP(3);comment:修改时间" json:"update_time"` // 修改时间
}

// TableName Contact's table name
func (*Contact) TableName() string {
	return TableNameContact
}


================================================
FILE: dal/model/group_member.gen.go
================================================
// Code generated by gorm.io/gen. DO NOT EDIT.
// Code generated by gorm.io/gen. DO NOT EDIT.
// Code generated by gorm.io/gen. DO NOT EDIT.

package model

import (
	"time"
)

const TableNameGroupMember = "group_member"

// GroupMember 群成员表
type GroupMember struct {
	ID         int64     `gorm:"column:id;primaryKey;autoIncrement:true;comment:id" json:"id"`                             // id
	GroupID    int64     `gorm:"column:group_id;not null;comment:群主id" json:"group_id"`                                    // 群主id
	UID        int64     `gorm:"column:uid;not null;comment:成员uid" json:"uid"`                                             // 成员uid
	Role       int32     `gorm:"column:role;not null;comment:成员角色 1群主 2管理员 3普通成员" json:"role"`                             // 成员角色 1群主 2管理员 3普通成员
	CreateTime time.Time `gorm:"column:create_time;not null;default:CURRENT_TIMESTAMP(3);comment:创建时间" json:"create_time"` // 创建时间
	UpdateTime time.Time `gorm:"column:update_time;not null;default:CURRENT_TIMESTAMP(3);comment:修改时间" json:"update_time"` // 修改时间
}

// TableName GroupMember's table name
func (*GroupMember) TableName() string {
	return TableNameGroupMember
}


================================================
FILE: dal/model/message.gen.go
================================================
// Code generated by gorm.io/gen. DO NOT EDIT.
// Code generated by gorm.io/gen. DO NOT EDIT.
// Code generated by gorm.io/gen. DO NOT EDIT.

package model

import (
	"time"
)

const TableNameMessage = "message"

// Message 消息表
type Message struct {
	ID           int64     `gorm:"column:id;primaryKey;autoIncrement:true;comment:id" json:"id"`                             // id
	RoomID       int64     `gorm:"column:room_id;not null;comment:会话表id" json:"room_id"`                                     // 会话表id
	FromUID      int64     `gorm:"column:from_uid;not null;comment:消息发送者uid" json:"from_uid"`                                // 消息发送者uid
	Content      string    `gorm:"column:content;comment:消息内容" json:"content"`                                               // 消息内容
	ReplyMsgID   int64     `gorm:"column:reply_msg_id;comment:回复的消息内容" json:"reply_msg_id"`                                  // 回复的消息内容
	DeleteStatus int32     `gorm:"column:delete_status;not null;comment:消息状态 0正常 1删除" json:"delete_status"`                  // 消息状态 0正常 1删除
	GapCount     int32     `gorm:"column:gap_count;comment:与回复的消息间隔多少条" json:"gap_count"`                                    // 与回复的消息间隔多少条
	Type         int32     `gorm:"column:type;default:1;comment:消息类型 1正常文本 2.撤回消息" json:"type"`                              // 消息类型 1正常文本 2.撤回消息
	Extra        string    `gorm:"column:extra;comment:扩展信息" json:"extra"`                                                   // 扩展信息
	CreateTime   time.Time `gorm:"column:create_time;not null;default:CURRENT_TIMESTAMP(3);comment:创建时间" json:"create_time"` // 创建时间
	UpdateTime   time.Time `gorm:"column:update_time;not null;default:CURRENT_TIMESTAMP(3);comment:修改时间" json:"update_time"` // 修改时间
}

// TableName Message's table name
func (*Message) TableName() string {
	return TableNameMessage
}


================================================
FILE: dal/model/room.gen.go
================================================
// Code generated by gorm.io/gen. DO NOT EDIT.
// Code generated by gorm.io/gen. DO NOT EDIT.
// Code generated by gorm.io/gen. DO NOT EDIT.

package model

import (
	"time"
)

const TableNameRoom = "room"

// Room 房间表
type Room struct {
	ID           int64     `gorm:"column:id;primaryKey;autoIncrement:true;comment:id" json:"id"`                                                    // id
	Type         int32     `gorm:"column:type;not null;comment:房间类型 1群聊 2单聊" json:"type"`                                                           // 房间类型 1群聊 2单聊
	HotFlag      int32     `gorm:"column:hot_flag;comment:是否全员展示 0否 1是" json:"hot_flag"`                                                            // 是否全员展示 0否 1是
	ActiveTime   time.Time `gorm:"column:active_time;not null;default:CURRENT_TIMESTAMP(3);comment:群最后消息的更新时间(热点群不需要写扩散,只更新这里)" json:"active_time"` // 群最后消息的更新时间(热点群不需要写扩散,只更新这里)
	LastMsgID    int64     `gorm:"column:last_msg_id;comment:会话中的最后一条消息id" json:"last_msg_id"`                                                      // 会话中的最后一条消息id
	ExtJSON      string    `gorm:"column:ext_json;comment:额外信息(根据不同类型房间有不同存储的东西)" json:"ext_json"`                                                  // 额外信息(根据不同类型房间有不同存储的东西)
	CreateTime   time.Time `gorm:"column:create_time;not null;default:CURRENT_TIMESTAMP(3);comment:创建时间" json:"create_time"`                        // 创建时间
	UpdateTime   time.Time `gorm:"column:update_time;not null;default:CURRENT_TIMESTAMP(3);comment:修改时间" json:"update_time"`                        // 修改时间
	DeleteStatus int32     `gorm:"column:delete_status;not null;comment:房间状态 0正常 1禁用(删好友了禁用)" json:"delete_status"`                                 // 房间状态 0正常 1禁用(删好友了禁用)
}

// TableName Room's table name
func (*Room) TableName() string {
	return TableNameRoom
}


================================================
FILE: dal/model/room_friend.gen.go
================================================
// Code generated by gorm.io/gen. DO NOT EDIT.
// Code generated by gorm.io/gen. DO NOT EDIT.
// Code generated by gorm.io/gen. DO NOT EDIT.

package model

import (
	"time"
)

const TableNameRoomFriend = "room_friend"

// RoomFriend 单聊房间表
type RoomFriend struct {
	ID           int64     `gorm:"column:id;primaryKey;autoIncrement:true;comment:id" json:"id"`                             // id
	RoomID       int64     `gorm:"column:room_id;not null;comment:房间id" json:"room_id"`                                      // 房间id
	Uid1         int64     `gorm:"column:uid1;not null;comment:uid1(更小的uid)" json:"uid1"`                                    // uid1(更小的uid)
	Uid2         int64     `gorm:"column:uid2;not null;comment:uid2(更大的uid)" json:"uid2"`                                    // uid2(更大的uid)
	RoomKey      string    `gorm:"column:room_key;not null;comment:房间key由两个uid拼接,先做排序uid1_uid2" json:"room_key"`             // 房间key由两个uid拼接,先做排序uid1_uid2
	DeleteStatus int32     `gorm:"column:delete_status;not null;comment:房间状态 0正常 1禁用(删好友了禁用)" json:"delete_status"`          // 房间状态 0正常 1禁用(删好友了禁用)
	CreateTime   time.Time `gorm:"column:create_time;not null;default:CURRENT_TIMESTAMP(3);comment:创建时间" json:"create_time"` // 创建时间
	UpdateTime   time.Time `gorm:"column:update_time;not null;default:CURRENT_TIMESTAMP(3);comment:修改时间" json:"update_time"` // 修改时间
}

// TableName RoomFriend's table name
func (*RoomFriend) TableName() string {
	return TableNameRoomFriend
}


================================================
FILE: dal/model/room_group.gen.go
================================================
// Code generated by gorm.io/gen. DO NOT EDIT.
// Code generated by gorm.io/gen. DO NOT EDIT.
// Code generated by gorm.io/gen. DO NOT EDIT.

package model

import (
	"time"
)

const TableNameRoomGroup = "room_group"

// RoomGroup 群聊房间表
type RoomGroup struct {
	ID           int64     `gorm:"column:id;primaryKey;autoIncrement:true;comment:id" json:"id"`                             // id
	RoomID       int64     `gorm:"column:room_id;not null;comment:房间id" json:"room_id"`                                      // 房间id
	Name         string    `gorm:"column:name;not null;comment:群名称" json:"name"`                                             // 群名称
	Avatar       string    `gorm:"column:avatar;not null;comment:群头像" json:"avatar"`                                         // 群头像
	ExtJSON      string    `gorm:"column:ext_json;comment:额外信息(根据不同类型房间有不同存储的东西)" json:"ext_json"`                           // 额外信息(根据不同类型房间有不同存储的东西)
	DeleteStatus int32     `gorm:"column:delete_status;not null;comment:逻辑删除(0-正常,1-删除)" json:"delete_status"`               // 逻辑删除(0-正常,1-删除)
	CreateTime   time.Time `gorm:"column:create_time;not null;default:CURRENT_TIMESTAMP(3);comment:创建时间" json:"create_time"` // 创建时间
	UpdateTime   time.Time `gorm:"column:update_time;not null;default:CURRENT_TIMESTAMP(3);comment:修改时间" json:"update_time"` // 修改时间
}

// TableName RoomGroup's table name
func (*RoomGroup) TableName() string {
	return TableNameRoomGroup
}


================================================
FILE: dal/model/user.gen.go
================================================
// Code generated by gorm.io/gen. DO NOT EDIT.
// Code generated by gorm.io/gen. DO NOT EDIT.
// Code generated by gorm.io/gen. DO NOT EDIT.

package model

import (
	"time"
)

const TableNameUser = "user"

// User 用户表
type User struct {
	ID           int64     `gorm:"column:id;primaryKey;autoIncrement:true;comment:用户id" json:"id"`                                  // 用户id
	Phone        string    `gorm:"column:phone;not null;comment:用户手机" json:"phone"`                                                 // 用户手机
	Password     string    `gorm:"column:password;not null;comment:用户密码" json:"password"`                                           // 用户密码
	Name         string    `gorm:"column:name;not null;comment:用户昵称" json:"name"`                                                   // 用户昵称
	Avatar       string    `gorm:"column:avatar;not null;comment:用户头像" json:"avatar"`                                               // 用户头像
	Sex          int32     `gorm:"column:sex;default:3;comment:性别 1为男性,2为女性,3未知" json:"sex"`                                        // 性别 1为男性,2为女性,3未知
	ActiveStatus int32     `gorm:"column:active_status;default:2;comment:在线状态 1在线 2离线" json:"active_status"`                        // 在线状态 1在线 2离线
	LastOptTime  time.Time `gorm:"column:last_opt_time;not null;default:CURRENT_TIMESTAMP(3);comment:最后上下线时间" json:"last_opt_time"` // 最后上下线时间
	IPInfo       string    `gorm:"column:ip_info;comment:ip信息,用于显示用户地理位置" json:"ip_info"`                                           // ip信息,用于显示用户地理位置
	ItemID       int64     `gorm:"column:item_id;comment:佩戴的徽章id" json:"item_id"`                                                   // 佩戴的徽章id
	Status       int32     `gorm:"column:status;default:1;comment:使用状态 1.正常 2禁用" json:"status"`                                     // 使用状态 1.正常 2禁用
	CreateTime   time.Time `gorm:"column:create_time;not null;default:CURRENT_TIMESTAMP(3);comment:创建时间" json:"create_time"`        // 创建时间
	UpdateTime   time.Time `gorm:"column:update_time;not null;default:CURRENT_TIMESTAMP(3);comment:修改时间" json:"update_time"`        // 修改时间
}

// TableName User's table name
func (*User) TableName() string {
	return TableNameUser
}


================================================
FILE: dal/model/user_apply.gen.go
================================================
// Code generated by gorm.io/gen. DO NOT EDIT.
// Code generated by gorm.io/gen. DO NOT EDIT.
// Code generated by gorm.io/gen. DO NOT EDIT.

package model

import (
	"time"
)

const TableNameUserApply = "user_apply"

// UserApply 用户申请表
type UserApply struct {
	ID         int64     `gorm:"column:id;primaryKey;autoIncrement:true;comment:id" json:"id"`                             // id
	UID        int64     `gorm:"column:uid;not null;comment:申请人uid" json:"uid"`                                            // 申请人uid
	Type       int32     `gorm:"column:type;not null;comment:申请类型 1加好友" json:"type"`                                       // 申请类型 1加好友
	TargetID   int64     `gorm:"column:target_id;not null;comment:接收人uid" json:"target_id"`                                // 接收人uid
	Msg        string    `gorm:"column:msg;not null;comment:申请信息" json:"msg"`                                              // 申请信息
	Status     int32     `gorm:"column:status;not null;comment:申请状态 1待审批 2同意" json:"status"`                               // 申请状态 1待审批 2同意
	ReadStatus int32     `gorm:"column:read_status;not null;comment:阅读状态 1未读 2已读" json:"read_status"`                      // 阅读状态 1未读 2已读
	CreateTime time.Time `gorm:"column:create_time;not null;default:CURRENT_TIMESTAMP(3);comment:创建时间" json:"create_time"` // 创建时间
	UpdateTime time.Time `gorm:"column:update_time;not null;default:CURRENT_TIMESTAMP(3);comment:修改时间" json:"update_time"` // 修改时间
}

// TableName UserApply's table name
func (*UserApply) TableName() string {
	return TableNameUserApply
}


================================================
FILE: dal/model/user_friend.gen.go
================================================
// Code generated by gorm.io/gen. DO NOT EDIT.
// Code generated by gorm.io/gen. DO NOT EDIT.
// Code generated by gorm.io/gen. DO NOT EDIT.

package model

import (
	"time"
)

const TableNameUserFriend = "user_friend"

// UserFriend 用户联系人表
type UserFriend struct {
	ID           int64     `gorm:"column:id;primaryKey;autoIncrement:true;comment:id" json:"id"`                             // id
	UID          int64     `gorm:"column:uid;not null;comment:uid" json:"uid"`                                               // uid
	FriendUID    int64     `gorm:"column:friend_uid;not null;comment:好友uid" json:"friend_uid"`                               // 好友uid
	DeleteStatus int32     `gorm:"column:delete_status;not null;comment:逻辑删除(0-正常,1-删除)" json:"delete_status"`               // 逻辑删除(0-正常,1-删除)
	CreateTime   time.Time `gorm:"column:create_time;not null;default:CURRENT_TIMESTAMP(3);comment:创建时间" json:"create_time"` // 创建时间
	UpdateTime   time.Time `gorm:"column:update_time;not null;default:CURRENT_TIMESTAMP(3);comment:修改时间" json:"update_time"` // 修改时间
}

// TableName UserFriend's table name
func (*UserFriend) TableName() string {
	return TableNameUserFriend
}


================================================
FILE: dal/query/contact.gen.go
================================================
// Code generated by gorm.io/gen. DO NOT EDIT.
// Code generated by gorm.io/gen. DO NOT EDIT.
// Code generated by gorm.io/gen. DO NOT EDIT.

package query

import (
	"context"

	"gorm.io/gorm"
	"gorm.io/gorm/clause"
	"gorm.io/gorm/schema"

	"gorm.io/gen"
	"gorm.io/gen/field"

	"gorm.io/plugin/dbresolver"

	"DiTing-Go/dal/model"
)

func newContact(db *gorm.DB, opts ...gen.DOOption) contact {
	_contact := contact{}

	_contact.contactDo.UseDB(db, opts...)
	_contact.contactDo.UseModel(&model.Contact{})

	tableName := _contact.contactDo.TableName()
	_contact.ALL = field.NewAsterisk(tableName)
	_contact.ID = field.NewInt64(tableName, "id")
	_contact.UID = field.NewInt64(tableName, "uid")
	_contact.RoomID = field.NewInt64(tableName, "room_id")
	_contact.ReadTime = field.NewTime(tableName, "read_time")
	_contact.ActiveTime = field.NewTime(tableName, "active_time")
	_contact.LastMsgID = field.NewInt64(tableName, "last_msg_id")
	_contact.CreateTime = field.NewTime(tableName, "create_time")
	_contact.UpdateTime = field.NewTime(tableName, "update_time")

	_contact.fillFieldMap()

	return _contact
}

// contact 会话列表
type contact struct {
	contactDo contactDo

	ALL        field.Asterisk
	ID         field.Int64 // id
	UID        field.Int64 // uid
	RoomID     field.Int64 // 房间id
	ReadTime   field.Time  // 阅读到的时间
	ActiveTime field.Time  // 会话内消息最后更新的时间(只有普通会话需要维护,全员会话不需要维护)
	LastMsgID  field.Int64 // 会话最新消息id
	CreateTime field.Time  // 创建时间
	UpdateTime field.Time  // 修改时间

	fieldMap map[string]field.Expr
}

func (c contact) Table(newTableName string) *contact {
	c.contactDo.UseTable(newTableName)
	return c.updateTableName(newTableName)
}

func (c contact) As(alias string) *contact {
	c.contactDo.DO = *(c.contactDo.As(alias).(*gen.DO))
	return c.updateTableName(alias)
}

func (c *contact) updateTableName(table string) *contact {
	c.ALL = field.NewAsterisk(table)
	c.ID = field.NewInt64(table, "id")
	c.UID = field.NewInt64(table, "uid")
	c.RoomID = field.NewInt64(table, "room_id")
	c.ReadTime = field.NewTime(table, "read_time")
	c.ActiveTime = field.NewTime(table, "active_time")
	c.LastMsgID = field.NewInt64(table, "last_msg_id")
	c.CreateTime = field.NewTime(table, "create_time")
	c.UpdateTime = field.NewTime(table, "update_time")

	c.fillFieldMap()

	return c
}

func (c *contact) WithContext(ctx context.Context) IContactDo { return c.contactDo.WithContext(ctx) }

func (c contact) TableName() string { return c.contactDo.TableName() }

func (c contact) Alias() string { return c.contactDo.Alias() }

func (c contact) Columns(cols ...field.Expr) gen.Columns { return c.contactDo.Columns(cols...) }

func (c *contact) GetFieldByName(fieldName string) (field.OrderExpr, bool) {
	_f, ok := c.fieldMap[fieldName]
	if !ok || _f == nil {
		return nil, false
	}
	_oe, ok := _f.(field.OrderExpr)
	return _oe, ok
}

func (c *contact) fillFieldMap() {
	c.fieldMap = make(map[string]field.Expr, 8)
	c.fieldMap["id"] = c.ID
	c.fieldMap["uid"] = c.UID
	c.fieldMap["room_id"] = c.RoomID
	c.fieldMap["read_time"] = c.ReadTime
	c.fieldMap["active_time"] = c.ActiveTime
	c.fieldMap["last_msg_id"] = c.LastMsgID
	c.fieldMap["create_time"] = c.CreateTime
	c.fieldMap["update_time"] = c.UpdateTime
}

func (c contact) clone(db *gorm.DB) contact {
	c.contactDo.ReplaceConnPool(db.Statement.ConnPool)
	return c
}

func (c contact) replaceDB(db *gorm.DB) contact {
	c.contactDo.ReplaceDB(db)
	return c
}

type contactDo struct{ gen.DO }

type IContactDo interface {
	gen.SubQuery
	Debug() IContactDo
	WithContext(ctx context.Context) IContactDo
	WithResult(fc func(tx gen.Dao)) gen.ResultInfo
	ReplaceDB(db *gorm.DB)
	ReadDB() IContactDo
	WriteDB() IContactDo
	As(alias string) gen.Dao
	Session(config *gorm.Session) IContactDo
	Columns(cols ...field.Expr) gen.Columns
	Clauses(conds ...clause.Expression) IContactDo
	Not(conds ...gen.Condition) IContactDo
	Or(conds ...gen.Condition) IContactDo
	Select(conds ...field.Expr) IContactDo
	Where(conds ...gen.Condition) IContactDo
	Order(conds ...field.Expr) IContactDo
	Distinct(cols ...field.Expr) IContactDo
	Omit(cols ...field.Expr) IContactDo
	Join(table schema.Tabler, on ...field.Expr) IContactDo
	LeftJoin(table schema.Tabler, on ...field.Expr) IContactDo
	RightJoin(table schema.Tabler, on ...field.Expr) IContactDo
	Group(cols ...field.Expr) IContactDo
	Having(conds ...gen.Condition) IContactDo
	Limit(limit int) IContactDo
	Offset(offset int) IContactDo
	Count() (count int64, err error)
	Scopes(funcs ...func(gen.Dao) gen.Dao) IContactDo
	Unscoped() IContactDo
	Create(values ...*model.Contact) error
	CreateInBatches(values []*model.Contact, batchSize int) error
	Save(values ...*model.Contact) error
	First() (*model.Contact, error)
	Take() (*model.Contact, error)
	Last() (*model.Contact, error)
	Find() ([]*model.Contact, error)
	FindInBatch(batchSize int, fc func(tx gen.Dao, batch int) error) (results []*model.Contact, err error)
	FindInBatches(result *[]*model.Contact, batchSize int, fc func(tx gen.Dao, batch int) error) error
	Pluck(column field.Expr, dest interface{}) error
	Delete(...*model.Contact) (info gen.ResultInfo, err error)
	Update(column field.Expr, value interface{}) (info gen.ResultInfo, err error)
	UpdateSimple(columns ...field.AssignExpr) (info gen.ResultInfo, err error)
	Updates(value interface{}) (info gen.ResultInfo, err error)
	UpdateColumn(column field.Expr, value interface{}) (info gen.ResultInfo, err error)
	UpdateColumnSimple(columns ...field.AssignExpr) (info gen.ResultInfo, err error)
	UpdateColumns(value interface{}) (info gen.ResultInfo, err error)
	UpdateFrom(q gen.SubQuery) gen.Dao
	Attrs(attrs ...field.AssignExpr) IContactDo
	Assign(attrs ...field.AssignExpr) IContactDo
	Joins(fields ...field.RelationField) IContactDo
	Preload(fields ...field.RelationField) IContactDo
	FirstOrInit() (*model.Contact, error)
	FirstOrCreate() (*model.Contact, error)
	FindByPage(offset int, limit int) (result []*model.Contact, count int64, err error)
	ScanByPage(result interface{}, offset int, limit int) (count int64, err error)
	Scan(result interface{}) (err error)
	Returning(value interface{}, columns ...string) IContactDo
	UnderlyingDB() *gorm.DB
	schema.Tabler
}

func (c contactDo) Debug() IContactDo {
	return c.withDO(c.DO.Debug())
}

func (c contactDo) WithContext(ctx context.Context) IContactDo {
	return c.withDO(c.DO.WithContext(ctx))
}

func (c contactDo) ReadDB() IContactDo {
	return c.Clauses(dbresolver.Read)
}

func (c contactDo) WriteDB() IContactDo {
	return c.Clauses(dbresolver.Write)
}

func (c contactDo) Session(config *gorm.Session) IContactDo {
	return c.withDO(c.DO.Session(config))
}

func (c contactDo) Clauses(conds ...clause.Expression) IContactDo {
	return c.withDO(c.DO.Clauses(conds...))
}

func (c contactDo) Returning(value interface{}, columns ...string) IContactDo {
	return c.withDO(c.DO.Returning(value, columns...))
}

func (c contactDo) Not(conds ...gen.Condition) IContactDo {
	return c.withDO(c.DO.Not(conds...))
}

func (c contactDo) Or(conds ...gen.Condition) IContactDo {
	return c.withDO(c.DO.Or(conds...))
}

func (c contactDo) Select(conds ...field.Expr) IContactDo {
	return c.withDO(c.DO.Select(conds...))
}

func (c contactDo) Where(conds ...gen.Condition) IContactDo {
	return c.withDO(c.DO.Where(conds...))
}

func (c contactDo) Order(conds ...field.Expr) IContactDo {
	return c.withDO(c.DO.Order(conds...))
}

func (c contactDo) Distinct(cols ...field.Expr) IContactDo {
	return c.withDO(c.DO.Distinct(cols...))
}

func (c contactDo) Omit(cols ...field.Expr) IContactDo {
	return c.withDO(c.DO.Omit(cols...))
}

func (c contactDo) Join(table schema.Tabler, on ...field.Expr) IContactDo {
	return c.withDO(c.DO.Join(table, on...))
}

func (c contactDo) LeftJoin(table schema.Tabler, on ...field.Expr) IContactDo {
	return c.withDO(c.DO.LeftJoin(table, on...))
}

func (c contactDo) RightJoin(table schema.Tabler, on ...field.Expr) IContactDo {
	return c.withDO(c.DO.RightJoin(table, on...))
}

func (c contactDo) Group(cols ...field.Expr) IContactDo {
	return c.withDO(c.DO.Group(cols...))
}

func (c contactDo) Having(conds ...gen.Condition) IContactDo {
	return c.withDO(c.DO.Having(conds...))
}

func (c contactDo) Limit(limit int) IContactDo {
	return c.withDO(c.DO.Limit(limit))
}

func (c contactDo) Offset(offset int) IContactDo {
	return c.withDO(c.DO.Offset(offset))
}

func (c contactDo) Scopes(funcs ...func(gen.Dao) gen.Dao) IContactDo {
	return c.withDO(c.DO.Scopes(funcs...))
}

func (c contactDo) Unscoped() IContactDo {
	return c.withDO(c.DO.Unscoped())
}

func (c contactDo) Create(values ...*model.Contact) error {
	if len(values) == 0 {
		return nil
	}
	return c.DO.Create(values)
}

func (c contactDo) CreateInBatches(values []*model.Contact, batchSize int) error {
	return c.DO.CreateInBatches(values, batchSize)
}

// Save : !!! underlying implementation is different with GORM
// The method is equivalent to executing the statement: db.Clauses(clause.OnConflict{UpdateAll: true}).Create(values)
func (c contactDo) Save(values ...*model.Contact) error {
	if len(values) == 0 {
		return nil
	}
	return c.DO.Save(values)
}

func (c contactDo) First() (*model.Contact, error) {
	if result, err := c.DO.First(); err != nil {
		return nil, err
	} else {
		return result.(*model.Contact), nil
	}
}

func (c contactDo) Take() (*model.Contact, error) {
	if result, err := c.DO.Take(); err != nil {
		return nil, err
	} else {
		return result.(*model.Contact), nil
	}
}

func (c contactDo) Last() (*model.Contact, error) {
	if result, err := c.DO.Last(); err != nil {
		return nil, err
	} else {
		return result.(*model.Contact), nil
	}
}

func (c contactDo) Find() ([]*model.Contact, error) {
	result, err := c.DO.Find()
	return result.([]*model.Contact), err
}

func (c contactDo) FindInBatch(batchSize int, fc func(tx gen.Dao, batch int) error) (results []*model.Contact, err error) {
	buf := make([]*model.Contact, 0, batchSize)
	err = c.DO.FindInBatches(&buf, batchSize, func(tx gen.Dao, batch int) error {
		defer func() { results = append(results, buf...) }()
		return fc(tx, batch)
	})
	return results, err
}

func (c contactDo) FindInBatches(result *[]*model.Contact, batchSize int, fc func(tx gen.Dao, batch int) error) error {
	return c.DO.FindInBatches(result, batchSize, fc)
}

func (c contactDo) Attrs(attrs ...field.AssignExpr) IContactDo {
	return c.withDO(c.DO.Attrs(attrs...))
}

func (c contactDo) Assign(attrs ...field.AssignExpr) IContactDo {
	return c.withDO(c.DO.Assign(attrs...))
}

func (c contactDo) Joins(fields ...field.RelationField) IContactDo {
	for _, _f := range fields {
		c = *c.withDO(c.DO.Joins(_f))
	}
	return &c
}

func (c contactDo) Preload(fields ...field.RelationField) IContactDo {
	for _, _f := range fields {
		c = *c.withDO(c.DO.Preload(_f))
	}
	return &c
}

func (c contactDo) FirstOrInit() (*model.Contact, error) {
	if result, err := c.DO.FirstOrInit(); err != nil {
		return nil, err
	} else {
		return result.(*model.Contact), nil
	}
}

func (c contactDo) FirstOrCreate() (*model.Contact, error) {
	if result, err := c.DO.FirstOrCreate(); err != nil {
		return nil, err
	} else {
		return result.(*model.Contact), nil
	}
}

func (c contactDo) FindByPage(offset int, limit int) (result []*model.Contact, count int64, err error) {
	result, err = c.Offset(offset).Limit(limit).Find()
	if err != nil {
		return
	}

	if size := len(result); 0 < limit && 0 < size && size < limit {
		count = int64(size + offset)
		return
	}

	count, err = c.Offset(-1).Limit(-1).Count()
	return
}

func (c contactDo) ScanByPage(result interface{}, offset int, limit int) (count int64, err error) {
	count, err = c.Count()
	if err != nil {
		return
	}

	err = c.Offset(offset).Limit(limit).Scan(result)
	return
}

func (c contactDo) Scan(result interface{}) (err error) {
	return c.DO.Scan(result)
}

func (c contactDo) Delete(models ...*model.Contact) (result gen.ResultInfo, err error) {
	return c.DO.Delete(models)
}

func (c *contactDo) withDO(do gen.Dao) *contactDo {
	c.DO = *do.(*gen.DO)
	return c
}


================================================
FILE: dal/query/gen.go
================================================
// Code generated by gorm.io/gen. DO NOT EDIT.
// Code generated by gorm.io/gen. DO NOT EDIT.
// Code generated by gorm.io/gen. DO NOT EDIT.

package query

import (
	"context"
	"database/sql"

	"gorm.io/gorm"

	"gorm.io/gen"

	"gorm.io/plugin/dbresolver"
)

var (
	Q    = new(Query)
	User *user
)

func SetDefault(db *gorm.DB, opts ...gen.DOOption) {
	*Q = *Use(db, opts...)
	User = &Q.User
}

func Use(db *gorm.DB, opts ...gen.DOOption) *Query {
	return &Query{
		db:   db,
		User: newUser(db, opts...),
	}
}

type Query struct {
	db *gorm.DB

	User user
}

func (q *Query) Available() bool { return q.db != nil }

func (q *Query) clone(db *gorm.DB) *Query {
	return &Query{
		db:   db,
		User: q.User.clone(db),
	}
}

func (q *Query) ReadDB() *Query {
	return q.ReplaceDB(q.db.Clauses(dbresolver.Read))
}

func (q *Query) WriteDB() *Query {
	return q.ReplaceDB(q.db.Clauses(dbresolver.Write))
}

func (q *Query) ReplaceDB(db *gorm.DB) *Query {
	return &Query{
		db:   db,
		User: q.User.replaceDB(db),
	}
}

type queryCtx struct {
	User IUserDo
}

func (q *Query) WithContext(ctx context.Context) *queryCtx {
	return &queryCtx{
		User: q.User.WithContext(ctx),
	}
}

func (q *Query) Transaction(fc func(tx *Query) error, opts ...*sql.TxOptions) error {
	return q.db.Transaction(func(tx *gorm.DB) error { return fc(q.clone(tx)) }, opts...)
}

func (q *Query) Begin(opts ...*sql.TxOptions) *QueryTx {
	tx := q.db.Begin(opts...)
	return &QueryTx{Query: q.clone(tx), Error: tx.Error}
}

type QueryTx struct {
	*Query
	Error error
}

func (q *QueryTx) Commit() error {
	return q.db.Commit().Error
}

func (q *QueryTx) Rollback() error {
	return q.db.Rollback().Error
}

func (q *QueryTx) SavePoint(name string) error {
	return q.db.SavePoint(name).Error
}

func (q *QueryTx) RollbackTo(name string) error {
	return q.db.RollbackTo(name).Error
}


================================================
FILE: dal/query/group_member.gen.go
================================================
// Code generated by gorm.io/gen. DO NOT EDIT.
// Code generated by gorm.io/gen. DO NOT EDIT.
// Code generated by gorm.io/gen. DO NOT EDIT.

package query

import (
	"context"

	"gorm.io/gorm"
	"gorm.io/gorm/clause"
	"gorm.io/gorm/schema"

	"gorm.io/gen"
	"gorm.io/gen/field"

	"gorm.io/plugin/dbresolver"

	"DiTing-Go/dal/model"
)

func newGroupMember(db *gorm.DB, opts ...gen.DOOption) groupMember {
	_groupMember := groupMember{}

	_groupMember.groupMemberDo.UseDB(db, opts...)
	_groupMember.groupMemberDo.UseModel(&model.GroupMember{})

	tableName := _groupMember.groupMemberDo.TableName()
	_groupMember.ALL = field.NewAsterisk(tableName)
	_groupMember.ID = field.NewInt64(tableName, "id")
	_groupMember.GroupID = field.NewInt64(tableName, "group_id")
	_groupMember.UID = field.NewInt64(tableName, "uid")
	_groupMember.Role = field.NewInt32(tableName, "role")
	_groupMember.CreateTime = field.NewTime(tableName, "create_time")
	_groupMember.UpdateTime = field.NewTime(tableName, "update_time")

	_groupMember.fillFieldMap()

	return _groupMember
}

// groupMember 群成员表
type groupMember struct {
	groupMemberDo groupMemberDo

	ALL        field.Asterisk
	ID         field.Int64 // id
	GroupID    field.Int64 // 群主id
	UID        field.Int64 // 成员uid
	Role       field.Int32 // 成员角色 1群主 2管理员 3普通成员
	CreateTime field.Time  // 创建时间
	UpdateTime field.Time  // 修改时间

	fieldMap map[string]field.Expr
}

func (g groupMember) Table(newTableName string) *groupMember {
	g.groupMemberDo.UseTable(newTableName)
	return g.updateTableName(newTableName)
}

func (g groupMember) As(alias string) *groupMember {
	g.groupMemberDo.DO = *(g.groupMemberDo.As(alias).(*gen.DO))
	return g.updateTableName(alias)
}

func (g *groupMember) updateTableName(table string) *groupMember {
	g.ALL = field.NewAsterisk(table)
	g.ID = field.NewInt64(table, "id")
	g.GroupID = field.NewInt64(table, "group_id")
	g.UID = field.NewInt64(table, "uid")
	g.Role = field.NewInt32(table, "role")
	g.CreateTime = field.NewTime(table, "create_time")
	g.UpdateTime = field.NewTime(table, "update_time")

	g.fillFieldMap()

	return g
}

func (g *groupMember) WithContext(ctx context.Context) IGroupMemberDo {
	return g.groupMemberDo.WithContext(ctx)
}

func (g groupMember) TableName() string { return g.groupMemberDo.TableName() }

func (g groupMember) Alias() string { return g.groupMemberDo.Alias() }

func (g groupMember) Columns(cols ...field.Expr) gen.Columns { return g.groupMemberDo.Columns(cols...) }

func (g *groupMember) GetFieldByName(fieldName string) (field.OrderExpr, bool) {
	_f, ok := g.fieldMap[fieldName]
	if !ok || _f == nil {
		return nil, false
	}
	_oe, ok := _f.(field.OrderExpr)
	return _oe, ok
}

func (g *groupMember) fillFieldMap() {
	g.fieldMap = make(map[string]field.Expr, 6)
	g.fieldMap["id"] = g.ID
	g.fieldMap["group_id"] = g.GroupID
	g.fieldMap["uid"] = g.UID
	g.fieldMap["role"] = g.Role
	g.fieldMap["create_time"] = g.CreateTime
	g.fieldMap["update_time"] = g.UpdateTime
}

func (g groupMember) clone(db *gorm.DB) groupMember {
	g.groupMemberDo.ReplaceConnPool(db.Statement.ConnPool)
	return g
}

func (g groupMember) replaceDB(db *gorm.DB) groupMember {
	g.groupMemberDo.ReplaceDB(db)
	return g
}

type groupMemberDo struct{ gen.DO }

type IGroupMemberDo interface {
	gen.SubQuery
	Debug() IGroupMemberDo
	WithContext(ctx context.Context) IGroupMemberDo
	WithResult(fc func(tx gen.Dao)) gen.ResultInfo
	ReplaceDB(db *gorm.DB)
	ReadDB() IGroupMemberDo
	WriteDB() IGroupMemberDo
	As(alias string) gen.Dao
	Session(config *gorm.Session) IGroupMemberDo
	Columns(cols ...field.Expr) gen.Columns
	Clauses(conds ...clause.Expression) IGroupMemberDo
	Not(conds ...gen.Condition) IGroupMemberDo
	Or(conds ...gen.Condition) IGroupMemberDo
	Select(conds ...field.Expr) IGroupMemberDo
	Where(conds ...gen.Condition) IGroupMemberDo
	Order(conds ...field.Expr) IGroupMemberDo
	Distinct(cols ...field.Expr) IGroupMemberDo
	Omit(cols ...field.Expr) IGroupMemberDo
	Join(table schema.Tabler, on ...field.Expr) IGroupMemberDo
	LeftJoin(table schema.Tabler, on ...field.Expr) IGroupMemberDo
	RightJoin(table schema.Tabler, on ...field.Expr) IGroupMemberDo
	Group(cols ...field.Expr) IGroupMemberDo
	Having(conds ...gen.Condition) IGroupMemberDo
	Limit(limit int) IGroupMemberDo
	Offset(offset int) IGroupMemberDo
	Count() (count int64, err error)
	Scopes(funcs ...func(gen.Dao) gen.Dao) IGroupMemberDo
	Unscoped() IGroupMemberDo
	Create(values ...*model.GroupMember) error
	CreateInBatches(values []*model.GroupMember, batchSize int) error
	Save(values ...*model.GroupMember) error
	First() (*model.GroupMember, error)
	Take() (*model.GroupMember, error)
	Last() (*model.GroupMember, error)
	Find() ([]*model.GroupMember, error)
	FindInBatch(batchSize int, fc func(tx gen.Dao, batch int) error) (results []*model.GroupMember, err error)
	FindInBatches(result *[]*model.GroupMember, batchSize int, fc func(tx gen.Dao, batch int) error) error
	Pluck(column field.Expr, dest interface{}) error
	Delete(...*model.GroupMember) (info gen.ResultInfo, err error)
	Update(column field.Expr, value interface{}) (info gen.ResultInfo, err error)
	UpdateSimple(columns ...field.AssignExpr) (info gen.ResultInfo, err error)
	Updates(value interface{}) (info gen.ResultInfo, err error)
	UpdateColumn(column field.Expr, value interface{}) (info gen.ResultInfo, err error)
	UpdateColumnSimple(columns ...field.AssignExpr) (info gen.ResultInfo, err error)
	UpdateColumns(value interface{}) (info gen.ResultInfo, err error)
	UpdateFrom(q gen.SubQuery) gen.Dao
	Attrs(attrs ...field.AssignExpr) IGroupMemberDo
	Assign(attrs ...field.AssignExpr) IGroupMemberDo
	Joins(fields ...field.RelationField) IGroupMemberDo
	Preload(fields ...field.RelationField) IGroupMemberDo
	FirstOrInit() (*model.GroupMember, error)
	FirstOrCreate() (*model.GroupMember, error)
	FindByPage(offset int, limit int) (result []*model.GroupMember, count int64, err error)
	ScanByPage(result interface{}, offset int, limit int) (count int64, err error)
	Scan(result interface{}) (err error)
	Returning(value interface{}, columns ...string) IGroupMemberDo
	UnderlyingDB() *gorm.DB
	schema.Tabler
}

func (g groupMemberDo) Debug() IGroupMemberDo {
	return g.withDO(g.DO.Debug())
}

func (g groupMemberDo) WithContext(ctx context.Context) IGroupMemberDo {
	return g.withDO(g.DO.WithContext(ctx))
}

func (g groupMemberDo) ReadDB() IGroupMemberDo {
	return g.Clauses(dbresolver.Read)
}

func (g groupMemberDo) WriteDB() IGroupMemberDo {
	return g.Clauses(dbresolver.Write)
}

func (g groupMemberDo) Session(config *gorm.Session) IGroupMemberDo {
	return g.withDO(g.DO.Session(config))
}

func (g groupMemberDo) Clauses(conds ...clause.Expression) IGroupMemberDo {
	return g.withDO(g.DO.Clauses(conds...))
}

func (g groupMemberDo) Returning(value interface{}, columns ...string) IGroupMemberDo {
	return g.withDO(g.DO.Returning(value, columns...))
}

func (g groupMemberDo) Not(conds ...gen.Condition) IGroupMemberDo {
	return g.withDO(g.DO.Not(conds...))
}

func (g groupMemberDo) Or(conds ...gen.Condition) IGroupMemberDo {
	return g.withDO(g.DO.Or(conds...))
}

func (g groupMemberDo) Select(conds ...field.Expr) IGroupMemberDo {
	return g.withDO(g.DO.Select(conds...))
}

func (g groupMemberDo) Where(conds ...gen.Condition) IGroupMemberDo {
	return g.withDO(g.DO.Where(conds...))
}

func (g groupMemberDo) Order(conds ...field.Expr) IGroupMemberDo {
	return g.withDO(g.DO.Order(conds...))
}

func (g groupMemberDo) Distinct(cols ...field.Expr) IGroupMemberDo {
	return g.withDO(g.DO.Distinct(cols...))
}

func (g groupMemberDo) Omit(cols ...field.Expr) IGroupMemberDo {
	return g.withDO(g.DO.Omit(cols...))
}

func (g groupMemberDo) Join(table schema.Tabler, on ...field.Expr) IGroupMemberDo {
	return g.withDO(g.DO.Join(table, on...))
}

func (g groupMemberDo) LeftJoin(table schema.Tabler, on ...field.Expr) IGroupMemberDo {
	return g.withDO(g.DO.LeftJoin(table, on...))
}

func (g groupMemberDo) RightJoin(table schema.Tabler, on ...field.Expr) IGroupMemberDo {
	return g.withDO(g.DO.RightJoin(table, on...))
}

func (g groupMemberDo) Group(cols ...field.Expr) IGroupMemberDo {
	return g.withDO(g.DO.Group(cols...))
}

func (g groupMemberDo) Having(conds ...gen.Condition) IGroupMemberDo {
	return g.withDO(g.DO.Having(conds...))
}

func (g groupMemberDo) Limit(limit int) IGroupMemberDo {
	return g.withDO(g.DO.Limit(limit))
}

func (g groupMemberDo) Offset(offset int) IGroupMemberDo {
	return g.withDO(g.DO.Offset(offset))
}

func (g groupMemberDo) Scopes(funcs ...func(gen.Dao) gen.Dao) IGroupMemberDo {
	return g.withDO(g.DO.Scopes(funcs...))
}

func (g groupMemberDo) Unscoped() IGroupMemberDo {
	return g.withDO(g.DO.Unscoped())
}

func (g groupMemberDo) Create(values ...*model.GroupMember) error {
	if len(values) == 0 {
		return nil
	}
	return g.DO.Create(values)
}

func (g groupMemberDo) CreateInBatches(values []*model.GroupMember, batchSize int) error {
	return g.DO.CreateInBatches(values, batchSize)
}

// Save : !!! underlying implementation is different with GORM
// The method is equivalent to executing the statement: db.Clauses(clause.OnConflict{UpdateAll: true}).Create(values)
func (g groupMemberDo) Save(values ...*model.GroupMember) error {
	if len(values) == 0 {
		return nil
	}
	return g.DO.Save(values)
}

func (g groupMemberDo) First() (*model.GroupMember, error) {
	if result, err := g.DO.First(); err != nil {
		return nil, err
	} else {
		return result.(*model.GroupMember), nil
	}
}

func (g groupMemberDo) Take() (*model.GroupMember, error) {
	if result, err := g.DO.Take(); err != nil {
		return nil, err
	} else {
		return result.(*model.GroupMember), nil
	}
}

func (g groupMemberDo) Last() (*model.GroupMember, error) {
	if result, err := g.DO.Last(); err != nil {
		return nil, err
	} else {
		return result.(*model.GroupMember), nil
	}
}

func (g groupMemberDo) Find() ([]*model.GroupMember, error) {
	result, err := g.DO.Find()
	return result.([]*model.GroupMember), err
}

func (g groupMemberDo) FindInBatch(batchSize int, fc func(tx gen.Dao, batch int) error) (results []*model.GroupMember, err error) {
	buf := make([]*model.GroupMember, 0, batchSize)
	err = g.DO.FindInBatches(&buf, batchSize, func(tx gen.Dao, batch int) error {
		defer func() { results = append(results, buf...) }()
		return fc(tx, batch)
	})
	return results, err
}

func (g groupMemberDo) FindInBatches(result *[]*model.GroupMember, batchSize int, fc func(tx gen.Dao, batch int) error) error {
	return g.DO.FindInBatches(result, batchSize, fc)
}

func (g groupMemberDo) Attrs(attrs ...field.AssignExpr) IGroupMemberDo {
	return g.withDO(g.DO.Attrs(attrs...))
}

func (g groupMemberDo) Assign(attrs ...field.AssignExpr) IGroupMemberDo {
	return g.withDO(g.DO.Assign(attrs...))
}

func (g groupMemberDo) Joins(fields ...field.RelationField) IGroupMemberDo {
	for _, _f := range fields {
		g = *g.withDO(g.DO.Joins(_f))
	}
	return &g
}

func (g groupMemberDo) Preload(fields ...field.RelationField) IGroupMemberDo {
	for _, _f := range fields {
		g = *g.withDO(g.DO.Preload(_f))
	}
	return &g
}

func (g groupMemberDo) FirstOrInit() (*model.GroupMember, error) {
	if result, err := g.DO.FirstOrInit(); err != nil {
		return nil, err
	} else {
		return result.(*model.GroupMember), nil
	}
}

func (g groupMemberDo) FirstOrCreate() (*model.GroupMember, error) {
	if result, err := g.DO.FirstOrCreate(); err != nil {
		return nil, err
	} else {
		return result.(*model.GroupMember), nil
	}
}

func (g groupMemberDo) FindByPage(offset int, limit int) (result []*model.GroupMember, count int64, err error) {
	result, err = g.Offset(offset).Limit(limit).Find()
	if err != nil {
		return
	}

	if size := len(result); 0 < limit && 0 < size && size < limit {
		count = int64(size + offset)
		return
	}

	count, err = g.Offset(-1).Limit(-1).Count()
	return
}

func (g groupMemberDo) ScanByPage(result interface{}, offset int, limit int) (count int64, err error) {
	count, err = g.Count()
	if err != nil {
		return
	}

	err = g.Offset(offset).Limit(limit).Scan(result)
	return
}

func (g groupMemberDo) Scan(result interface{}) (err error) {
	return g.DO.Scan(result)
}

func (g groupMemberDo) Delete(models ...*model.GroupMember) (result gen.ResultInfo, err error) {
	return g.DO.Delete(models)
}

func (g *groupMemberDo) withDO(do gen.Dao) *groupMemberDo {
	g.DO = *do.(*gen.DO)
	return g
}


================================================
FILE: dal/query/message.gen.go
================================================
// Code generated by gorm.io/gen. DO NOT EDIT.
// Code generated by gorm.io/gen. DO NOT EDIT.
// Code generated by gorm.io/gen. DO NOT EDIT.

package query

import (
	"context"

	"gorm.io/gorm"
	"gorm.io/gorm/clause"
	"gorm.io/gorm/schema"

	"gorm.io/gen"
	"gorm.io/gen/field"

	"gorm.io/plugin/dbresolver"

	"DiTing-Go/dal/model"
)

func newMessage(db *gorm.DB, opts ...gen.DOOption) message {
	_message := message{}

	_message.messageDo.UseDB(db, opts...)
	_message.messageDo.UseModel(&model.Message{})

	tableName := _message.messageDo.TableName()
	_message.ALL = field.NewAsterisk(tableName)
	_message.ID = field.NewInt64(tableName, "id")
	_message.RoomID = field.NewInt64(tableName, "room_id")
	_message.FromUID = field.NewInt64(tableName, "from_uid")
	_message.Content = field.NewString(tableName, "content")
	_message.ReplyMsgID = field.NewInt64(tableName, "reply_msg_id")
	_message.DeleteStatus = field.NewInt32(tableName, "delete_status")
	_message.GapCount = field.NewInt32(tableName, "gap_count")
	_message.Type = field.NewInt32(tableName, "type")
	_message.Extra = field.NewString(tableName, "extra")
	_message.CreateTime = field.NewTime(tableName, "create_time")
	_message.UpdateTime = field.NewTime(tableName, "update_time")

	_message.fillFieldMap()

	return _message
}

// message 消息表
type message struct {
	messageDo messageDo

	ALL          field.Asterisk
	ID           field.Int64  // id
	RoomID       field.Int64  // 会话表id
	FromUID      field.Int64  // 消息发送者uid
	Content      field.String // 消息内容
	ReplyMsgID   field.Int64  // 回复的消息内容
	DeleteStatus field.Int32  // 消息状态 0正常 1删除
	GapCount     field.Int32  // 与回复的消息间隔多少条
	Type         field.Int32  // 消息类型 1正常文本 2.撤回消息
	Extra        field.String // 扩展信息
	CreateTime   field.Time   // 创建时间
	UpdateTime   field.Time   // 修改时间

	fieldMap map[string]field.Expr
}

func (m message) Table(newTableName string) *message {
	m.messageDo.UseTable(newTableName)
	return m.updateTableName(newTableName)
}

func (m message) As(alias string) *message {
	m.messageDo.DO = *(m.messageDo.As(alias).(*gen.DO))
	return m.updateTableName(alias)
}

func (m *message) updateTableName(table string) *message {
	m.ALL = field.NewAsterisk(table)
	m.ID = field.NewInt64(table, "id")
	m.RoomID = field.NewInt64(table, "room_id")
	m.FromUID = field.NewInt64(table, "from_uid")
	m.Content = field.NewString(table, "content")
	m.ReplyMsgID = field.NewInt64(table, "reply_msg_id")
	m.DeleteStatus = field.NewInt32(table, "delete_status")
	m.GapCount = field.NewInt32(table, "gap_count")
	m.Type = field.NewInt32(table, "type")
	m.Extra = field.NewString(table, "extra")
	m.CreateTime = field.NewTime(table, "create_time")
	m.UpdateTime = field.NewTime(table, "update_time")

	m.fillFieldMap()

	return m
}

func (m *message) WithContext(ctx context.Context) IMessageDo { return m.messageDo.WithContext(ctx) }

func (m message) TableName() string { return m.messageDo.TableName() }

func (m message) Alias() string { return m.messageDo.Alias() }

func (m message) Columns(cols ...field.Expr) gen.Columns { return m.messageDo.Columns(cols...) }

func (m *message) GetFieldByName(fieldName string) (field.OrderExpr, bool) {
	_f, ok := m.fieldMap[fieldName]
	if !ok || _f == nil {
		return nil, false
	}
	_oe, ok := _f.(field.OrderExpr)
	return _oe, ok
}

func (m *message) fillFieldMap() {
	m.fieldMap = make(map[string]field.Expr, 11)
	m.fieldMap["id"] = m.ID
	m.fieldMap["room_id"] = m.RoomID
	m.fieldMap["from_uid"] = m.FromUID
	m.fieldMap["content"] = m.Content
	m.fieldMap["reply_msg_id"] = m.ReplyMsgID
	m.fieldMap["delete_status"] = m.DeleteStatus
	m.fieldMap["gap_count"] = m.GapCount
	m.fieldMap["type"] = m.Type
	m.fieldMap["extra"] = m.Extra
	m.fieldMap["create_time"] = m.CreateTime
	m.fieldMap["update_time"] = m.UpdateTime
}

func (m message) clone(db *gorm.DB) message {
	m.messageDo.ReplaceConnPool(db.Statement.ConnPool)
	return m
}

func (m message) replaceDB(db *gorm.DB) message {
	m.messageDo.ReplaceDB(db)
	return m
}

type messageDo struct{ gen.DO }

type IMessageDo interface {
	gen.SubQuery
	Debug() IMessageDo
	WithContext(ctx context.Context) IMessageDo
	WithResult(fc func(tx gen.Dao)) gen.ResultInfo
	ReplaceDB(db *gorm.DB)
	ReadDB() IMessageDo
	WriteDB() IMessageDo
	As(alias string) gen.Dao
	Session(config *gorm.Session) IMessageDo
	Columns(cols ...field.Expr) gen.Columns
	Clauses(conds ...clause.Expression) IMessageDo
	Not(conds ...gen.Condition) IMessageDo
	Or(conds ...gen.Condition) IMessageDo
	Select(conds ...field.Expr) IMessageDo
	Where(conds ...gen.Condition) IMessageDo
	Order(conds ...field.Expr) IMessageDo
	Distinct(cols ...field.Expr) IMessageDo
	Omit(cols ...field.Expr) IMessageDo
	Join(table schema.Tabler, on ...field.Expr) IMessageDo
	LeftJoin(table schema.Tabler, on ...field.Expr) IMessageDo
	RightJoin(table schema.Tabler, on ...field.Expr) IMessageDo
	Group(cols ...field.Expr) IMessageDo
	Having(conds ...gen.Condition) IMessageDo
	Limit(limit int) IMessageDo
	Offset(offset int) IMessageDo
	Count() (count int64, err error)
	Scopes(funcs ...func(gen.Dao) gen.Dao) IMessageDo
	Unscoped() IMessageDo
	Create(values ...*model.Message) error
	CreateInBatches(values []*model.Message, batchSize int) error
	Save(values ...*model.Message) error
	First() (*model.Message, error)
	Take() (*model.Message, error)
	Last() (*model.Message, error)
	Find() ([]*model.Message, error)
	FindInBatch(batchSize int, fc func(tx gen.Dao, batch int) error) (results []*model.Message, err error)
	FindInBatches(result *[]*model.Message, batchSize int, fc func(tx gen.Dao, batch int) error) error
	Pluck(column field.Expr, dest interface{}) error
	Delete(...*model.Message) (info gen.ResultInfo, err error)
	Update(column field.Expr, value interface{}) (info gen.ResultInfo, err error)
	UpdateSimple(columns ...field.AssignExpr) (info gen.ResultInfo, err error)
	Updates(value interface{}) (info gen.ResultInfo, err error)
	UpdateColumn(column field.Expr, value interface{}) (info gen.ResultInfo, err error)
	UpdateColumnSimple(columns ...field.AssignExpr) (info gen.ResultInfo, err error)
	UpdateColumns(value interface{}) (info gen.ResultInfo, err error)
	UpdateFrom(q gen.SubQuery) gen.Dao
	Attrs(attrs ...field.AssignExpr) IMessageDo
	Assign(attrs ...field.AssignExpr) IMessageDo
	Joins(fields ...field.RelationField) IMessageDo
	Preload(fields ...field.RelationField) IMessageDo
	FirstOrInit() (*model.Message, error)
	FirstOrCreate() (*model.Message, error)
	FindByPage(offset int, limit int) (result []*model.Message, count int64, err error)
	ScanByPage(result interface{}, offset int, limit int) (count int64, err error)
	Scan(result interface{}) (err error)
	Returning(value interface{}, columns ...string) IMessageDo
	UnderlyingDB() *gorm.DB
	schema.Tabler
}

func (m messageDo) Debug() IMessageDo {
	return m.withDO(m.DO.Debug())
}

func (m messageDo) WithContext(ctx context.Context) IMessageDo {
	return m.withDO(m.DO.WithContext(ctx))
}

func (m messageDo) ReadDB() IMessageDo {
	return m.Clauses(dbresolver.Read)
}

func (m messageDo) WriteDB() IMessageDo {
	return m.Clauses(dbresolver.Write)
}

func (m messageDo) Session(config *gorm.Session) IMessageDo {
	return m.withDO(m.DO.Session(config))
}

func (m messageDo) Clauses(conds ...clause.Expression) IMessageDo {
	return m.withDO(m.DO.Clauses(conds...))
}

func (m messageDo) Returning(value interface{}, columns ...string) IMessageDo {
	return m.withDO(m.DO.Returning(value, columns...))
}

func (m messageDo) Not(conds ...gen.Condition) IMessageDo {
	return m.withDO(m.DO.Not(conds...))
}

func (m messageDo) Or(conds ...gen.Condition) IMessageDo {
	return m.withDO(m.DO.Or(conds...))
}

func (m messageDo) Select(conds ...field.Expr) IMessageDo {
	return m.withDO(m.DO.Select(conds...))
}

func (m messageDo) Where(conds ...gen.Condition) IMessageDo {
	return m.withDO(m.DO.Where(conds...))
}

func (m messageDo) Order(conds ...field.Expr) IMessageDo {
	return m.withDO(m.DO.Order(conds...))
}

func (m messageDo) Distinct(cols ...field.Expr) IMessageDo {
	return m.withDO(m.DO.Distinct(cols...))
}

func (m messageDo) Omit(cols ...field.Expr) IMessageDo {
	return m.withDO(m.DO.Omit(cols...))
}

func (m messageDo) Join(table schema.Tabler, on ...field.Expr) IMessageDo {
	return m.withDO(m.DO.Join(table, on...))
}

func (m messageDo) LeftJoin(table schema.Tabler, on ...field.Expr) IMessageDo {
	return m.withDO(m.DO.LeftJoin(table, on...))
}

func (m messageDo) RightJoin(table schema.Tabler, on ...field.Expr) IMessageDo {
	return m.withDO(m.DO.RightJoin(table, on...))
}

func (m messageDo) Group(cols ...field.Expr) IMessageDo {
	return m.withDO(m.DO.Group(cols...))
}

func (m messageDo) Having(conds ...gen.Condition) IMessageDo {
	return m.withDO(m.DO.Having(conds...))
}

func (m messageDo) Limit(limit int) IMessageDo {
	return m.withDO(m.DO.Limit(limit))
}

func (m messageDo) Offset(offset int) IMessageDo {
	return m.withDO(m.DO.Offset(offset))
}

func (m messageDo) Scopes(funcs ...func(gen.Dao) gen.Dao) IMessageDo {
	return m.withDO(m.DO.Scopes(funcs...))
}

func (m messageDo) Unscoped() IMessageDo {
	return m.withDO(m.DO.Unscoped())
}

func (m messageDo) Create(values ...*model.Message) error {
	if len(values) == 0 {
		return nil
	}
	return m.DO.Create(values)
}

func (m messageDo) CreateInBatches(values []*model.Message, batchSize int) error {
	return m.DO.CreateInBatches(values, batchSize)
}

// Save : !!! underlying implementation is different with GORM
// The method is equivalent to executing the statement: db.Clauses(clause.OnConflict{UpdateAll: true}).Create(values)
func (m messageDo) Save(values ...*model.Message) error {
	if len(values) == 0 {
		return nil
	}
	return m.DO.Save(values)
}

func (m messageDo) First() (*model.Message, error) {
	if result, err := m.DO.First(); err != nil {
		return nil, err
	} else {
		return result.(*model.Message), nil
	}
}

func (m messageDo) Take() (*model.Message, error) {
	if result, err := m.DO.Take(); err != nil {
		return nil, err
	} else {
		return result.(*model.Message), nil
	}
}

func (m messageDo) Last() (*model.Message, error) {
	if result, err := m.DO.Last(); err != nil {
		return nil, err
	} else {
		return result.(*model.Message), nil
	}
}

func (m messageDo) Find() ([]*model.Message, error) {
	result, err := m.DO.Find()
	return result.([]*model.Message), err
}

func (m messageDo) FindInBatch(batchSize int, fc func(tx gen.Dao, batch int) error) (results []*model.Message, err error) {
	buf := make([]*model.Message, 0, batchSize)
	err = m.DO.FindInBatches(&buf, batchSize, func(tx gen.Dao, batch int) error {
		defer func() { results = append(results, buf...) }()
		return fc(tx, batch)
	})
	return results, err
}

func (m messageDo) FindInBatches(result *[]*model.Message, batchSize int, fc func(tx gen.Dao, batch int) error) error {
	return m.DO.FindInBatches(result, batchSize, fc)
}

func (m messageDo) Attrs(attrs ...field.AssignExpr) IMessageDo {
	return m.withDO(m.DO.Attrs(attrs...))
}

func (m messageDo) Assign(attrs ...field.AssignExpr) IMessageDo {
	return m.withDO(m.DO.Assign(attrs...))
}

func (m messageDo) Joins(fields ...field.RelationField) IMessageDo {
	for _, _f := range fields {
		m = *m.withDO(m.DO.Joins(_f))
	}
	return &m
}

func (m messageDo) Preload(fields ...field.RelationField) IMessageDo {
	for _, _f := range fields {
		m = *m.withDO(m.DO.Preload(_f))
	}
	return &m
}

func (m messageDo) FirstOrInit() (*model.Message, error) {
	if result, err := m.DO.FirstOrInit(); err != nil {
		return nil, err
	} else {
		return result.(*model.Message), nil
	}
}

func (m messageDo) FirstOrCreate() (*model.Message, error) {
	if result, err := m.DO.FirstOrCreate(); err != nil {
		return nil, err
	} else {
		return result.(*model.Message), nil
	}
}

func (m messageDo) FindByPage(offset int, limit int) (result []*model.Message, count int64, err error) {
	result, err = m.Offset(offset).Limit(limit).Find()
	if err != nil {
		return
	}

	if size := len(result); 0 < limit && 0 < size && size < limit {
		count = int64(size + offset)
		return
	}

	count, err = m.Offset(-1).Limit(-1).Count()
	return
}

func (m messageDo) ScanByPage(result interface{}, offset int, limit int) (count int64, err error) {
	count, err = m.Count()
	if err != nil {
		return
	}

	err = m.Offset(offset).Limit(limit).Scan(result)
	return
}

func (m messageDo) Scan(result interface{}) (err error) {
	return m.DO.Scan(result)
}

func (m messageDo) Delete(models ...*model.Message) (result gen.ResultInfo, err error) {
	return m.DO.Delete(models)
}

func (m *messageDo) withDO(do gen.Dao) *messageDo {
	m.DO = *do.(*gen.DO)
	return m
}


================================================
FILE: dal/query/room.gen.go
================================================
// Code generated by gorm.io/gen. DO NOT EDIT.
// Code generated by gorm.io/gen. DO NOT EDIT.
// Code generated by gorm.io/gen. DO NOT EDIT.

package query

import (
	"context"

	"gorm.io/gorm"
	"gorm.io/gorm/clause"
	"gorm.io/gorm/schema"

	"gorm.io/gen"
	"gorm.io/gen/field"

	"gorm.io/plugin/dbresolver"

	"DiTing-Go/dal/model"
)

func newRoom(db *gorm.DB, opts ...gen.DOOption) room {
	_room := room{}

	_room.roomDo.UseDB(db, opts...)
	_room.roomDo.UseModel(&model.Room{})

	tableName := _room.roomDo.TableName()
	_room.ALL = field.NewAsterisk(tableName)
	_room.ID = field.NewInt64(tableName, "id")
	_room.Type = field.NewInt32(tableName, "type")
	_room.HotFlag = field.NewInt32(tableName, "hot_flag")
	_room.ActiveTime = field.NewTime(tableName, "active_time")
	_room.LastMsgID = field.NewInt64(tableName, "last_msg_id")
	_room.ExtJSON = field.NewString(tableName, "ext_json")
	_room.CreateTime = field.NewTime(tableName, "create_time")
	_room.UpdateTime = field.NewTime(tableName, "update_time")
	_room.DeleteStatus = field.NewInt32(tableName, "delete_status")

	_room.fillFieldMap()

	return _room
}

// room 房间表
type room struct {
	roomDo roomDo

	ALL          field.Asterisk
	ID           field.Int64  // id
	Type         field.Int32  // 房间类型 1群聊 2单聊
	HotFlag      field.Int32  // 是否全员展示 0否 1是
	ActiveTime   field.Time   // 群最后消息的更新时间(热点群不需要写扩散,只更新这里)
	LastMsgID    field.Int64  // 会话中的最后一条消息id
	ExtJSON      field.String // 额外信息(根据不同类型房间有不同存储的东西)
	CreateTime   field.Time   // 创建时间
	UpdateTime   field.Time   // 修改时间
	DeleteStatus field.Int32  // 房间状态 0正常 1禁用(删好友了禁用)

	fieldMap map[string]field.Expr
}

func (r room) Table(newTableName string) *room {
	r.roomDo.UseTable(newTableName)
	return r.updateTableName(newTableName)
}

func (r room) As(alias string) *room {
	r.roomDo.DO = *(r.roomDo.As(alias).(*gen.DO))
	return r.updateTableName(alias)
}

func (r *room) updateTableName(table string) *room {
	r.ALL = field.NewAsterisk(table)
	r.ID = field.NewInt64(table, "id")
	r.Type = field.NewInt32(table, "type")
	r.HotFlag = field.NewInt32(table, "hot_flag")
	r.ActiveTime = field.NewTime(table, "active_time")
	r.LastMsgID = field.NewInt64(table, "last_msg_id")
	r.ExtJSON = field.NewString(table, "ext_json")
	r.CreateTime = field.NewTime(table, "create_time")
	r.UpdateTime = field.NewTime(table, "update_time")
	r.DeleteStatus = field.NewInt32(table, "delete_status")

	r.fillFieldMap()

	return r
}

func (r *room) WithContext(ctx context.Context) IRoomDo { return r.roomDo.WithContext(ctx) }

func (r room) TableName() string { return r.roomDo.TableName() }

func (r room) Alias() string { return r.roomDo.Alias() }

func (r room) Columns(cols ...field.Expr) gen.Columns { return r.roomDo.Columns(cols...) }

func (r *room) GetFieldByName(fieldName string) (field.OrderExpr, bool) {
	_f, ok := r.fieldMap[fieldName]
	if !ok || _f == nil {
		return nil, false
	}
	_oe, ok := _f.(field.OrderExpr)
	return _oe, ok
}

func (r *room) fillFieldMap() {
	r.fieldMap = make(map[string]field.Expr, 9)
	r.fieldMap["id"] = r.ID
	r.fieldMap["type"] = r.Type
	r.fieldMap["hot_flag"] = r.HotFlag
	r.fieldMap["active_time"] = r.ActiveTime
	r.fieldMap["last_msg_id"] = r.LastMsgID
	r.fieldMap["ext_json"] = r.ExtJSON
	r.fieldMap["create_time"] = r.CreateTime
	r.fieldMap["update_time"] = r.UpdateTime
	r.fieldMap["delete_status"] = r.DeleteStatus
}

func (r room) clone(db *gorm.DB) room {
	r.roomDo.ReplaceConnPool(db.Statement.ConnPool)
	return r
}

func (r room) replaceDB(db *gorm.DB) room {
	r.roomDo.ReplaceDB(db)
	return r
}

type roomDo struct{ gen.DO }

type IRoomDo interface {
	gen.SubQuery
	Debug() IRoomDo
	WithContext(ctx context.Context) IRoomDo
	WithResult(fc func(tx gen.Dao)) gen.ResultInfo
	ReplaceDB(db *gorm.DB)
	ReadDB() IRoomDo
	WriteDB() IRoomDo
	As(alias string) gen.Dao
	Session(config *gorm.Session) IRoomDo
	Columns(cols ...field.Expr) gen.Columns
	Clauses(conds ...clause.Expression) IRoomDo
	Not(conds ...gen.Condition) IRoomDo
	Or(conds ...gen.Condition) IRoomDo
	Select(conds ...field.Expr) IRoomDo
	Where(conds ...gen.Condition) IRoomDo
	Order(conds ...field.Expr) IRoomDo
	Distinct(cols ...field.Expr) IRoomDo
	Omit(cols ...field.Expr) IRoomDo
	Join(table schema.Tabler, on ...field.Expr) IRoomDo
	LeftJoin(table schema.Tabler, on ...field.Expr) IRoomDo
	RightJoin(table schema.Tabler, on ...field.Expr) IRoomDo
	Group(cols ...field.Expr) IRoomDo
	Having(conds ...gen.Condition) IRoomDo
	Limit(limit int) IRoomDo
	Offset(offset int) IRoomDo
	Count() (count int64, err error)
	Scopes(funcs ...func(gen.Dao) gen.Dao) IRoomDo
	Unscoped() IRoomDo
	Create(values ...*model.Room) error
	CreateInBatches(values []*model.Room, batchSize int) error
	Save(values ...*model.Room) error
	First() (*model.Room, error)
	Take() (*model.Room, error)
	Last() (*model.Room, error)
	Find() ([]*model.Room, error)
	FindInBatch(batchSize int, fc func(tx gen.Dao, batch int) error) (results []*model.Room, err error)
	FindInBatches(result *[]*model.Room, batchSize int, fc func(tx gen.Dao, batch int) error) error
	Pluck(column field.Expr, dest interface{}) error
	Delete(...*model.Room) (info gen.ResultInfo, err error)
	Update(column field.Expr, value interface{}) (info gen.ResultInfo, err error)
	UpdateSimple(columns ...field.AssignExpr) (info gen.ResultInfo, err error)
	Updates(value interface{}) (info gen.ResultInfo, err error)
	UpdateColumn(column field.Expr, value interface{}) (info gen.ResultInfo, err error)
	UpdateColumnSimple(columns ...field.AssignExpr) (info gen.ResultInfo, err error)
	UpdateColumns(value interface{}) (info gen.ResultInfo, err error)
	UpdateFrom(q gen.SubQuery) gen.Dao
	Attrs(attrs ...field.AssignExpr) IRoomDo
	Assign(attrs ...field.AssignExpr) IRoomDo
	Joins(fields ...field.RelationField) IRoomDo
	Preload(fields ...field.RelationField) IRoomDo
	FirstOrInit() (*model.Room, error)
	FirstOrCreate() (*model.Room, error)
	FindByPage(offset int, limit int) (result []*model.Room, count int64, err error)
	ScanByPage(result interface{}, offset int, limit int) (count int64, err error)
	Scan(result interface{}) (err error)
	Returning(value interface{}, columns ...string) IRoomDo
	UnderlyingDB() *gorm.DB
	schema.Tabler
}

func (r roomDo) Debug() IRoomDo {
	return r.withDO(r.DO.Debug())
}

func (r roomDo) WithContext(ctx context.Context) IRoomDo {
	return r.withDO(r.DO.WithContext(ctx))
}

func (r roomDo) ReadDB() IRoomDo {
	return r.Clauses(dbresolver.Read)
}

func (r roomDo) WriteDB() IRoomDo {
	return r.Clauses(dbresolver.Write)
}

func (r roomDo) Session(config *gorm.Session) IRoomDo {
	return r.withDO(r.DO.Session(config))
}

func (r roomDo) Clauses(conds ...clause.Expression) IRoomDo {
	return r.withDO(r.DO.Clauses(conds...))
}

func (r roomDo) Returning(value interface{}, columns ...string) IRoomDo {
	return r.withDO(r.DO.Returning(value, columns...))
}

func (r roomDo) Not(conds ...gen.Condition) IRoomDo {
	return r.withDO(r.DO.Not(conds...))
}

func (r roomDo) Or(conds ...gen.Condition) IRoomDo {
	return r.withDO(r.DO.Or(conds...))
}

func (r roomDo) Select(conds ...field.Expr) IRoomDo {
	return r.withDO(r.DO.Select(conds...))
}

func (r roomDo) Where(conds ...gen.Condition) IRoomDo {
	return r.withDO(r.DO.Where(conds...))
}

func (r roomDo) Order(conds ...field.Expr) IRoomDo {
	return r.withDO(r.DO.Order(conds...))
}

func (r roomDo) Distinct(cols ...field.Expr) IRoomDo {
	return r.withDO(r.DO.Distinct(cols...))
}

func (r roomDo) Omit(cols ...field.Expr) IRoomDo {
	return r.withDO(r.DO.Omit(cols...))
}

func (r roomDo) Join(table schema.Tabler, on ...field.Expr) IRoomDo {
	return r.withDO(r.DO.Join(table, on...))
}

func (r roomDo) LeftJoin(table schema.Tabler, on ...field.Expr) IRoomDo {
	return r.withDO(r.DO.LeftJoin(table, on...))
}

func (r roomDo) RightJoin(table schema.Tabler, on ...field.Expr) IRoomDo {
	return r.withDO(r.DO.RightJoin(table, on...))
}

func (r roomDo) Group(cols ...field.Expr) IRoomDo {
	return r.withDO(r.DO.Group(cols...))
}

func (r roomDo) Having(conds ...gen.Condition) IRoomDo {
	return r.withDO(r.DO.Having(conds...))
}

func (r roomDo) Limit(limit int) IRoomDo {
	return r.withDO(r.DO.Limit(limit))
}

func (r roomDo) Offset(offset int) IRoomDo {
	return r.withDO(r.DO.Offset(offset))
}

func (r roomDo) Scopes(funcs ...func(gen.Dao) gen.Dao) IRoomDo {
	return r.withDO(r.DO.Scopes(funcs...))
}

func (r roomDo) Unscoped() IRoomDo {
	return r.withDO(r.DO.Unscoped())
}

func (r roomDo) Create(values ...*model.Room) error {
	if len(values) == 0 {
		return nil
	}
	return r.DO.Create(values)
}

func (r roomDo) CreateInBatches(values []*model.Room, batchSize int) error {
	return r.DO.CreateInBatches(values, batchSize)
}

// Save : !!! underlying implementation is different with GORM
// The method is equivalent to executing the statement: db.Clauses(clause.OnConflict{UpdateAll: true}).Create(values)
func (r roomDo) Save(values ...*model.Room) error {
	if len(values) == 0 {
		return nil
	}
	return r.DO.Save(values)
}

func (r roomDo) First() (*model.Room, error) {
	if result, err := r.DO.First(); err != nil {
		return nil, err
	} else {
		return result.(*model.Room), nil
	}
}

func (r roomDo) Take() (*model.Room, error) {
	if result, err := r.DO.Take(); err != nil {
		return nil, err
	} else {
		return result.(*model.Room), nil
	}
}

func (r roomDo) Last() (*model.Room, error) {
	if result, err := r.DO.Last(); err != nil {
		return nil, err
	} else {
		return result.(*model.Room), nil
	}
}

func (r roomDo) Find() ([]*model.Room, error) {
	result, err := r.DO.Find()
	return result.([]*model.Room), err
}

func (r roomDo) FindInBatch(batchSize int, fc func(tx gen.Dao, batch int) error) (results []*model.Room, err error) {
	buf := make([]*model.Room, 0, batchSize)
	err = r.DO.FindInBatches(&buf, batchSize, func(tx gen.Dao, batch int) error {
		defer func() { results = append(results, buf...) }()
		return fc(tx, batch)
	})
	return results, err
}

func (r roomDo) FindInBatches(result *[]*model.Room, batchSize int, fc func(tx gen.Dao, batch int) error) error {
	return r.DO.FindInBatches(result, batchSize, fc)
}

func (r roomDo) Attrs(attrs ...field.AssignExpr) IRoomDo {
	return r.withDO(r.DO.Attrs(attrs...))
}

func (r roomDo) Assign(attrs ...field.AssignExpr) IRoomDo {
	return r.withDO(r.DO.Assign(attrs...))
}

func (r roomDo) Joins(fields ...field.RelationField) IRoomDo {
	for _, _f := range fields {
		r = *r.withDO(r.DO.Joins(_f))
	}
	return &r
}

func (r roomDo) Preload(fields ...field.RelationField) IRoomDo {
	for _, _f := range fields {
		r = *r.withDO(r.DO.Preload(_f))
	}
	return &r
}

func (r roomDo) FirstOrInit() (*model.Room, error) {
	if result, err := r.DO.FirstOrInit(); err != nil {
		return nil, err
	} else {
		return result.(*model.Room), nil
	}
}

func (r roomDo) FirstOrCreate() (*model.Room, error) {
	if result, err := r.DO.FirstOrCreate(); err != nil {
		return nil, err
	} else {
		return result.(*model.Room), nil
	}
}

func (r roomDo) FindByPage(offset int, limit int) (result []*model.Room, count int64, err error) {
	result, err = r.Offset(offset).Limit(limit).Find()
	if err != nil {
		return
	}

	if size := len(result); 0 < limit && 0 < size && size < limit {
		count = int64(size + offset)
		return
	}

	count, err = r.Offset(-1).Limit(-1).Count()
	return
}

func (r roomDo) ScanByPage(result interface{}, offset int, limit int) (count int64, err error) {
	count, err = r.Count()
	if err != nil {
		return
	}

	err = r.Offset(offset).Limit(limit).Scan(result)
	return
}

func (r roomDo) Scan(result interface{}) (err error) {
	return r.DO.Scan(result)
}

func (r roomDo) Delete(models ...*model.Room) (result gen.ResultInfo, err error) {
	return r.DO.Delete(models)
}

func (r *roomDo) withDO(do gen.Dao) *roomDo {
	r.DO = *do.(*gen.DO)
	return r
}


================================================
FILE: dal/query/room_friend.gen.go
================================================
// Code generated by gorm.io/gen. DO NOT EDIT.
// Code generated by gorm.io/gen. DO NOT EDIT.
// Code generated by gorm.io/gen. DO NOT EDIT.

package query

import (
	"context"

	"gorm.io/gorm"
	"gorm.io/gorm/clause"
	"gorm.io/gorm/schema"

	"gorm.io/gen"
	"gorm.io/gen/field"

	"gorm.io/plugin/dbresolver"

	"DiTing-Go/dal/model"
)

func newRoomFriend(db *gorm.DB, opts ...gen.DOOption) roomFriend {
	_roomFriend := roomFriend{}

	_roomFriend.roomFriendDo.UseDB(db, opts...)
	_roomFriend.roomFriendDo.UseModel(&model.RoomFriend{})

	tableName := _roomFriend.roomFriendDo.TableName()
	_roomFriend.ALL = field.NewAsterisk(tableName)
	_roomFriend.ID = field.NewInt64(tableName, "id")
	_roomFriend.RoomID = field.NewInt64(tableName, "room_id")
	_roomFriend.Uid1 = field.NewInt64(tableName, "uid1")
	_roomFriend.Uid2 = field.NewInt64(tableName, "uid2")
	_roomFriend.RoomKey = field.NewString(tableName, "room_key")
	_roomFriend.DeleteStatus = field.NewInt32(tableName, "delete_status")
	_roomFriend.CreateTime = field.NewTime(tableName, "create_time")
	_roomFriend.UpdateTime = field.NewTime(tableName, "update_time")

	_roomFriend.fillFieldMap()

	return _roomFriend
}

// roomFriend 单聊房间表
type roomFriend struct {
	roomFriendDo roomFriendDo

	ALL          field.Asterisk
	ID           field.Int64  // id
	RoomID       field.Int64  // 房间id
	Uid1         field.Int64  // uid1(更小的uid)
	Uid2         field.Int64  // uid2(更大的uid)
	RoomKey      field.String // 房间key由两个uid拼接,先做排序uid1_uid2
	DeleteStatus field.Int32  // 房间状态 0正常 1禁用(删好友了禁用)
	CreateTime   field.Time   // 创建时间
	UpdateTime   field.Time   // 修改时间

	fieldMap map[string]field.Expr
}

func (r roomFriend) Table(newTableName string) *roomFriend {
	r.roomFriendDo.UseTable(newTableName)
	return r.updateTableName(newTableName)
}

func (r roomFriend) As(alias string) *roomFriend {
	r.roomFriendDo.DO = *(r.roomFriendDo.As(alias).(*gen.DO))
	return r.updateTableName(alias)
}

func (r *roomFriend) updateTableName(table string) *roomFriend {
	r.ALL = field.NewAsterisk(table)
	r.ID = field.NewInt64(table, "id")
	r.RoomID = field.NewInt64(table, "room_id")
	r.Uid1 = field.NewInt64(table, "uid1")
	r.Uid2 = field.NewInt64(table, "uid2")
	r.RoomKey = field.NewString(table, "room_key")
	r.DeleteStatus = field.NewInt32(table, "delete_status")
	r.CreateTime = field.NewTime(table, "create_time")
	r.UpdateTime = field.NewTime(table, "update_time")

	r.fillFieldMap()

	return r
}

func (r *roomFriend) WithContext(ctx context.Context) IRoomFriendDo {
	return r.roomFriendDo.WithContext(ctx)
}

func (r roomFriend) TableName() string { return r.roomFriendDo.TableName() }

func (r roomFriend) Alias() string { return r.roomFriendDo.Alias() }

func (r roomFriend) Columns(cols ...field.Expr) gen.Columns { return r.roomFriendDo.Columns(cols...) }

func (r *roomFriend) GetFieldByName(fieldName string) (field.OrderExpr, bool) {
	_f, ok := r.fieldMap[fieldName]
	if !ok || _f == nil {
		return nil, false
	}
	_oe, ok := _f.(field.OrderExpr)
	return _oe, ok
}

func (r *roomFriend) fillFieldMap() {
	r.fieldMap = make(map[string]field.Expr, 8)
	r.fieldMap["id"] = r.ID
	r.fieldMap["room_id"] = r.RoomID
	r.fieldMap["uid1"] = r.Uid1
	r.fieldMap["uid2"] = r.Uid2
	r.fieldMap["room_key"] = r.RoomKey
	r.fieldMap["delete_status"] = r.DeleteStatus
	r.fieldMap["create_time"] = r.CreateTime
	r.fieldMap["update_time"] = r.UpdateTime
}

func (r roomFriend) clone(db *gorm.DB) roomFriend {
	r.roomFriendDo.ReplaceConnPool(db.Statement.ConnPool)
	return r
}

func (r roomFriend) replaceDB(db *gorm.DB) roomFriend {
	r.roomFriendDo.ReplaceDB(db)
	return r
}

type roomFriendDo struct{ gen.DO }

type IRoomFriendDo interface {
	gen.SubQuery
	Debug() IRoomFriendDo
	WithContext(ctx context.Context) IRoomFriendDo
	WithResult(fc func(tx gen.Dao)) gen.ResultInfo
	ReplaceDB(db *gorm.DB)
	ReadDB() IRoomFriendDo
	WriteDB() IRoomFriendDo
	As(alias string) gen.Dao
	Session(config *gorm.Session) IRoomFriendDo
	Columns(cols ...field.Expr) gen.Columns
	Clauses(conds ...clause.Expression) IRoomFriendDo
	Not(conds ...gen.Condition) IRoomFriendDo
	Or(conds ...gen.Condition) IRoomFriendDo
	Select(conds ...field.Expr) IRoomFriendDo
	Where(conds ...gen.Condition) IRoomFriendDo
	Order(conds ...field.Expr) IRoomFriendDo
	Distinct(cols ...field.Expr) IRoomFriendDo
	Omit(cols ...field.Expr) IRoomFriendDo
	Join(table schema.Tabler, on ...field.Expr) IRoomFriendDo
	LeftJoin(table schema.Tabler, on ...field.Expr) IRoomFriendDo
	RightJoin(table schema.Tabler, on ...field.Expr) IRoomFriendDo
	Group(cols ...field.Expr) IRoomFriendDo
	Having(conds ...gen.Condition) IRoomFriendDo
	Limit(limit int) IRoomFriendDo
	Offset(offset int) IRoomFriendDo
	Count() (count int64, err error)
	Scopes(funcs ...func(gen.Dao) gen.Dao) IRoomFriendDo
	Unscoped() IRoomFriendDo
	Create(values ...*model.RoomFriend) error
	CreateInBatches(values []*model.RoomFriend, batchSize int) error
	Save(values ...*model.RoomFriend) error
	First() (*model.RoomFriend, error)
	Take() (*model.RoomFriend, error)
	Last() (*model.RoomFriend, error)
	Find() ([]*model.RoomFriend, error)
	FindInBatch(batchSize int, fc func(tx gen.Dao, batch int) error) (results []*model.RoomFriend, err error)
	FindInBatches(result *[]*model.RoomFriend, batchSize int, fc func(tx gen.Dao, batch int) error) error
	Pluck(column field.Expr, dest interface{}) error
	Delete(...*model.RoomFriend) (info gen.ResultInfo, err error)
	Update(column field.Expr, value interface{}) (info gen.ResultInfo, err error)
	UpdateSimple(columns ...field.AssignExpr) (info gen.ResultInfo, err error)
	Updates(value interface{}) (info gen.ResultInfo, err error)
	UpdateColumn(column field.Expr, value interface{}) (info gen.ResultInfo, err error)
	UpdateColumnSimple(columns ...field.AssignExpr) (info gen.ResultInfo, err error)
	UpdateColumns(value interface{}) (info gen.ResultInfo, err error)
	UpdateFrom(q gen.SubQuery) gen.Dao
	Attrs(attrs ...field.AssignExpr) IRoomFriendDo
	Assign(attrs ...field.AssignExpr) IRoomFriendDo
	Joins(fields ...field.RelationField) IRoomFriendDo
	Preload(fields ...field.RelationField) IRoomFriendDo
	FirstOrInit() (*model.RoomFriend, error)
	FirstOrCreate() (*model.RoomFriend, error)
	FindByPage(offset int, limit int) (result []*model.RoomFriend, count int64, err error)
	ScanByPage(result interface{}, offset int, limit int) (count int64, err error)
	Scan(result interface{}) (err error)
	Returning(value interface{}, columns ...string) IRoomFriendDo
	UnderlyingDB() *gorm.DB
	schema.Tabler
}

func (r roomFriendDo) Debug() IRoomFriendDo {
	return r.withDO(r.DO.Debug())
}

func (r roomFriendDo) WithContext(ctx context.Context) IRoomFriendDo {
	return r.withDO(r.DO.WithContext(ctx))
}

func (r roomFriendDo) ReadDB() IRoomFriendDo {
	return r.Clauses(dbresolver.Read)
}

func (r roomFriendDo) WriteDB() IRoomFriendDo {
	return r.Clauses(dbresolver.Write)
}

func (r roomFriendDo) Session(config *gorm.Session) IRoomFriendDo {
	return r.withDO(r.DO.Session(config))
}

func (r roomFriendDo) Clauses(conds ...clause.Expression) IRoomFriendDo {
	return r.withDO(r.DO.Clauses(conds...))
}

func (r roomFriendDo) Returning(value interface{}, columns ...string) IRoomFriendDo {
	return r.withDO(r.DO.Returning(value, columns...))
}

func (r roomFriendDo) Not(conds ...gen.Condition) IRoomFriendDo {
	return r.withDO(r.DO.Not(conds...))
}

func (r roomFriendDo) Or(conds ...gen.Condition) IRoomFriendDo {
	return r.withDO(r.DO.Or(conds...))
}

func (r roomFriendDo) Select(conds ...field.Expr) IRoomFriendDo {
	return r.withDO(r.DO.Select(conds...))
}

func (r roomFriendDo) Where(conds ...gen.Condition) IRoomFriendDo {
	return r.withDO(r.DO.Where(conds...))
}

func (r roomFriendDo) Order(conds ...field.Expr) IRoomFriendDo {
	return r.withDO(r.DO.Order(conds...))
}

func (r roomFriendDo) Distinct(cols ...field.Expr) IRoomFriendDo {
	return r.withDO(r.DO.Distinct(cols...))
}

func (r roomFriendDo) Omit(cols ...field.Expr) IRoomFriendDo {
	return r.withDO(r.DO.Omit(cols...))
}

func (r roomFriendDo) Join(table schema.Tabler, on ...field.Expr) IRoomFriendDo {
	return r.withDO(r.DO.Join(table, on...))
}

func (r roomFriendDo) LeftJoin(table schema.Tabler, on ...field.Expr) IRoomFriendDo {
	return r.withDO(r.DO.LeftJoin(table, on...))
}

func (r roomFriendDo) RightJoin(table schema.Tabler, on ...field.Expr) IRoomFriendDo {
	return r.withDO(r.DO.RightJoin(table, on...))
}

func (r roomFriendDo) Group(cols ...field.Expr) IRoomFriendDo {
	return r.withDO(r.DO.Group(cols...))
}

func (r roomFriendDo) Having(conds ...gen.Condition) IRoomFriendDo {
	return r.withDO(r.DO.Having(conds...))
}

func (r roomFriendDo) Limit(limit int) IRoomFriendDo {
	return r.withDO(r.DO.Limit(limit))
}

func (r roomFriendDo) Offset(offset int) IRoomFriendDo {
	return r.withDO(r.DO.Offset(offset))
}

func (r roomFriendDo) Scopes(funcs ...func(gen.Dao) gen.Dao) IRoomFriendDo {
	return r.withDO(r.DO.Scopes(funcs...))
}

func (r roomFriendDo) Unscoped() IRoomFriendDo {
	return r.withDO(r.DO.Unscoped())
}

func (r roomFriendDo) Create(values ...*model.RoomFriend) error {
	if len(values) == 0 {
		return nil
	}
	return r.DO.Create(values)
}

func (r roomFriendDo) CreateInBatches(values []*model.RoomFriend, batchSize int) error {
	return r.DO.CreateInBatches(values, batchSize)
}

// Save : !!! underlying implementation is different with GORM
// The method is equivalent to executing the statement: db.Clauses(clause.OnConflict{UpdateAll: true}).Create(values)
func (r roomFriendDo) Save(values ...*model.RoomFriend) error {
	if len(values) == 0 {
		return nil
	}
	return r.DO.Save(values)
}

func (r roomFriendDo) First() (*model.RoomFriend, error) {
	if result, err := r.DO.First(); err != nil {
		return nil, err
	} else {
		return result.(*model.RoomFriend), nil
	}
}

func (r roomFriendDo) Take() (*model.RoomFriend, error) {
	if result, err := r.DO.Take(); err != nil {
		return nil, err
	} else {
		return result.(*model.RoomFriend), nil
	}
}

func (r roomFriendDo) Last() (*model.RoomFriend, error) {
	if result, err := r.DO.Last(); err != nil {
		return nil, err
	} else {
		return result.(*model.RoomFriend), nil
	}
}

func (r roomFriendDo) Find() ([]*model.RoomFriend, error) {
	result, err := r.DO.Find()
	return result.([]*model.RoomFriend), err
}

func (r roomFriendDo) FindInBatch(batchSize int, fc func(tx gen.Dao, batch int) error) (results []*model.RoomFriend, err error) {
	buf := make([]*model.RoomFriend, 0, batchSize)
	err = r.DO.FindInBatches(&buf, batchSize, func(tx gen.Dao, batch int) error {
		defer func() { results = append(results, buf...) }()
		return fc(tx, batch)
	})
	return results, err
}

func (r roomFriendDo) FindInBatches(result *[]*model.RoomFriend, batchSize int, fc func(tx gen.Dao, batch int) error) error {
	return r.DO.FindInBatches(result, batchSize, fc)
}

func (r roomFriendDo) Attrs(attrs ...field.AssignExpr) IRoomFriendDo {
	return r.withDO(r.DO.Attrs(attrs...))
}

func (r roomFriendDo) Assign(attrs ...field.AssignExpr) IRoomFriendDo {
	return r.withDO(r.DO.Assign(attrs...))
}

func (r roomFriendDo) Joins(fields ...field.RelationField) IRoomFriendDo {
	for _, _f := range fields {
		r = *r.withDO(r.DO.Joins(_f))
	}
	return &r
}

func (r roomFriendDo) Preload(fields ...field.RelationField) IRoomFriendDo {
	for _, _f := range fields {
		r = *r.withDO(r.DO.Preload(_f))
	}
	return &r
}

func (r roomFriendDo) FirstOrInit() (*model.RoomFriend, error) {
	if result, err := r.DO.FirstOrInit(); err != nil {
		return nil, err
	} else {
		return result.(*model.RoomFriend), nil
	}
}

func (r roomFriendDo) FirstOrCreate() (*model.RoomFriend, error) {
	if result, err := r.DO.FirstOrCreate(); err != nil {
		return nil, err
	} else {
		return result.(*model.RoomFriend), nil
	}
}

func (r roomFriendDo) FindByPage(offset int, limit int) (result []*model.RoomFriend, count int64, err error) {
	result, err = r.Offset(offset).Limit(limit).Find()
	if err != nil {
		return
	}

	if size := len(result); 0 < limit && 0 < size && size < limit {
		count = int64(size + offset)
		return
	}

	count, err = r.Offset(-1).Limit(-1).Count()
	return
}

func (r roomFriendDo) ScanByPage(result interface{}, offset int, limit int) (count int64, err error) {
	count, err = r.Count()
	if err != nil {
		return
	}

	err = r.Offset(offset).Limit(limit).Scan(result)
	return
}

func (r roomFriendDo) Scan(result interface{}) (err error) {
	return r.DO.Scan(result)
}

func (r roomFriendDo) Delete(models ...*model.RoomFriend) (result gen.ResultInfo, err error) {
	return r.DO.Delete(models)
}

func (r *roomFriendDo) withDO(do gen.Dao) *roomFriendDo {
	r.DO = *do.(*gen.DO)
	return r
}


================================================
FILE: dal/query/room_group.gen.go
================================================
// Code generated by gorm.io/gen. DO NOT EDIT.
// Code generated by gorm.io/gen. DO NOT EDIT.
// Code generated by gorm.io/gen. DO NOT EDIT.

package query

import (
	"context"

	"gorm.io/gorm"
	"gorm.io/gorm/clause"
	"gorm.io/gorm/schema"

	"gorm.io/gen"
	"gorm.io/gen/field"

	"gorm.io/plugin/dbresolver"

	"DiTing-Go/dal/model"
)

func newRoomGroup(db *gorm.DB, opts ...gen.DOOption) roomGroup {
	_roomGroup := roomGroup{}

	_roomGroup.roomGroupDo.UseDB(db, opts...)
	_roomGroup.roomGroupDo.UseModel(&model.RoomGroup{})

	tableName := _roomGroup.roomGroupDo.TableName()
	_roomGroup.ALL = field.NewAsterisk(tableName)
	_roomGroup.ID = field.NewInt64(tableName, "id")
	_roomGroup.RoomID = field.NewInt64(tableName, "room_id")
	_roomGroup.Name = field.NewString(tableName, "name")
	_roomGroup.Avatar = field.NewString(tableName, "avatar")
	_roomGroup.ExtJSON = field.NewString(tableName, "ext_json")
	_roomGroup.DeleteStatus = field.NewInt32(tableName, "delete_status")
	_roomGroup.CreateTime = field.NewTime(tableName, "create_time")
	_roomGroup.UpdateTime = field.NewTime(tableName, "update_time")

	_roomGroup.fillFieldMap()

	return _roomGroup
}

// roomGroup 群聊房间表
type roomGroup struct {
	roomGroupDo roomGroupDo

	ALL          field.Asterisk
	ID           field.Int64  // id
	RoomID       field.Int64  // 房间id
	Name         field.String // 群名称
	Avatar       field.String // 群头像
	ExtJSON      field.String // 额外信息(根据不同类型房间有不同存储的东西)
	DeleteStatus field.Int32  // 逻辑删除(0-正常,1-删除)
	CreateTime   field.Time   // 创建时间
	UpdateTime   field.Time   // 修改时间

	fieldMap map[string]field.Expr
}

func (r roomGroup) Table(newTableName string) *roomGroup {
	r.roomGroupDo.UseTable(newTableName)
	return r.updateTableName(newTableName)
}

func (r roomGroup) As(alias string) *roomGroup {
	r.roomGroupDo.DO = *(r.roomGroupDo.As(alias).(*gen.DO))
	return r.updateTableName(alias)
}

func (r *roomGroup) updateTableName(table string) *roomGroup {
	r.ALL = field.NewAsterisk(table)
	r.ID = field.NewInt64(table, "id")
	r.RoomID = field.NewInt64(table, "room_id")
	r.Name = field.NewString(table, "name")
	r.Avatar = field.NewString(table, "avatar")
	r.ExtJSON = field.NewString(table, "ext_json")
	r.DeleteStatus = field.NewInt32(table, "delete_status")
	r.CreateTime = field.NewTime(table, "create_time")
	r.UpdateTime = field.NewTime(table, "update_time")

	r.fillFieldMap()

	return r
}

func (r *roomGroup) WithContext(ctx context.Context) IRoomGroupDo {
	return r.roomGroupDo.WithContext(ctx)
}

func (r roomGroup) TableName() string { return r.roomGroupDo.TableName() }

func (r roomGroup) Alias() string { return r.roomGroupDo.Alias() }

func (r roomGroup) Columns(cols ...field.Expr) gen.Columns { return r.roomGroupDo.Columns(cols...) }

func (r *roomGroup) GetFieldByName(fieldName string) (field.OrderExpr, bool) {
	_f, ok := r.fieldMap[fieldName]
	if !ok || _f == nil {
		return nil, false
	}
	_oe, ok := _f.(field.OrderExpr)
	return _oe, ok
}

func (r *roomGroup) fillFieldMap() {
	r.fieldMap = make(map[string]field.Expr, 8)
	r.fieldMap["id"] = r.ID
	r.fieldMap["room_id"] = r.RoomID
	r.fieldMap["name"] = r.Name
	r.fieldMap["avatar"] = r.Avatar
	r.fieldMap["ext_json"] = r.ExtJSON
	r.fieldMap["delete_status"] = r.DeleteStatus
	r.fieldMap["create_time"] = r.CreateTime
	r.fieldMap["update_time"] = r.UpdateTime
}

func (r roomGroup) clone(db *gorm.DB) roomGroup {
	r.roomGroupDo.ReplaceConnPool(db.Statement.ConnPool)
	return r
}

func (r roomGroup) replaceDB(db *gorm.DB) roomGroup {
	r.roomGroupDo.ReplaceDB(db)
	return r
}

type roomGroupDo struct{ gen.DO }

type IRoomGroupDo interface {
	gen.SubQuery
	Debug() IRoomGroupDo
	WithContext(ctx context.Context) IRoomGroupDo
	WithResult(fc func(tx gen.Dao)) gen.ResultInfo
	ReplaceDB(db *gorm.DB)
	ReadDB() IRoomGroupDo
	WriteDB() IRoomGroupDo
	As(alias string) gen.Dao
	Session(config *gorm.Session) IRoomGroupDo
	Columns(cols ...field.Expr) gen.Columns
	Clauses(conds ...clause.Expression) IRoomGroupDo
	Not(conds ...gen.Condition) IRoomGroupDo
	Or(conds ...gen.Condition) IRoomGroupDo
	Select(conds ...field.Expr) IRoomGroupDo
	Where(conds ...gen.Condition) IRoomGroupDo
	Order(conds ...field.Expr) IRoomGroupDo
	Distinct(cols ...field.Expr) IRoomGroupDo
	Omit(cols ...field.Expr) IRoomGroupDo
	Join(table schema.Tabler, on ...field.Expr) IRoomGroupDo
	LeftJoin(table schema.Tabler, on ...field.Expr) IRoomGroupDo
	RightJoin(table schema.Tabler, on ...field.Expr) IRoomGroupDo
	Group(cols ...field.Expr) IRoomGroupDo
	Having(conds ...gen.Condition) IRoomGroupDo
	Limit(limit int) IRoomGroupDo
	Offset(offset int) IRoomGroupDo
	Count() (count int64, err error)
	Scopes(funcs ...func(gen.Dao) gen.Dao) IRoomGroupDo
	Unscoped() IRoomGroupDo
	Create(values ...*model.RoomGroup) error
	CreateInBatches(values []*model.RoomGroup, batchSize int) error
	Save(values ...*model.RoomGroup) error
	First() (*model.RoomGroup, error)
	Take() (*model.RoomGroup, error)
	Last() (*model.RoomGroup, error)
	Find() ([]*model.RoomGroup, error)
	FindInBatch(batchSize int, fc func(tx gen.Dao, batch int) error) (results []*model.RoomGroup, err error)
	FindInBatches(result *[]*model.RoomGroup, batchSize int, fc func(tx gen.Dao, batch int) error) error
	Pluck(column field.Expr, dest interface{}) error
	Delete(...*model.RoomGroup) (info gen.ResultInfo, err error)
	Update(column field.Expr, value interface{}) (info gen.ResultInfo, err error)
	UpdateSimple(columns ...field.AssignExpr) (info gen.ResultInfo, err error)
	Updates(value interface{}) (info gen.ResultInfo, err error)
	UpdateColumn(column field.Expr, value interface{}) (info gen.ResultInfo, err error)
	UpdateColumnSimple(columns ...field.AssignExpr) (info gen.ResultInfo, err error)
	UpdateColumns(value interface{}) (info gen.ResultInfo, err error)
	UpdateFrom(q gen.SubQuery) gen.Dao
	Attrs(attrs ...field.AssignExpr) IRoomGroupDo
	Assign(attrs ...field.AssignExpr) IRoomGroupDo
	Joins(fields ...field.RelationField) IRoomGroupDo
	Preload(fields ...field.RelationField) IRoomGroupDo
	FirstOrInit() (*model.RoomGroup, error)
	FirstOrCreate() (*model.RoomGroup, error)
	FindByPage(offset int, limit int) (result []*model.RoomGroup, count int64, err error)
	ScanByPage(result interface{}, offset int, limit int) (count int64, err error)
	Scan(result interface{}) (err error)
	Returning(value interface{}, columns ...string) IRoomGroupDo
	UnderlyingDB() *gorm.DB
	schema.Tabler
}

func (r roomGroupDo) Debug() IRoomGroupDo {
	return r.withDO(r.DO.Debug())
}

func (r roomGroupDo) WithContext(ctx context.Context) IRoomGroupDo {
	return r.withDO(r.DO.WithContext(ctx))
}

func (r roomGroupDo) ReadDB() IRoomGroupDo {
	return r.Clauses(dbresolver.Read)
}

func (r roomGroupDo) WriteDB() IRoomGroupDo {
	return r.Clauses(dbresolver.Write)
}

func (r roomGroupDo) Session(config *gorm.Session) IRoomGroupDo {
	return r.withDO(r.DO.Session(config))
}

func (r roomGroupDo) Clauses(conds ...clause.Expression) IRoomGroupDo {
	return r.withDO(r.DO.Clauses(conds...))
}

func (r roomGroupDo) Returning(value interface{}, columns ...string) IRoomGroupDo {
	return r.withDO(r.DO.Returning(value, columns...))
}

func (r roomGroupDo) Not(conds ...gen.Condition) IRoomGroupDo {
	return r.withDO(r.DO.Not(conds...))
}

func (r roomGroupDo) Or(conds ...gen.Condition) IRoomGroupDo {
	return r.withDO(r.DO.Or(conds...))
}

func (r roomGroupDo) Select(conds ...field.Expr) IRoomGroupDo {
	return r.withDO(r.DO.Select(conds...))
}

func (r roomGroupDo) Where(conds ...gen.Condition) IRoomGroupDo {
	return r.withDO(r.DO.Where(conds...))
}

func (r roomGroupDo) Order(conds ...field.Expr) IRoomGroupDo {
	return r.withDO(r.DO.Order(conds...))
}

func (r roomGroupDo) Distinct(cols ...field.Expr) IRoomGroupDo {
	return r.withDO(r.DO.Distinct(cols...))
}

func (r roomGroupDo) Omit(cols ...field.Expr) IRoomGroupDo {
	return r.withDO(r.DO.Omit(cols...))
}

func (r roomGroupDo) Join(table schema.Tabler, on ...field.Expr) IRoomGroupDo {
	return r.withDO(r.DO.Join(table, on...))
}

func (r roomGroupDo) LeftJoin(table schema.Tabler, on ...field.Expr) IRoomGroupDo {
	return r.withDO(r.DO.LeftJoin(table, on...))
}

func (r roomGroupDo) RightJoin(table schema.Tabler, on ...field.Expr) IRoomGroupDo {
	return r.withDO(r.DO.RightJoin(table, on...))
}

func (r roomGroupDo) Group(cols ...field.Expr) IRoomGroupDo {
	return r.withDO(r.DO.Group(cols...))
}

func (r roomGroupDo) Having(conds ...gen.Condition) IRoomGroupDo {
	return r.withDO(r.DO.Having(conds...))
}

func (r roomGroupDo) Limit(limit int) IRoomGroupDo {
	return r.withDO(r.DO.Limit(limit))
}

func (r roomGroupDo) Offset(offset int) IRoomGroupDo {
	return r.withDO(r.DO.Offset(offset))
}

func (r roomGroupDo) Scopes(funcs ...func(gen.Dao) gen.Dao) IRoomGroupDo {
	return r.withDO(r.DO.Scopes(funcs...))
}

func (r roomGroupDo) Unscoped() IRoomGroupDo {
	return r.withDO(r.DO.Unscoped())
}

func (r roomGroupDo) Create(values ...*model.RoomGroup) error {
	if len(values) == 0 {
		return nil
	}
	return r.DO.Create(values)
}

func (r roomGroupDo) CreateInBatches(values []*model.RoomGroup, batchSize int) error {
	return r.DO.CreateInBatches(values, batchSize)
}

// Save : !!! underlying implementation is different with GORM
// The method is equivalent to executing the statement: db.Clauses(clause.OnConflict{UpdateAll: true}).Create(values)
func (r roomGroupDo) Save(values ...*model.RoomGroup) error {
	if len(values) == 0 {
		return nil
	}
	return r.DO.Save(values)
}

func (r roomGroupDo) First() (*model.RoomGroup, error) {
	if result, err := r.DO.First(); err != nil {
		return nil, err
	} else {
		return result.(*model.RoomGroup), nil
	}
}

func (r roomGroupDo) Take() (*model.RoomGroup, error) {
	if result, err := r.DO.Take(); err != nil {
		return nil, err
	} else {
		return result.(*model.RoomGroup), nil
	}
}

func (r roomGroupDo) Last() (*model.RoomGroup, error) {
	if result, err := r.DO.Last(); err != nil {
		return nil, err
	} else {
		return result.(*model.RoomGroup), nil
	}
}

func (r roomGroupDo) Find() ([]*model.RoomGroup, error) {
	result, err := r.DO.Find()
	return result.([]*model.RoomGroup), err
}

func (r roomGroupDo) FindInBatch(batchSize int, fc func(tx gen.Dao, batch int) error) (results []*model.RoomGroup, err error) {
	buf := make([]*model.RoomGroup, 0, batchSize)
	err = r.DO.FindInBatches(&buf, batchSize, func(tx gen.Dao, batch int) error {
		defer func() { results = append(results, buf...) }()
		return fc(tx, batch)
	})
	return results, err
}

func (r roomGroupDo) FindInBatches(result *[]*model.RoomGroup, batchSize int, fc func(tx gen.Dao, batch int) error) error {
	return r.DO.FindInBatches(result, batchSize, fc)
}

func (r roomGroupDo) Attrs(attrs ...field.AssignExpr) IRoomGroupDo {
	return r.withDO(r.DO.Attrs(attrs...))
}

func (r roomGroupDo) Assign(attrs ...field.AssignExpr) IRoomGroupDo {
	return r.withDO(r.DO.Assign(attrs...))
}

func (r roomGroupDo) Joins(fields ...field.RelationField) IRoomGroupDo {
	for _, _f := range fields {
		r = *r.withDO(r.DO.Joins(_f))
	}
	return &r
}

func (r roomGroupDo) Preload(fields ...field.RelationField) IRoomGroupDo {
	for _, _f := range fields {
		r = *r.withDO(r.DO.Preload(_f))
	}
	return &r
}

func (r roomGroupDo) FirstOrInit() (*model.RoomGroup, error) {
	if result, err := r.DO.FirstOrInit(); err != nil {
		return nil, err
	} else {
		return result.(*model.RoomGroup), nil
	}
}

func (r roomGroupDo) FirstOrCreate() (*model.RoomGroup, error) {
	if result, err := r.DO.FirstOrCreate(); err != nil {
		return nil, err
	} else {
		return result.(*model.RoomGroup), nil
	}
}

func (r roomGroupDo) FindByPage(offset int, limit int) (result []*model.RoomGroup, count int64, err error) {
	result, err = r.Offset(offset).Limit(limit).Find()
	if err != nil {
		return
	}

	if size := len(result); 0 < limit && 0 < size && size < limit {
		count = int64(size + offset)
		return
	}

	count, err = r.Offset(-1).Limit(-1).Count()
	return
}

func (r roomGroupDo) ScanByPage(result interface{}, offset int, limit int) (count int64, err error) {
	count, err = r.Count()
	if err != nil {
		return
	}

	err = r.Offset(offset).Limit(limit).Scan(result)
	return
}

func (r roomGroupDo) Scan(result interface{}) (err error) {
	return r.DO.Scan(result)
}

func (r roomGroupDo) Delete(models ...*model.RoomGroup) (result gen.ResultInfo, err error) {
	return r.DO.Delete(models)
}

func (r *roomGroupDo) withDO(do gen.Dao) *roomGroupDo {
	r.DO = *do.(*gen.DO)
	return r
}


================================================
FILE: dal/query/user.gen.go
================================================
// Code generated by gorm.io/gen. DO NOT EDIT.
// Code generated by gorm.io/gen. DO NOT EDIT.
// Code generated by gorm.io/gen. DO NOT EDIT.

package query

import (
	"context"

	"gorm.io/gorm"
	"gorm.io/gorm/clause"
	"gorm.io/gorm/schema"

	"gorm.io/gen"
	"gorm.io/gen/field"

	"gorm.io/plugin/dbresolver"

	"DiTing-Go/dal/model"
)

func newUser(db *gorm.DB, opts ...gen.DOOption) user {
	_user := user{}

	_user.userDo.UseDB(db, opts...)
	_user.userDo.UseModel(&model.User{})

	tableName := _user.userDo.TableName()
	_user.ALL = field.NewAsterisk(tableName)
	_user.ID = field.NewInt64(tableName, "id")
	_user.Phone = field.NewString(tableName, "phone")
	_user.Password = field.NewString(tableName, "password")
	_user.Name = field.NewString(tableName, "name")
	_user.Avatar = field.NewString(tableName, "avatar")
	_user.Sex = field.NewInt32(tableName, "sex")
	_user.ActiveStatus = field.NewInt32(tableName, "active_status")
	_user.LastOptTime = field.NewTime(tableName, "last_opt_time")
	_user.IPInfo = field.NewString(tableName, "ip_info")
	_user.ItemID = field.NewInt64(tableName, "item_id")
	_user.Status = field.NewInt32(tableName, "status")
	_user.CreateTime = field.NewTime(tableName, "create_time")
	_user.UpdateTime = field.NewTime(tableName, "update_time")

	_user.fillFieldMap()

	return _user
}

// user 用户表
type user struct {
	userDo userDo

	ALL          field.Asterisk
	ID           field.Int64  // 用户id
	Phone        field.String // 用户手机
	Password     field.String // 用户密码
	Name         field.String // 用户昵称
	Avatar       field.String // 用户头像
	Sex          field.Int32  // 性别 1为男性,2为女性,3未知
	ActiveStatus field.Int32  // 在线状态 1在线 2离线
	LastOptTime  field.Time   // 最后上下线时间
	IPInfo       field.String // ip信息,用于显示用户地理位置
	ItemID       field.Int64  // 佩戴的徽章id
	Status       field.Int32  // 使用状态 1.正常 2禁用
	CreateTime   field.Time   // 创建时间
	UpdateTime   field.Time   // 修改时间

	fieldMap map[string]field.Expr
}

func (u user) Table(newTableName string) *user {
	u.userDo.UseTable(newTableName)
	return u.updateTableName(newTableName)
}

func (u user) As(alias string) *user {
	u.userDo.DO = *(u.userDo.As(alias).(*gen.DO))
	return u.updateTableName(alias)
}

func (u *user) updateTableName(table string) *user {
	u.ALL = field.NewAsterisk(table)
	u.ID = field.NewInt64(table, "id")
	u.Phone = field.NewString(table, "phone")
	u.Password = field.NewString(table, "password")
	u.Name = field.NewString(table, "name")
	u.Avatar = field.NewString(table, "avatar")
	u.Sex = field.NewInt32(table, "sex")
	u.ActiveStatus = field.NewInt32(table, "active_status")
	u.LastOptTime = field.NewTime(table, "last_opt_time")
	u.IPInfo = field.NewString(table, "ip_info")
	u.ItemID = field.NewInt64(table, "item_id")
	u.Status = field.NewInt32(table, "status")
	u.CreateTime = field.NewTime(table, "create_time")
	u.UpdateTime = field.NewTime(table, "update_time")

	u.fillFieldMap()

	return u
}

func (u *user) WithContext(ctx context.Context) IUserDo { return u.userDo.WithContext(ctx) }

func (u user) TableName() string { return u.userDo.TableName() }

func (u user) Alias() string { return u.userDo.Alias() }

func (u user) Columns(cols ...field.Expr) gen.Columns { return u.userDo.Columns(cols...) }

func (u *user) GetFieldByName(fieldName string) (field.OrderExpr, bool) {
	_f, ok := u.fieldMap[fieldName]
	if !ok || _f == nil {
		return nil, false
	}
	_oe, ok := _f.(field.OrderExpr)
	return _oe, ok
}

func (u *user) fillFieldMap() {
	u.fieldMap = make(map[string]field.Expr, 13)
	u.fieldMap["id"] = u.ID
	u.fieldMap["phone"] = u.Phone
	u.fieldMap["password"] = u.Password
	u.fieldMap["name"] = u.Name
	u.fieldMap["avatar"] = u.Avatar
	u.fieldMap["sex"] = u.Sex
	u.fieldMap["active_status"] = u.ActiveStatus
	u.fieldMap["last_opt_time"] = u.LastOptTime
	u.fieldMap["ip_info"] = u.IPInfo
	u.fieldMap["item_id"] = u.ItemID
	u.fieldMap["status"] = u.Status
	u.fieldMap["create_time"] = u.CreateTime
	u.fieldMap["update_time"] = u.UpdateTime
}

func (u user) clone(db *gorm.DB) user {
	u.userDo.ReplaceConnPool(db.Statement.ConnPool)
	return u
}

func (u user) replaceDB(db *gorm.DB) user {
	u.userDo.ReplaceDB(db)
	return u
}

type userDo struct{ gen.DO }

type IUserDo interface {
	gen.SubQuery
	Debug() IUserDo
	WithContext(ctx context.Context) IUserDo
	WithResult(fc func(tx gen.Dao)) gen.ResultInfo
	ReplaceDB(db *gorm.DB)
	ReadDB() IUserDo
	WriteDB() IUserDo
	As(alias string) gen.Dao
	Session(config *gorm.Session) IUserDo
	Columns(cols ...field.Expr) gen.Columns
	Clauses(conds ...clause.Expression) IUserDo
	Not(conds ...gen.Condition) IUserDo
	Or(conds ...gen.Condition) IUserDo
	Select(conds ...field.Expr) IUserDo
	Where(conds ...gen.Condition) IUserDo
	Order(conds ...field.Expr) IUserDo
	Distinct(cols ...field.Expr) IUserDo
	Omit(cols ...field.Expr) IUserDo
	Join(table schema.Tabler, on ...field.Expr) IUserDo
	LeftJoin(table schema.Tabler, on ...field.Expr) IUserDo
	RightJoin(table schema.Tabler, on ...field.Expr) IUserDo
	Group(cols ...field.Expr) IUserDo
	Having(conds ...gen.Condition) IUserDo
	Limit(limit int) IUserDo
	Offset(offset int) IUserDo
	Count() (count int64, err error)
	Scopes(funcs ...func(gen.Dao) gen.Dao) IUserDo
	Unscoped() IUserDo
	Create(values ...*model.User) error
	CreateInBatches(values []*model.User, batchSize int) error
	Save(values ...*model.User) error
	First() (*model.User, error)
	Take() (*model.User, error)
	Last() (*model.User, error)
	Find() ([]*model.User, error)
	FindInBatch(batchSize int, fc func(tx gen.Dao, batch int) error) (results []*model.User, err error)
	FindInBatches(result *[]*model.User, batchSize int, fc func(tx gen.Dao, batch int) error) error
	Pluck(column field.Expr, dest interface{}) error
	Delete(...*model.User) (info gen.ResultInfo, err error)
	Update(column field.Expr, value interface{}) (info gen.ResultInfo, err error)
	UpdateSimple(columns ...field.AssignExpr) (info gen.ResultInfo, err error)
	Updates(value interface{}) (info gen.ResultInfo, err error)
	UpdateColumn(column field.Expr, value interface{}) (info gen.ResultInfo, err error)
	UpdateColumnSimple(columns ...field.AssignExpr) (info gen.ResultInfo, err error)
	UpdateColumns(value interface{}) (info gen.ResultInfo, err error)
	UpdateFrom(q gen.SubQuery) gen.Dao
	Attrs(attrs ...field.AssignExpr) IUserDo
	Assign(attrs ...field.AssignExpr) IUserDo
	Joins(fields ...field.RelationField) IUserDo
	Preload(fields ...field.RelationField) IUserDo
	FirstOrInit() (*model.User, error)
	FirstOrCreate() (*model.User, error)
	FindByPage(offset int, limit int) (result []*model.User, count int64, err error)
	ScanByPage(result interface{}, offset int, limit int) (count int64, err error)
	Scan(result interface{}) (err error)
	Returning(value interface{}, columns ...string) IUserDo
	UnderlyingDB() *gorm.DB
	schema.Tabler
}

func (u userDo) Debug() IUserDo {
	return u.withDO(u.DO.Debug())
}

func (u userDo) WithContext(ctx context.Context) IUserDo {
	return u.withDO(u.DO.WithContext(ctx))
}

func (u userDo) ReadDB() IUserDo {
	return u.Clauses(dbresolver.Read)
}

func (u userDo) WriteDB() IUserDo {
	return u.Clauses(dbresolver.Write)
}

func (u userDo) Session(config *gorm.Session) IUserDo {
	return u.withDO(u.DO.Session(config))
}

func (u userDo) Clauses(conds ...clause.Expression) IUserDo {
	return u.withDO(u.DO.Clauses(conds...))
}

func (u userDo) Returning(value interface{}, columns ...string) IUserDo {
	return u.withDO(u.DO.Returning(value, columns...))
}

func (u userDo) Not(conds ...gen.Condition) IUserDo {
	return u.withDO(u.DO.Not(conds...))
}

func (u userDo) Or(conds ...gen.Condition) IUserDo {
	return u.withDO(u.DO.Or(conds...))
}

func (u userDo) Select(conds ...field.Expr) IUserDo {
	return u.withDO(u.DO.Select(conds...))
}

func (u userDo) Where(conds ...gen.Condition) IUserDo {
	return u.withDO(u.DO.Where(conds...))
}

func (u userDo) Order(conds ...field.Expr) IUserDo {
	return u.withDO(u.DO.Order(conds...))
}

func (u userDo) Distinct(cols ...field.Expr) IUserDo {
	return u.withDO(u.DO.Distinct(cols...))
}

func (u userDo) Omit(cols ...field.Expr) IUserDo {
	return u.withDO(u.DO.Omit(cols...))
}

func (u userDo) Join(table schema.Tabler, on ...field.Expr) IUserDo {
	return u.withDO(u.DO.Join(table, on...))
}

func (u userDo) LeftJoin(table schema.Tabler, on ...field.Expr) IUserDo {
	return u.withDO(u.DO.LeftJoin(table, on...))
}

func (u userDo) RightJoin(table schema.Tabler, on ...field.Expr) IUserDo {
	return u.withDO(u.DO.RightJoin(table, on...))
}

func (u userDo) Group(cols ...field.Expr) IUserDo {
	return u.withDO(u.DO.Group(cols...))
}

func (u userDo) Having(conds ...gen.Condition) IUserDo {
	return u.withDO(u.DO.Having(conds...))
}

func (u userDo) Limit(limit int) IUserDo {
	return u.withDO(u.DO.Limit(limit))
}

func (u userDo) Offset(offset int) IUserDo {
	return u.withDO(u.DO.Offset(offset))
}

func (u userDo) Scopes(funcs ...func(gen.Dao) gen.Dao) IUserDo {
	return u.withDO(u.DO.Scopes(funcs...))
}

func (u userDo) Unscoped() IUserDo {
	return u.withDO(u.DO.Unscoped())
}

func (u userDo) Create(values ...*model.User) error {
	if len(values) == 0 {
		return nil
	}
	return u.DO.Create(values)
}

func (u userDo) CreateInBatches(values []*model.User, batchSize int) error {
	return u.DO.CreateInBatches(values, batchSize)
}

// Save : !!! underlying implementation is different with GORM
// The method is equivalent to executing the statement: db.Clauses(clause.OnConflict{UpdateAll: true}).Create(values)
func (u userDo) Save(values ...*model.User) error {
	if len(values) == 0 {
		return nil
	}
	return u.DO.Save(values)
}

func (u userDo) First() (*model.User, error) {
	if result, err := u.DO.First(); err != nil {
		return nil, err
	} else {
		return result.(*model.User), nil
	}
}

func (u userDo) Take() (*model.User, error) {
	if result, err := u.DO.Take(); err != nil {
		return nil, err
	} else {
		return result.(*model.User), nil
	}
}

func (u userDo) Last() (*model.User, error) {
	if result, err := u.DO.Last(); err != nil {
		return nil, err
	} else {
		return result.(*model.User), nil
	}
}

func (u userDo) Find() ([]*model.User, error) {
	result, err := u.DO.Find()
	return result.([]*model.User), err
}

func (u userDo) FindInBatch(batchSize int, fc func(tx gen.Dao, batch int) error) (results []*model.User, err error) {
	buf := make([]*model.User, 0, batchSize)
	err = u.DO.FindInBatches(&buf, batchSize, func(tx gen.Dao, batch int) error {
		defer func() { results = append(results, buf...) }()
		return fc(tx, batch)
	})
	return results, err
}

func (u userDo) FindInBatches(result *[]*model.User, batchSize int, fc func(tx gen.Dao, batch int) error) error {
	return u.DO.FindInBatches(result, batchSize, fc)
}

func (u userDo) Attrs(attrs ...field.AssignExpr) IUserDo {
	return u.withDO(u.DO.Attrs(attrs...))
}

func (u userDo) Assign(attrs ...field.AssignExpr) IUserDo {
	return u.withDO(u.DO.Assign(attrs...))
}

func (u userDo) Joins(fields ...field.RelationField) IUserDo {
	for _, _f := range fields {
		u = *u.withDO(u.DO.Joins(_f))
	}
	return &u
}

func (u userDo) Preload(fields ...field.RelationField) IUserDo {
	for _, _f := range fields {
		u = *u.withDO(u.DO.Preload(_f))
	}
	return &u
}

func (u userDo) FirstOrInit() (*model.User, error) {
	if result, err := u.DO.FirstOrInit(); err != nil {
		return nil, err
	} else {
		return result.(*model.User), nil
	}
}

func (u userDo) FirstOrCreate() (*model.User, error) {
	if result, err := u.DO.FirstOrCreate(); err != nil {
		return nil, err
	} else {
		return result.(*model.User), nil
	}
}

func (u userDo) FindByPage(offset int, limit int) (result []*model.User, count int64, err error) {
	result, err = u.Offset(offset).Limit(limit).Find()
	if err != nil {
		return
	}

	if size := len(result); 0 < limit && 0 < size && size < limit {
		count = int64(size + offset)
		return
	}

	count, err = u.Offset(-1).Limit(-1).Count()
	return
}

func (u userDo) ScanByPage(result interface{}, offset int, limit int) (count int64, err error) {
	count, err = u.Count()
	if err != nil {
		return
	}

	err = u.Offset(offset).Limit(limit).Scan(result)
	return
}

func (u userDo) Scan(result interface{}) (err error) {
	return u.DO.Scan(result)
}

func (u userDo) Delete(models ...*model.User) (result gen.ResultInfo, err error) {
	return u.DO.Delete(models)
}

func (u *userDo) withDO(do gen.Dao) *userDo {
	u.DO = *do.(*gen.DO)
	return u
}


================================================
FILE: dal/query/user_apply.gen.go
================================================
// Code generated by gorm.io/gen. DO NOT EDIT.
// Code generated by gorm.io/gen. DO NOT EDIT.
// Code generated by gorm.io/gen. DO NOT EDIT.

package query

import (
	"context"

	"gorm.io/gorm"
	"gorm.io/gorm/clause"
	"gorm.io/gorm/schema"

	"gorm.io/gen"
	"gorm.io/gen/field"

	"gorm.io/plugin/dbresolver"

	"DiTing-Go/dal/model"
)

func newUserApply(db *gorm.DB, opts ...gen.DOOption) userApply {
	_userApply := userApply{}

	_userApply.userApplyDo.UseDB(db, opts...)
	_userApply.userApplyDo.UseModel(&model.UserApply{})

	tableName := _userApply.userApplyDo.TableName()
	_userApply.ALL = field.NewAsterisk(tableName)
	_userApply.ID = field.NewInt64(tableName, "id")
	_userApply.UID = field.NewInt64(tableName, "uid")
	_userApply.Type = field.NewInt32(tableName, "type")
	_userApply.TargetID = field.NewInt64(tableName, "target_id")
	_userApply.Msg = field.NewString(tableName, "msg")
	_userApply.Status = field.NewInt32(tableName, "status")
	_userApply.ReadStatus = field.NewInt32(tableName, "read_status")
	_userApply.CreateTime = field.NewTime(tableName, "create_time")
	_userApply.UpdateTime = field.NewTime(tableName, "update_time")

	_userApply.fillFieldMap()

	return _userApply
}

// userApply 用户申请表
type userApply struct {
	userApplyDo userApplyDo

	ALL        field.Asterisk
	ID         field.Int64  // id
	UID        field.Int64  // 申请人uid
	Type       field.Int32  // 申请类型 1加好友
	TargetID   field.Int64  // 接收人uid
	Msg        field.String // 申请信息
	Status     field.Int32  // 申请状态 1待审批 2同意
	ReadStatus field.Int32  // 阅读状态 1未读 2已读
	CreateTime field.Time   // 创建时间
	UpdateTime field.Time   // 修改时间

	fieldMap map[string]field.Expr
}

func (u userApply) Table(newTableName string) *userApply {
	u.userApplyDo.UseTable(newTableName)
	return u.updateTableName(newTableName)
}

func (u userApply) As(alias string) *userApply {
	u.userApplyDo.DO = *(u.userApplyDo.As(alias).(*gen.DO))
	return u.updateTableName(alias)
}

func (u *userApply) updateTableName(table string) *userApply {
	u.ALL = field.NewAsterisk(table)
	u.ID = field.NewInt64(table, "id")
	u.UID = field.NewInt64(table, "uid")
	u.Type = field.NewInt32(table, "type")
	u.TargetID = field.NewInt64(table, "target_id")
	u.Msg = field.NewString(table, "msg")
	u.Status = field.NewInt32(table, "status")
	u.ReadStatus = field.NewInt32(table, "read_status")
	u.CreateTime = field.NewTime(table, "create_time")
	u.UpdateTime = field.NewTime(table, "update_time")

	u.fillFieldMap()

	return u
}

func (u *userApply) WithContext(ctx context.Context) IUserApplyDo {
	return u.userApplyDo.WithContext(ctx)
}

func (u userApply) TableName() string { return u.userApplyDo.TableName() }

func (u userApply) Alias() string { return u.userApplyDo.Alias() }

func (u userApply) Columns(cols ...field.Expr) gen.Columns { return u.userApplyDo.Columns(cols...) }

func (u *userApply) GetFieldByName(fieldName string) (field.OrderExpr, bool) {
	_f, ok := u.fieldMap[fieldName]
	if !ok || _f == nil {
		return nil, false
	}
	_oe, ok := _f.(field.OrderExpr)
	return _oe, ok
}

func (u *userApply) fillFieldMap() {
	u.fieldMap = make(map[string]field.Expr, 9)
	u.fieldMap["id"] = u.ID
	u.fieldMap["uid"] = u.UID
	u.fieldMap["type"] = u.Type
	u.fieldMap["target_id"] = u.TargetID
	u.fieldMap["msg"] = u.Msg
	u.fieldMap["status"] = u.Status
	u.fieldMap["read_status"] = u.ReadStatus
	u.fieldMap["create_time"] = u.CreateTime
	u.fieldMap["update_time"] = u.UpdateTime
}

func (u userApply) clone(db *gorm.DB) userApply {
	u.userApplyDo.ReplaceConnPool(db.Statement.ConnPool)
	return u
}

func (u userApply) replaceDB(db *gorm.DB) userApply {
	u.userApplyDo.ReplaceDB(db)
	return u
}

type userApplyDo struct{ gen.DO }

type IUserApplyDo interface {
	gen.SubQuery
	Debug() IUserApplyDo
	WithContext(ctx context.Context) IUserApplyDo
	WithResult(fc func(tx gen.Dao)) gen.ResultInfo
	ReplaceDB(db *gorm.DB)
	ReadDB() IUserApplyDo
	WriteDB() IUserApplyDo
	As(alias string) gen.Dao
	Session(config *gorm.Session) IUserApplyDo
	Columns(cols ...field.Expr) gen.Columns
	Clauses(conds ...clause.Expression) IUserApplyDo
	Not(conds ...gen.Condition) IUserApplyDo
	Or(conds ...gen.Condition) IUserApplyDo
	Select(conds ...field.Expr) IUserApplyDo
	Where(conds ...gen.Condition) IUserApplyDo
	Order(conds ...field.Expr) IUserApplyDo
	Distinct(cols ...field.Expr) IUserApplyDo
	Omit(cols ...field.Expr) IUserApplyDo
	Join(table schema.Tabler, on ...field.Expr) IUserApplyDo
	LeftJoin(table schema.Tabler, on ...field.Expr) IUserApplyDo
	RightJoin(table schema.Tabler, on ...field.Expr) IUserApplyDo
	Group(cols ...field.Expr) IUserApplyDo
	Having(conds ...gen.Condition) IUserApplyDo
	Limit(limit int) IUserApplyDo
	Offset(offset int) IUserApplyDo
	Count() (count int64, err error)
	Scopes(funcs ...func(gen.Dao) gen.Dao) IUserApplyDo
	Unscoped() IUserApplyDo
	Create(values ...*model.UserApply) error
	CreateInBatches(values []*model.UserApply, batchSize int) error
	Save(values ...*model.UserApply) error
	First() (*model.UserApply, error)
	Take() (*model.UserApply, error)
	Last() (*model.UserApply, error)
	Find() ([]*model.UserApply, error)
	FindInBatch(batchSize int, fc func(tx gen.Dao, batch int) error) (results []*model.UserApply, err error)
	FindInBatches(result *[]*model.UserApply, batchSize int, fc func(tx gen.Dao, batch int) error) error
	Pluck(column field.Expr, dest interface{}) error
	Delete(...*model.UserApply) (info gen.ResultInfo, err error)
	Update(column field.Expr, value interface{}) (info gen.ResultInfo, err error)
	UpdateSimple(columns ...field.AssignExpr) (info gen.ResultInfo, err error)
	Updates(value interface{}) (info gen.ResultInfo, err error)
	UpdateColumn(column field.Expr, value interface{}) (info gen.ResultInfo, err error)
	UpdateColumnSimple(columns ...field.AssignExpr) (info gen.ResultInfo, err error)
	UpdateColumns(value interface{}) (info gen.ResultInfo, err error)
	UpdateFrom(q gen.SubQuery) gen.Dao
	Attrs(attrs ...field.AssignExpr) IUserApplyDo
	Assign(attrs ...field.AssignExpr) IUserApplyDo
	Joins(fields ...field.RelationField) IUserApplyDo
	Preload(fields ...field.RelationField) IUserApplyDo
	FirstOrInit() (*model.UserApply, error)
	FirstOrCreate() (*model.UserApply, error)
	FindByPage(offset int, limit int) (result []*model.UserApply, count int64, err error)
	ScanByPage(result interface{}, offset int, limit int) (count int64, err error)
	Scan(result interface{}) (err error)
	Returning(value interface{}, columns ...string) IUserApplyDo
	UnderlyingDB() *gorm.DB
	schema.Tabler
}

func (u userApplyDo) Debug() IUserApplyDo {
	return u.withDO(u.DO.Debug())
}

func (u userApplyDo) WithContext(ctx context.Context) IUserApplyDo {
	return u.withDO(u.DO.WithContext(ctx))
}

func (u userApplyDo) ReadDB() IUserApplyDo {
	return u.Clauses(dbresolver.Read)
}

func (u userApplyDo) WriteDB() IUserApplyDo {
	return u.Clauses(dbresolver.Write)
}

func (u userApplyDo) Session(config *gorm.Session) IUserApplyDo {
	return u.withDO(u.DO.Session(config))
}

func (u userApplyDo) Clauses(conds ...clause.Expression) IUserApplyDo {
	return u.withDO(u.DO.Clauses(conds...))
}

func (u userApplyDo) Returning(value interface{}, columns ...string) IUserApplyDo {
	return u.withDO(u.DO.Returning(value, columns...))
}

func (u userApplyDo) Not(conds ...gen.Condition) IUserApplyDo {
	return u.withDO(u.DO.Not(conds...))
}

func (u userApplyDo) Or(conds ...gen.Condition) IUserApplyDo {
	return u.withDO(u.DO.Or(conds...))
}

func (u userApplyDo) Select(conds ...field.Expr) IUserApplyDo {
	return u.withDO(u.DO.Select(conds...))
}

func (u userApplyDo) Where(conds ...gen.Condition) IUserApplyDo {
	return u.withDO(u.DO.Where(conds...))
}

func (u userApplyDo) Order(conds ...field.Expr) IUserApplyDo {
	return u.withDO(u.DO.Order(conds...))
}

func (u userApplyDo) Distinct(cols ...field.Expr) IUserApplyDo {
	return u.withDO(u.DO.Distinct(cols...))
}

func (u userApplyDo) Omit(cols ...field.Expr) IUserApplyDo {
	return u.withDO(u.DO.Omit(cols...))
}

func (u userApplyDo) Join(table schema.Tabler, on ...field.Expr) IUserApplyDo {
	return u.withDO(u.DO.Join(table, on...))
}

func (u userApplyDo) LeftJoin(table schema.Tabler, on ...field.Expr) IUserApplyDo {
	return u.withDO(u.DO.LeftJoin(table, on...))
}

func (u userApplyDo) RightJoin(table schema.Tabler, on ...field.Expr) IUserApplyDo {
	return u.withDO(u.DO.RightJoin(table, on...))
}

func (u userApplyDo) Group(cols ...field.Expr) IUserApplyDo {
	return u.withDO(u.DO.Group(cols...))
}

func (u userApplyDo) Having(conds ...gen.Condition) IUserApplyDo {
	return u.withDO(u.DO.Having(conds...))
}

func (u userApplyDo) Limit(limit int) IUserApplyDo {
	return u.withDO(u.DO.Limit(limit))
}

func (u userApplyDo) Offset(offset int) IUserApplyDo {
	return u.withDO(u.DO.Offset(offset))
}

func (u userApplyDo) Scopes(funcs ...func(gen.Dao) gen.Dao) IUserApplyDo {
	return u.withDO(u.DO.Scopes(funcs...))
}

func (u userApplyDo) Unscoped() IUserApplyDo {
	return u.withDO(u.DO.Unscoped())
}

func (u userApplyDo) Create(values ...*model.UserApply) error {
	if len(values) == 0 {
		return nil
	}
	return u.DO.Create(values)
}

func (u userApplyDo) CreateInBatches(values []*model.UserApply, batchSize int) error {
	return u.DO.CreateInBatches(values, batchSize)
}

// Save : !!! underlying implementation is different with GORM
// The method is equivalent to executing the statement: db.Clauses(clause.OnConflict{UpdateAll: true}).Create(values)
func (u userApplyDo) Save(values ...*model.UserApply) error {
	if len(values) == 0 {
		return nil
	}
	return u.DO.Save(values)
}

func (u userApplyDo) First() (*model.UserApply, error) {
	if result, err := u.DO.First(); err != nil {
		return nil, err
	} else {
		return result.(*model.UserApply), nil
	}
}

func (u userApplyDo) Take() (*model.UserApply, error) {
	if result, err := u.DO.Take(); err != nil {
		return nil, err
	} else {
		return result.(*model.UserApply), nil
	}
}

func (u userApplyDo) Last() (*model.UserApply, error) {
	if result, err := u.DO.Last(); err != nil {
		return nil, err
	} else {
		return result.(*model.UserApply), nil
	}
}

func (u userApplyDo) Find() ([]*model.UserApply, error) {
	result, err := u.DO.Find()
	return result.([]*model.UserApply), err
}

func (u userApplyDo) FindInBatch(batchSize int, fc func(tx gen.Dao, batch int) error) (results []*model.UserApply, err error) {
	buf := make([]*model.UserApply, 0, batchSize)
	err = u.DO.FindInBatches(&buf, batchSize, func(tx gen.Dao, batch int) error {
		defer func() { results = append(results, buf...) }()
		return fc(tx, batch)
	})
	return results, err
}

func (u userApplyDo) FindInBatches(result *[]*model.UserApply, batchSize int, fc func(tx gen.Dao, batch int) error) error {
	return u.DO.FindInBatches(result, batchSize, fc)
}

func (u userApplyDo) Attrs(attrs ...field.AssignExpr) IUserApplyDo {
	return u.withDO(u.DO.Attrs(attrs...))
}

func (u userApplyDo) Assign(attrs ...field.AssignExpr) IUserApplyDo {
	return u.withDO(u.DO.Assign(attrs...))
}

func (u userApplyDo) Joins(fields ...field.RelationField) IUserApplyDo {
	for _, _f := range fields {
		u = *u.withDO(u.DO.Joins(_f))
	}
	return &u
}

func (u userApplyDo) Preload(fields ...field.RelationField) IUserApplyDo {
	for _, _f := range fields {
		u = *u.withDO(u.DO.Preload(_f))
	}
	return &u
}

func (u userApplyDo) FirstOrInit() (*model.UserApply, error) {
	if result, err := u.DO.FirstOrInit(); err != nil {
		return nil, err
	} else {
		return result.(*model.UserApply), nil
	}
}

func (u userApplyDo) FirstOrCreate() (*model.UserApply, error) {
	if result, err := u.DO.FirstOrCreate(); err != nil {
		return nil, err
	} else {
		return result.(*model.UserApply), nil
	}
}

func (u userApplyDo) FindByPage(offset int, limit int) (result []*model.UserApply, count int64, err error) {
	result, err = u.Offset(offset).Limit(limit).Find()
	if err != nil {
		return
	}

	if size := len(result); 0 < limit && 0 < size && size < limit {
		count = int64(size + offset)
		return
	}

	count, err = u.Offset(-1).Limit(-1).Count()
	return
}

func (u userApplyDo) ScanByPage(result interface{}, offset int, limit int) (count int64, err error) {
	count, err = u.Count()
	if err != nil {
		return
	}

	err = u.Offset(offset).Limit(limit).Scan(result)
	return
}

func (u userApplyDo) Scan(result interface{}) (err error) {
	return u.DO.Scan(result)
}

func (u userApplyDo) Delete(models ...*model.UserApply) (result gen.ResultInfo, err error) {
	return u.DO.Delete(models)
}

func (u *userApplyDo) withDO(do gen.Dao) *userApplyDo {
	u.DO = *do.(*gen.DO)
	return u
}


================================================
FILE: dal/query/user_friend.gen.go
================================================
// Code generated by gorm.io/gen. DO NOT EDIT.
// Code generated by gorm.io/gen. DO NOT EDIT.
// Code generated by gorm.io/gen. DO NOT EDIT.

package query

import (
	"context"

	"gorm.io/gorm"
	"gorm.io/gorm/clause"
	"gorm.io/gorm/schema"

	"gorm.io/gen"
	"gorm.io/gen/field"

	"gorm.io/plugin/dbresolver"

	"DiTing-Go/dal/model"
)

func newUserFriend(db *gorm.DB, opts ...gen.DOOption) userFriend {
	_userFriend := userFriend{}

	_userFriend.userFriendDo.UseDB(db, opts...)
	_userFriend.userFriendDo.UseModel(&model.UserFriend{})

	tableName := _userFriend.userFriendDo.TableName()
	_userFriend.ALL = field.NewAsterisk(tableName)
	_userFriend.ID = field.NewInt64(tableName, "id")
	_userFriend.UID = field.NewInt64(tableName, "uid")
	_userFriend.FriendUID = field.NewInt64(tableName, "friend_uid")
	_userFriend.DeleteStatus = field.NewInt32(tableName, "delete_status")
	_userFriend.CreateTime = field.NewTime(tableName, "create_time")
	_userFriend.UpdateTime = field.NewTime(tableName, "update_time")

	_userFriend.fillFieldMap()

	return _userFriend
}

// userFriend 用户联系人表
type userFriend struct {
	userFriendDo userFriendDo

	ALL          field.Asterisk
	ID           field.Int64 // id
	UID          field.Int64 // uid
	FriendUID    field.Int64 // 好友uid
	DeleteStatus field.Int32 // 逻辑删除(0-正常,1-删除)
	CreateTime   field.Time  // 创建时间
	UpdateTime   field.Time  // 修改时间

	fieldMap map[string]field.Expr
}

func (u userFriend) Table(newTableName string) *userFriend {
	u.userFriendDo.UseTable(newTableName)
	return u.updateTableName(newTableName)
}

func (u userFriend) As(alias string) *userFriend {
	u.userFriendDo.DO = *(u.userFriendDo.As(alias).(*gen.DO))
	return u.updateTableName(alias)
}

func (u *userFriend) updateTableName(table string) *userFriend {
	u.ALL = field.NewAsterisk(table)
	u.ID = field.NewInt64(table, "id")
	u.UID = field.NewInt64(table, "uid")
	u.FriendUID = field.NewInt64(table, "friend_uid")
	u.DeleteStatus = field.NewInt32(table, "delete_status")
	u.CreateTime = field.NewTime(table, "create_time")
	u.UpdateTime = field.NewTime(table, "update_time")

	u.fillFieldMap()

	return u
}

func (u *userFriend) WithContext(ctx context.Context) IUserFriendDo {
	return u.userFriendDo.WithContext(ctx)
}

func (u userFriend) TableName() string { return u.userFriendDo.TableName() }

func (u userFriend) Alias() string { return u.userFriendDo.Alias() }

func (u userFriend) Columns(cols ...field.Expr) gen.Columns { return u.userFriendDo.Columns(cols...) }

func (u *userFriend) GetFieldByName(fieldName string) (field.OrderExpr, bool) {
	_f, ok := u.fieldMap[fieldName]
	if !ok || _f == nil {
		return nil, false
	}
	_oe, ok := _f.(field.OrderExpr)
	return _oe, ok
}

func (u *userFriend) fillFieldMap() {
	u.fieldMap = make(map[string]field.Expr, 6)
	u.fieldMap["id"] = u.ID
	u.fieldMap["uid"] = u.UID
	u.fieldMap["friend_uid"] = u.FriendUID
	u.fieldMap["delete_status"] = u.DeleteStatus
	u.fieldMap["create_time"] = u.CreateTime
	u.fieldMap["update_time"] = u.UpdateTime
}

func (u userFriend) clone(db *gorm.DB) userFriend {
	u.userFriendDo.ReplaceConnPool(db.Statement.ConnPool)
	return u
}

func (u userFriend) replaceDB(db *gorm.DB) userFriend {
	u.userFriendDo.ReplaceDB(db)
	return u
}

type userFriendDo struct{ gen.DO }

type IUserFriendDo interface {
	gen.SubQuery
	Debug() IUserFriendDo
	WithContext(ctx context.Context) IUserFriendDo
	WithResult(fc func(tx gen.Dao)) gen.ResultInfo
	ReplaceDB(db *gorm.DB)
	ReadDB() IUserFriendDo
	WriteDB() IUserFriendDo
	As(alias string) gen.Dao
	Session(config *gorm.Session) IUserFriendDo
	Columns(cols ...field.Expr) gen.Columns
	Clauses(conds ...clause.Expression) IUserFriendDo
	Not(conds ...gen.Condition) IUserFriendDo
	Or(conds ...gen.Condition) IUserFriendDo
	Select(conds ...field.Expr) IUserFriendDo
	Where(conds ...gen.Condition) IUserFriendDo
	Order(conds ...field.Expr) IUserFriendDo
	Distinct(cols ...field.Expr) IUserFriendDo
	Omit(cols ...field.Expr) IUserFriendDo
	Join(table schema.Tabler, on ...field.Expr) IUserFriendDo
	LeftJoin(table schema.Tabler, on ...field.Expr) IUserFriendDo
	RightJoin(table schema.Tabler, on ...field.Expr) IUserFriendDo
	Group(cols ...field.Expr) IUserFriendDo
	Having(conds ...gen.Condition) IUserFriendDo
	Limit(limit int) IUserFriendDo
	Offset(offset int) IUserFriendDo
	Count() (count int64, err error)
	Scopes(funcs ...func(gen.Dao) gen.Dao) IUserFriendDo
	Unscoped() IUserFriendDo
	Create(values ...*model.UserFriend) error
	CreateInBatches(values []*model.UserFriend, batchSize int) error
	Save(values ...*model.UserFriend) error
	First() (*model.UserFriend, error)
	Take() (*model.UserFriend, error)
	Last() (*model.UserFriend, error)
	Find() ([]*model.UserFriend, error)
	FindInBatch(batchSize int, fc func(tx gen.Dao, batch int) error) (results []*model.UserFriend, err error)
	FindInBatches(result *[]*model.UserFriend, batchSize int, fc func(tx gen.Dao, batch int) error) error
	Pluck(column field.Expr, dest interface{}) error
	Delete(...*model.UserFriend) (info gen.ResultInfo, err error)
	Update(column field.Expr, value interface{}) (info gen.ResultInfo, err error)
	UpdateSimple(columns ...field.AssignExpr) (info gen.ResultInfo, err error)
	Updates(value interface{}) (info gen.ResultInfo, err error)
	UpdateColumn(column field.Expr, value interface{}) (info gen.ResultInfo, err error)
	UpdateColumnSimple(columns ...field.AssignExpr) (info gen.ResultInfo, err error)
	UpdateColumns(value interface{}) (info gen.ResultInfo, err error)
	UpdateFrom(q gen.SubQuery) gen.Dao
	Attrs(attrs ...field.AssignExpr) IUserFriendDo
	Assign(attrs ...field.AssignExpr) IUserFriendDo
	Joins(fields ...field.RelationField) IUserFriendDo
	Preload(fields ...field.RelationField) IUserFriendDo
	FirstOrInit() (*model.UserFriend, error)
	FirstOrCreate() (*model.UserFriend, error)
	FindByPage(offset int, limit int) (result []*model.UserFriend, count int64, err error)
	ScanByPage(result interface{}, offset int, limit int) (count int64, err error)
	Scan(result interface{}) (err error)
	Returning(value interface{}, columns ...string) IUserFriendDo
	UnderlyingDB() *gorm.DB
	schema.Tabler
}

func (u userFriendDo) Debug() IUserFriendDo {
	return u.withDO(u.DO.Debug())
}

func (u userFriendDo) WithContext(ctx context.Context) IUserFriendDo {
	return u.withDO(u.DO.WithContext(ctx))
}

func (u userFriendDo) ReadDB() IUserFriendDo {
	return u.Clauses(dbresolver.Read)
}

func (u userFriendDo) WriteDB() IUserFriendDo {
	return u.Clauses(dbresolver.Write)
}

func (u userFriendDo) Session(config *gorm.Session) IUserFriendDo {
	return u.withDO(u.DO.Session(config))
}

func (u userFriendDo) Clauses(conds ...clause.Expression) IUserFriendDo {
	return u.withDO(u.DO.Clauses(conds...))
}

func (u userFriendDo) Returning(value interface{}, columns ...string) IUserFriendDo {
	return u.withDO(u.DO.Returning(value, columns...))
}

func (u userFriendDo) Not(conds ...gen.Condition) IUserFriendDo {
	return u.withDO(u.DO.Not(conds...))
}

func (u userFriendDo) Or(conds ...gen.Condition) IUserFriendDo {
	return u.withDO(u.DO.Or(conds...))
}

func (u userFriendDo) Select(conds ...field.Expr) IUserFriendDo {
	return u.withDO(u.DO.Select(conds...))
}

func (u userFriendDo) Where(conds ...gen.Condition) IUserFriendDo {
	return u.withDO(u.DO.Where(conds...))
}

func (u userFriendDo) Order(conds ...field.Expr) IUserFriendDo {
	return u.withDO(u.DO.Order(conds...))
}

func (u userFriendDo) Distinct(cols ...field.Expr) IUserFriendDo {
	return u.withDO(u.DO.Distinct(cols...))
}

func (u userFriendDo) Omit(cols ...field.Expr) IUserFriendDo {
	return u.withDO(u.DO.Omit(cols...))
}

func (u userFriendDo) Join(table schema.Tabler, on ...field.Expr) IUserFriendDo {
	return u.withDO(u.DO.Join(table, on...))
}

func (u userFriendDo) LeftJoin(table schema.Tabler, on ...field.Expr) IUserFriendDo {
	return u.withDO(u.DO.LeftJoin(table, on...))
}

func (u userFriendDo) RightJoin(table schema.Tabler, on ...field.Expr) IUserFriendDo {
	return u.withDO(u.DO.RightJoin(table, on...))
}

func (u userFriendDo) Group(cols ...field.Expr) IUserFriendDo {
	return u.withDO(u.DO.Group(cols...))
}

func (u userFriendDo) Having(conds ...gen.Condition) IUserFriendDo {
	return u.withDO(u.DO.Having(conds...))
}

func (u userFriendDo) Limit(limit int) IUserFriendDo {
	return u.withDO(u.DO.Limit(limit))
}

func (u userFriendDo) Offset(offset int) IUserFriendDo {
	return u.withDO(u.DO.Offset(offset))
}

func (u userFriendDo) Scopes(funcs ...func(gen.Dao) gen.Dao) IUserFriendDo {
	return u.withDO(u.DO.Scopes(funcs...))
}

func (u userFriendDo) Unscoped() IUserFriendDo {
	return u.withDO(u.DO.Unscoped())
}

func (u userFriendDo) Create(values ...*model.UserFriend) error {
	if len(values) == 0 {
		return nil
	}
	return u.DO.Create(values)
}

func (u userFriendDo) CreateInBatches(values []*model.UserFriend, batchSize int) error {
	return u.DO.CreateInBatches(values, batchSize)
}

// Save : !!! underlying implementation is different with GORM
// The method is equivalent to executing the statement: db.Clauses(clause.OnConflict{UpdateAll: true}).Create(values)
func (u userFriendDo) Save(values ...*model.UserFriend) error {
	if len(values) == 0 {
		return nil
	}
	return u.DO.Save(values)
}

func (u userFriendDo) First() (*model.UserFriend, error) {
	if result, err := u.DO.First(); err != nil {
		return nil, err
	} else {
		return result.(*model.UserFriend), nil
	}
}

func (u userFriendDo) Take() (*model.UserFriend, error) {
	if result, err := u.DO.Take(); err != nil {
		return nil, err
	} else {
		return result.(*model.UserFriend), nil
	}
}

func (u userFriendDo) Last() (*model.UserFriend, error) {
	if result, err := u.DO.Last(); err != nil {
		return nil, err
	} else {
		return result.(*model.UserFriend), nil
	}
}

func (u userFriendDo) Find() ([]*model.UserFriend, error) {
	result, err := u.DO.Find()
	return result.([]*model.UserFriend), err
}

func (u userFriendDo) FindInBatch(batchSize int, fc func(tx gen.Dao, batch int) error) (results []*model.UserFriend, err error) {
	buf := make([]*model.UserFriend, 0, batchSize)
	err = u.DO.FindInBatches(&buf, batchSize, func(tx gen.Dao, batch int) error {
		defer func() { results = append(results, buf...) }()
		return fc(tx, batch)
	})
	return results, err
}

func (u userFriendDo) FindInBatches(result *[]*model.UserFriend, batchSize int, fc func(tx gen.Dao, batch int) error) error {
	return u.DO.FindInBatches(result, batchSize, fc)
}

func (u userFriendDo) Attrs(attrs ...field.AssignExpr) IUserFriendDo {
	return u.withDO(u.DO.Attrs(attrs...))
}

func (u userFriendDo) Assign(attrs ...field.AssignExpr) IUserFriendDo {
	return u.withDO(u.DO.Assign(attrs...))
}

func (u userFriendDo) Joins(fields ...field.RelationField) IUserFriendDo {
	for _, _f := range fields {
		u = *u.withDO(u.DO.Joins(_f))
	}
	return &u
}

func (u userFriendDo) Preload(fields ...field.RelationField) IUserFriendDo {
	for _, _f := range fields {
		u = *u.withDO(u.DO.Preload(_f))
	}
	return &u
}

func (u userFriendDo) FirstOrInit() (*model.UserFriend, error) {
	if result, err := u.DO.FirstOrInit(); err != nil {
		return nil, err
	} else {
		return result.(*model.UserFriend), nil
	}
}

func (u userFriendDo) FirstOrCreate() (*model.UserFriend, error) {
	if result, err := u.DO.FirstOrCreate(); err != nil {
		return nil, err
	} else {
		return result.(*model.UserFriend), nil
	}
}

func (u userFriendDo) FindByPage(offset int, limit int) (result []*model.UserFriend, count int64, err error) {
	result, err = u.Offset(offset).Limit(limit).Find()
	if err != nil {
		return
	}

	if size := len(result); 0 < limit && 0 < size && size < limit {
		count = int64(size + offset)
		return
	}

	count, err = u.Offset(-1).Limit(-1).Count()
	return
}

func (u userFriendDo) ScanByPage(result interface{}, offset int, limit int) (count int64, err error) {
	count, err = u.Count()
	if err != nil {
		return
	}

	err = u.Offset(offset).Limit(limit).Scan(result)
	return
}

func (u userFriendDo) Scan(result interface{}) (err error) {
	return u.DO.Scan(result)
}

func (u userFriendDo) Delete(models ...*model.UserFriend) (result gen.ResultInfo, err error) {
	return u.DO.Delete(models)
}

func (u *userFriendDo) withDO(do gen.Dao) *userFriendDo {
	u.DO = *do.(*gen.DO)
	return u
}


================================================
FILE: docs/docs.go
================================================
// Code generated by swaggo/swag. DO NOT EDIT.

package docs

import "github.com/swaggo/swag"

const docTemplate = `{
    "schemes": {{ marshal .Schemes }},
    "swagger": "2.0",
    "info": {
        "description": "{{escape .Description}}",
        "title": "{{.Title}}",
        "contact": {},
        "version": "{{.Version}}"
    },
    "host": "{{.Host}}",
    "basePath": "{{.BasePath}}",
    "paths": {
        "/api/contact/add": {
            "post": {
                "produces": [
                    "application/json"
                ],
                "summary": "添加好友",
                "parameters": [
                    {
                        "description": "好友uid",
                        "name": "uid",
                        "in": "body",
                        "required": true,
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "description": "验证消息",
                        "name": "msg",
                        "in": "body",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "成功",
                        "schema": {
                            "$ref": "#/definitions/resp.ResponseData"
                        }
                    },
                    "500": {
                        "description": "内部错误",
                        "schema": {
                            "$ref": "#/definitions/resp.ResponseData"
                        }
                    }
                }
            }
        },
        "/api/contact/delete": {
            "put": {
                "produces": [
                    "application/json"
                ],
                "summary": "同意好友申请",
                "parameters": [
                    {
                        "description": "好友uid",
                        "name": "uid",
                        "in": "body",
                        "required": true,
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "成功",
                        "schema": {
                            "$ref": "#/definitions/resp.ResponseData"
                        }
                    },
                    "500": {
                        "description": "内部错误",
                        "schema": {
                            "$ref": "#/definitions/resp.ResponseData"
                        }
                    }
                }
            },
            "delete": {
                "produces": [
                    "application/json"
                ],
                "summary": "删除好友",
                "parameters": [
                    {
                        "description": "好友uid",
                        "name": "uid",
                        "in": "body",
                        "required": true,
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "成功",
                        "schema": {
                            "$ref": "#/definitions/resp.ResponseData"
                        }
                    },
                    "500": {
                        "description": "内部错误",
                        "schema": {
                            "$ref": "#/definitions/resp.ResponseData"
                        }
                    }
                }
            }
        },
        "/api/contact/getApplyList": {
            "get": {
                "security": [
                    {
                        "ApiKeyAuth": []
                    }
                ],
                "produces": [
                    "application/json"
                ],
                "summary": "获取用户好友申请列表",
                "parameters": [
                    {
                        "type": "integer",
                        "description": "last_id",
                        "name": "last_id",
                        "in": "query",
                        "required": true
                    },
                    {
                        "type": "integer",
                        "description": "limit",
                        "name": "limit",
                        "in": "query",
                        "required": true
                    }
                ],
                "responses": {
                    "200": {
                        "description": "成功",
                        "schema": {
                            "$ref": "#/definitions/resp.ResponseData"
                        }
                    },
                    "500": {
                        "description": "内部错误",
                        "schema": {
                            "$ref": "#/definitions/resp.ResponseData"
                        }
                    }
                }
            }
        },
        "/api/public/login": {
            "post": {
                "produces": [
                    "application/json"
                ],
                "summary": "用户登录",
                "parameters": [
                    {
                        "description": "用户名",
                        "name": "name",
                        "in": "body",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "description": "密码",
                        "name": "password",
                        "in": "body",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "成功",
                        "schema": {
                            "$ref": "#/definitions/resp.ResponseData"
                        }
                    },
                    "500": {
                        "description": "内部错误",
                        "schema": {
                            "$ref": "#/definitions/resp.ResponseData"
                        }
                    }
                }
            }
        },
        "/api/public/register": {
            "post": {
                "produces": [
                    "application/json"
                ],
                "summary": "用户注册",
                "parameters": [
                    {
                        "description": "用户名",
                        "name": "name",
                        "in": "body",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "description": "密码",
                        "name": "password",
                        "in": "body",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "成功",
                        "schema": {
                            "$ref": "#/definitions/resp.ResponseData"
                        }
                    },
                    "500": {
                        "description": "内部错误",
                        "schema": {
                            "$ref": "#/definitions/resp.ResponseData"
                        }
                    }
                }
            }
        }
    },
    "definitions": {
        "resp.ResponseData": {
            "type": "object",
            "properties": {
                "code": {
                    "description": "状态码",
                    "type": "integer"
                },
                "data": {
                    "description": "响应数据"
                },
                "message": {
                    "description": "响应消息",
                    "type": "string"
                }
            }
        }
    },
    "securityDefinitions": {
        "ApiKeyAuth": {
            "type": "apiKey",
            "name": "Authorization",
            "in": "header"
        }
    }
}`

// SwaggerInfo holds exported Swagger Info so clients can modify it
var SwaggerInfo = &swag.Spec{
	Version:          "",
	Host:             "",
	BasePath:         "",
	Schemes:          []string{},
	Title:            "",
	Description:      "",
	InfoInstanceName: "swagger",
	SwaggerTemplate:  docTemplate,
	LeftDelim:        "{{",
	RightDelim:       "}}",
}

func init() {
	swag.Register(SwaggerInfo.InstanceName(), SwaggerInfo)
}


================================================
FILE: docs/swagger.json
================================================
{
    "swagger": "2.0",
    "info": {
        "contact": {}
    },
    "paths": {
        "/api/contact/add": {
            "post": {
                "produces": [
                    "application/json"
                ],
                "summary": "添加好友",
                "parameters": [
                    {
                        "description": "好友uid",
                        "name": "uid",
                        "in": "body",
                        "required": true,
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "description": "验证消息",
                        "name": "msg",
                        "in": "body",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "成功",
                        "schema": {
                            "$ref": "#/definitions/resp.ResponseData"
                        }
                    },
                    "500": {
                        "description": "内部错误",
                        "schema": {
                            "$ref": "#/definitions/resp.ResponseData"
                        }
                    }
                }
            }
        },
        "/api/contact/delete": {
            "put": {
                "produces": [
                    "application/json"
                ],
                "summary": "同意好友申请",
                "parameters": [
                    {
                        "description": "好友uid",
                        "name": "uid",
                        "in": "body",
                        "required": true,
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "成功",
                        "schema": {
                            "$ref": "#/definitions/resp.ResponseData"
                        }
                    },
                    "500": {
                        "description": "内部错误",
                        "schema": {
                            "$ref": "#/definitions/resp.ResponseData"
                        }
                    }
                }
            },
            "delete": {
                "produces": [
                    "application/json"
                ],
                "summary": "删除好友",
                "parameters": [
                    {
                        "description": "好友uid",
                        "name": "uid",
                        "in": "body",
                        "required": true,
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "成功",
                        "schema": {
                            "$ref": "#/definitions/resp.ResponseData"
                        }
                    },
                    "500": {
                        "description": "内部错误",
                        "schema": {
                            "$ref": "#/definitions/resp.ResponseData"
                        }
                    }
                }
            }
        },
        "/api/contact/getApplyList": {
            "get": {
                "security": [
                    {
                        "ApiKeyAuth": []
                    }
                ],
                "produces": [
                    "application/json"
                ],
                "summary": "获取用户好友申请列表",
                "parameters": [
                    {
                        "type": "integer",
                        "description": "last_id",
                        "name": "last_id",
                        "in": "query",
                        "required": true
                    },
                    {
                        "type": "integer",
                        "description": "limit",
                        "name": "limit",
                        "in": "query",
                        "required": true
                    }
                ],
                "responses": {
                    "200": {
                        "description": "成功",
                        "schema": {
                            "$ref": "#/definitions/resp.ResponseData"
                        }
                    },
                    "500": {
                        "description": "内部错误",
                        "schema": {
                            "$ref": "#/definitions/resp.ResponseData"
                        }
                    }
                }
            }
        },
        "/api/public/login": {
            "post": {
                "produces": [
                    "application/json"
                ],
                "summary": "用户登录",
                "parameters": [
                    {
                        "description": "用户名",
                        "name": "name",
                        "in": "body",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "description": "密码",
                        "name": "password",
                        "in": "body",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "成功",
                        "schema": {
                            "$ref": "#/definitions/resp.ResponseData"
                        }
                    },
                    "500": {
                        "description": "内部错误",
                        "schema": {
                            "$ref": "#/definitions/resp.ResponseData"
                        }
                    }
                }
            }
        },
        "/api/public/register": {
            "post": {
                "produces": [
                    "application/json"
                ],
                "summary": "用户注册",
                "parameters": [
                    {
                        "description": "用户名",
                        "name": "name",
                        "in": "body",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "description": "密码",
                        "name": "password",
                        "in": "body",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "成功",
                        "schema": {
                            "$ref": "#/definitions/resp.ResponseData"
                        }
                    },
                    "500": {
                        "description": "内部错误",
                        "schema": {
                            "$ref": "#/definitions/resp.ResponseData"
                        }
                    }
                }
            }
        }
    },
    "definitions": {
        "resp.ResponseData": {
            "type": "object",
            "properties": {
                "code": {
                    "description": "状态码",
                    "type": "integer"
                },
                "data": {
                    "description": "响应数据"
                },
                "message": {
                    "description": "响应消息",
                    "type": "string"
                }
            }
        }
    },
    "securityDefinitions": {
        "ApiKeyAuth": {
            "type": "apiKey",
            "name": "Authorization",
            "in": "header"
        }
    }
}

================================================
FILE: domain/dto/contact_dto.go
================================================
package dto

type ContactDto struct {
	// 会话ID
	ID int64 `json:"id"`
	// 房间ID
	RoomID int64 `json:"roomId"`
	// 头像
	Avatar string `json:"avatar"`
	// 会话名称
	Name string `json:"name"`
	// 最后一条消息内容
	LastMsg string `json:"lastMsg"`
	// 最后一条消息时间 时间戳格式
	LastTime int64 `json:"lastTime"`
	// 未读消息数
	UnreadCount int32 `json:"unreadCount"`
	// 会话类型
	Type int `json:"type"`
}


================================================
FILE: domain/dto/delete_friend_dto.go
================================================
package dto

type DeleteFriendDto struct {
	Uid       int64 `json:"uid"`
	FriendUid int64 `json:"friend_uid"`
}


================================================
FILE: domain/dto/group_dto.go
================================================
package dto

import "time"

type GetGroupMemberDto struct {
	// 用户ID
	UID int64 `json:"uid" gorm:"column:id"`
	// 用户名
	Name string `json:"name"`
	// 头像
	Avatar string `json:"avatar"`
	// 用户状态
	ActiveStatus int32 `json:"activeStatus"`
	// 最后活跃时间
	LastOptTime time.Time `json:"lastOptTime"`
}


================================================
FILE: domain/dto/msg_dto.go
================================================
package dto

type MessageBaseDto struct {
	// 下载地址
	Url string `json:"url"`
	// 文件大小
	Size int64 `json:"size"`
	// 文件名
	Name string `json:"name"`
}

type ImgMessageDto struct {
	MessageBaseDto MessageBaseDto `json:"message_base_dto"`
	// 图片高度
	Height int `json:"height"`
	// 图片宽度
	Width int `json:"width"`
}


================================================
FILE: domain/enum/event_bus.go
================================================
package enum

const (
	FriendApplyEvent = "main:FriendApplyEvent"
	FriendNewEvent   = "main:FriendNewEvent"
	NewMessageEvent  = "main:NewMessageEvent"
)


================================================
FILE: domain/enum/login.go
================================================
package enum

const (
	LoginByPassword     = 1 // 用户名密码登录
	LoginByPhoneCaptcha = 2 // 手机号验证码登录
)


================================================
FILE: domain/enum/message.go
================================================
package enum

const (
	TextMessage = 1
)

const (
	TextMessageType = 1
	ImgMessageType  = 3
)


================================================
FILE: domain/enum/redis.go
================================================
package enum

import "time"

const (
	Project    = "diting:"
	User       = Project + "User"
	UserFriend = Project + "userFriend:"
	UserApply  = Project + "userApply:"
	RoomFriend = Project + "roomFriend:"
	Contact    = Project + "contact:"
	Room       = Project + "room:"
)
const (
	// 房间缓存
	RoomCacheByID = Room + "%d"

	// 好友房间缓存
	RoomFriendCacheByRoomID          = RoomFriend + "%d"
	RoomFriendCacheByUidAndFriendUid = RoomFriend + "%d_%d"

	// phoneUid映射
	PhoneUidMap      = User + "PhoneUid:" + "%s"
	UserCacheByID    = User + "%d"
	UserCacheByName  = User + "%s"
	UserCacheByPhone = User + "Phone:" + "%s"
	UserCaptcha      = User + "Captcha:" + "%s"

	// 用户好友缓存
	UserFriendCacheByUidAndFriendUid = UserFriend + "%d_%d"

	// 好友申请缓存
	UserApplyCacheByUidAndFriendUid = UserApply + "%d_%d"

	// 会话缓存
	ContactCacheById = Contact + "%d"
)

const (
	DefaultCacheTime = 7 * 24 * time.Hour
	NotExpireTime    = 10 * 365 * 24 * time.Hour
)


================================================
FILE: domain/enum/redsync.go
================================================
package enum

const (
	Lock              = "lock:"
	UserLock          = Lock + "diting-user:"
	UserAndFriendLock = UserLock + "%d_%d"
)


================================================
FILE: domain/enum/rocketmq.go
================================================
package enum

const (
	UserLoginTopic    = "diting-login"
	NewFriendTopic    = "diting-new-friend"
	NewMessageTopic   = "diting-new-message"
	DeleteFriendTopic = "diting-delete-friend"
	FriendApplyTopic  = "diting-friend-apply"
)


================================================
FILE: domain/enum/room.go
================================================
package enum

const (
	// 房间状态
	HOT    = 1
	NORMAL = 0
	// 房间类型
	GROUP    = 1
	PERSONAL = 2
)


================================================
FILE: domain/enum/user.go
================================================
package enum

const (
	UserStatusNormal = 1
	UserStatusCancel = 2
)


================================================
FILE: domain/model/message.go
================================================
package model

import (
	"DiTing-Go/dal/model"
	"DiTing-Go/domain/enum"
)

type Message model.Message

func (msg Message) GetContactMsg() string {
	if msg.Type == enum.TextMessageType {
		return msg.Content
	} else if msg.Type == enum.ImgMessageType {
		return "[图片]"
	}
	return msg.Content
}


================================================
FILE: domain/vo/req/agree_friend_req.go
================================================
package req

type AgreeFriendReq struct {
	Uid int64 `json:"uid" binding:"required"`
}


================================================
FILE: domain/vo/req/captcha_req.go
================================================
package req

type CaptchaReq struct {
	// 手机号
	Phone string `json:"phone" binding:"required"`
}


================================================
FILE: domain/vo/req/create_group_req.go
================================================
package req

type CreateGroupReq struct {
	UidList []int64 `json:"uidList" binding:"required"`
}


================================================
FILE: domain/vo/req/delete_friend_req.go
================================================
package req

type DeleteFriendReq struct {
	Uid int64 `json:"uid" binding:"required"`
}


================================================
FILE: domain/vo/req/delete_group_req.go
================================================
package req

type DeleteGroupReq struct {
	ID int64 `uri:"id" binding:"required"`
}


================================================
FILE: domain/vo/req/get_group_member_list_req.go
================================================
package req

type GetGroupMemberListReq struct {
	// 房间ID
	RoomId   int64   `form:"roomId" binding:"required"`
	Cursor   *string `form:"cursor"`
	PageSize int     `form:"pageSize" binding:"required"`
}


================================================
FILE: domain/vo/req/get_message_list_req.go
================================================
package req

type GetMessageListReq struct {
	RoomId   int64   `json:"roomId" form:"roomId" binding:"required"`
	Cursor   *string `json:"cursor" form:"cursor" binding:"required"`
	PageSize int     `json:"pageSize" form:"pageSize" binding:"required"`
}


================================================
FILE: domain/vo/req/get_new_content_list_req.go
================================================
package req

type GetNewContentListReq struct {
	Timestamp int64 `json:"timestamp" form:"timestamp" binding:"required"`
}


================================================
FILE: domain/vo/req/get_new_msg_list_req.go
================================================
package req

type GetNewMsgListReq struct {
	// 房间ID
	RoomId int64 `json:"roomId" form:"roomId" binding:"required"`
	// 消息ID
	MsgId int64 `json:"msgId" form:"msgId" binding:"required"`
}


================================================
FILE: domain/vo/req/get_user_info_batch_req.go
================================================
package req

type UserInfoBatchReqItem struct {
	Uid            int64 `json:"uid"`
	LastModifyTime int64 `json:"lastModifyTime"`
}
type GetUserInfoBatchReq struct {
	List []UserInfoBatchReqItem `json:"list" bind:"required"`
}


================================================
FILE: domain/vo/req/get_user_info_by_name_req.go
================================================
package req

type GetUserInfoByNameReq struct {
	// 用户名
	Name string `form:"name" binding:"required"`
}


================================================
FILE: domain/vo/req/grant_administrator_req.go
================================================
package req

type GrantAdministratorReq struct {
	// 房间ID
	RoomId int64 `json:"room_id" binding:"required"`
	// 授权用户ID
	GrantUid int64 `json:"grant_uid" binding:"required"`
}


================================================
FILE: domain/vo/req/is_friend_req.go
================================================
package req

// IsFriendReq 是否是好友请求
type IsFriendReq struct {
	FriendUid int64 `uri:"friendUid" binding:"required"`
}


================================================
FILE: domain/vo/req/join_group_req.go
================================================
package req

type JoinGroupReq struct {
	ID int64 `json:"id" binding:"required"`
}


================================================
FILE: domain/vo/req/message_req.go
================================================
package req

type MessageBody struct {
	Content    string `json:"content" form:"content" binding:"required"`
	ReplyMsgId int64  `json:"replyMsgId" form:"replyMsgId"`
}
type MessageReq struct {
	RoomId  int64       `json:"roomId" form:"roomId" binding:"required"`
	MsgType int32       `json:"msgType" form:"msgType" binding:"required"`
	Body    MessageBody `json:"body" form:"body" binding:"required"`
}


================================================
FILE: domain/vo/req/quit_group_req.go
================================================
package req

type QuitGroupReq struct {
	// 房间di
	ID int64 `json:"id" binding:"required"`
}


================================================
FILE: domain/vo/req/remove_administrator_req.go
================================================
package req

type RemoveAdministratorReq struct {
	// 房间ID
	RoomId int64 `json:"room_id" binding:"required"`
	// 移除用户ID
	RemoveUid int64 `json:"remove_uid" binding:"required"`
}


================================================
FILE: domain/vo/req/uid_req.go
================================================
package req

type UidReq struct {
	Uid int64 `json:"uid"`
}


================================================
FILE: domain/vo/req/user_apply_req.go
================================================
package req

type UserApplyReq struct {
	Uid int64  `json:"uid"`
	Msg string `json:"msg"`
}


================================================
FILE: domain/vo/req/user_cancle_req.go
================================================
package req

type UserCancelReq struct {
	Captcha string `json:"captcha" binding:"required"`
}


================================================
FILE: domain/vo/req/user_login_req.go
================================================
package req

type UserLoginReq struct {
	UserName  string `json:"username,omitempty"`           // 用户名可选
	Password  string `json:"password,omitempty"`           // 密码可选
	Phone     string `json:"phone,omitempty"`              // 手机号可选
	Captcha   string `json:"captcha,omitempty"`            // 验证码
	LoginType int    `json:"loginType" binding:"required"` // 登录类型, 1: 用户名密码登录, 2: 手机号验证码登录
}


================================================
FILE: domain/vo/req/user_register_req.go
================================================
package req

type UserRegisterReq struct {
	// 用户名
	Username string `json:"username" binding:"required"`
	// 密码
	Password string `json:"password" binding:"required"`
	// 手机号
	Phone string `json:"phone" binding:"required"`
	// 验证码
	Captcha string `json:"captcha" binding:"required"` // 如果需要验证码,可以取消注释
}


================================================
FILE: domain/vo/resp/get_user_info_batch_resp.go
================================================
package resp

type GetUserInfoBatchResp struct {
	Uid         int64  `json:"uid"`
	Username    string `json:"name"`
	Avatar      string `json:"avatar"`
	NeedRefresh bool   `json:"needRefresh"`
}


================================================
FILE: domain/vo/resp/get_user_info_by_name_resp.go
================================================
package resp

type GetUserInfoByNameResp struct {
	// 用户ID
	Uid int64 `json:"uid"`
	// 用户名
	Name string `json:"name"`
	// 头像
	Avatar string `json:"avatar"`
	// 好友状态
	Status int32 `json:"status"`
}


================================================
FILE: domain/vo/resp/message_resp.go
================================================
package resp

type MsgUser struct {
	Uid      int64  `json:"uid"`
	Username string `json:"username"`
	Avatar   string `json:"avatar"`
}
type Msg struct {
	ID     int64    `json:"id"`
	RoomId int64    `json:"roomId"`
	Type   int32    `json:"type"`
	Body   TextBody `json:"body"`
}
type TextBody struct {
	Content string `json:"content"`
	Reply   int64  `json:"reply"`
}
type MessageResp struct {
	FromUser MsgUser `json:"fromUser"`
	Message  Msg     `json:"message"`
	SendTime int64   `json:"sendTime"`
}


================================================
FILE: domain/vo/resp/page_list_resp.go
================================================
package resp

type PageListResp struct {
	List  interface{} `json:"dataList"`
	Total int         `json:"total"`
}


================================================
FILE: domain/vo/resp/pre_signed_resp.go
================================================
package resp

type PreSignedResp struct {
	Url    string            `json:"url"`
	Policy map[string]string `json:"policy"`
}


================================================
FILE: domain/vo/resp/user_apply_resp.go
================================================
package resp

type UserApplyResp struct {
	ApplyId int64  `json:"applyId"` // 申请ID
	Uid     int64  `json:"uid"`     // 用户ID
	Msg     string `json:"msg"`     // 申请信息
	Status  int32  `json:"status"`  // 使用状态 1.待审批 2.已接受
}


================================================
FILE: domain/vo/resp/user_contact_resp.go
================================================
package resp

type UserContactResp struct {
	Uid          int64 `json:"uid"`          // 用户ID
	ActiveStatus int   `json:"activeStatus"` // 用户状态
	LastOptTime  int64 `json:"lastOptTime"`  // 最后操作时间
}


================================================
FILE: domain/vo/resp/user_login_resp.go
================================================
package resp

type UserLoginResp struct {
	Token  string `json:"token"`
	Uid    int64  `json:"uid"`
	Name   string `json:"name"`
	Avatar string `json:"avatar"`
}


================================================
FILE: event/listener/friend_apply_event.go
================================================
package listener

import (
	"DiTing-Go/dal/model"
	"DiTing-Go/domain/enum"
	"DiTing-Go/global"
	"DiTing-Go/utils/jsonUtils"
	"context"
	"github.com/apache/rocketmq-client-go/v2"
	"github.com/apache/rocketmq-client-go/v2/consumer"
	"github.com/apache/rocketmq-client-go/v2/primitive"
	"github.com/spf13/viper"
)

func init() {
	host := viper.GetString("rocketmq.host")
	// 设置推送消费者
	rocketConsumer, _ := rocketmq.NewPushConsumer(
		//消费组
		consumer.WithGroupName(enum.FriendApplyTopic),
		// namesrv地址
		consumer.WithNameServer([]string{host}),
	)
	err := rocketConsumer.Subscribe(enum.FriendApplyTopic, consumer.MessageSelector{}, friendApplyEvent)
	if err != nil {
		global.Logger.Panicf("subscribe error: %s", err.Error())
	}
	err = rocketConsumer.Start()
	if err != nil {
		global.Logger.Panicf("start consumer error: %s", err.Error())
	}
}

// FriendApplyEvent 好友申请事件
func friendApplyEvent(ctx context.Context, ext ...*primitive.MessageExt) (consumer.ConsumeResult, error) {
	for i := range ext {
		// 解码
		userApplyR := model.UserApply{}
		if err := jsonUtils.UnmarshalMsg(&userApplyR, ext[i]); err != nil {
			global.Logger.Errorf("jsonUtils unmarshal error: %s", err.Error())
			return consumer.ConsumeRetryLater, nil
		}

		if err := friendApply(userApplyR); err != nil {
			global.Logger.Errorf("friendApply error: %s", err.Error())
			return consumer.ConsumeRetryLater, nil
		}
	}
	return consumer.ConsumeSuccess, nil
}

func friendApply(apply model.UserApply) error {
	// 发送新消息事件
	//service.Send(apply.TargetID)
	return nil
}


================================================
FILE: event/listener/friend_delete_event.go
================================================
package listener

import (
	"DiTing-Go/dal/model"
	"DiTing-Go/domain/dto"
	"DiTing-Go/domain/enum"
	"DiTing-Go/global"
	pkgEnum "DiTing-Go/pkg/domain/enum"
	"DiTing-Go/pkg/utils"
	"DiTing-Go/utils/jsonUtils"
	"DiTing-Go/utils/redisCache"
	"context"
	"fmt"
	"github.com/apache/rocketmq-client-go/v2"
	"github.com/apache/rocketmq-client-go/v2/consumer"
	"github.com/apache/rocketmq-client-go/v2/primitive"
	"github.com/pkg/errors"
	"github.com/spf13/viper"
	"sort"
)

func init() {
	host := viper.GetString("rocketmq.host")
	// 设置推送消费者
	rocketConsumer, _ := rocketmq.NewPushConsumer(
		//消费组
		consumer.WithGroupName(enum.DeleteFriendTopic),
		// namesrv地址
		consumer.WithNameServer([]string{host}),
	)
	err := rocketConsumer.Subscribe(enum.DeleteFriendTopic, consumer.MessageSelector{}, deleteFriendEvent)
	if err != nil {
		global.Logger.Panicf("subscribe error: %s", err.Error())
	}
	err = rocketConsumer.Start()
	if err != nil {
		global.Logger.Panicf("start consumer error: %s", err.Error())
	}
}

func deleteFriendEvent(ctx context.Context, ext ...*primitive.MessageExt) (consumer.ConsumeResult, error) {
	for i := range ext {
		// 解码
		deleteFriendDto := dto.DeleteFriendDto{}
		if err := jsonUtils.UnmarshalMsg(&deleteFriendDto, ext[i]); err != nil {
			global.Logger.Errorf("jsonUtils unmarshal error: %s", err.Error())
			return consumer.ConsumeRetryLater, nil
		}

		if err := deleteFriend(deleteFriendDto); err != nil {
			global.Logger.Errorf("deleteFriend error: %s", err.Error())
			return consumer.ConsumeRetryLater, nil
		}
	}
	return consumer.ConsumeSuccess, nil
}

func deleteFriend(deleteFriendDto dto.DeleteFriendDto) error {

	uid := deleteFriendDto.Uid
	deleteFriendUid := deleteFriendDto.FriendUid

	// 加锁
	uids := utils.Int64Slice{uid, deleteFriendUid}
	sort.Sort(uids)
	key := fmt.Sprintf(enum.UserAndFriendLock, uids[0], uids[1])
	mutex, err := utils.GetLock(key)
	if err != nil {
		return err
	}
	defer utils.ReleaseLock(mutex)

	ctx := context.Background()
	tx := global.Query.Begin()
	userApply := global.Query.UserApply
	userApplyTx := tx.UserApply.WithContext(ctx)

	// 删除好友申请
	if _, err := userApplyTx.Where(userApply.UID.Eq(uid), userApply.TargetID.Eq(deleteFriendUid)).Delete(); err != nil {
		if err := tx.Rollback(); err != nil {
			global.Logger.Errorf("事务回滚失败 %s", err.Error())
		}
		global.Logger.Errorf("删除好友失败 %s", err.Error())
		return errors.New("Business Error")
	}
	// 删除redis缓存
	defer redisCache.RemoveUserApply(uid, deleteFriendUid)

	if _, err := userApplyTx.Where(userApply.UID.Eq(deleteFriendUid), userApply.TargetID.Eq(uid)).Delete(); err != nil {
		if err := tx.Rollback(); err != nil {
			global.Logger.Errorf("事务回滚失败 %s", err.Error())
		}
		global.Logger.Errorf("删除好友失败 %s", err.Error())
		return errors.New("Business Error")
	}
	// 删除redis缓存
	defer redisCache.RemoveUserApply(deleteFriendUid, uid)

	// 软删除好友房间
	roomFriend := global.Query.RoomFriend
	roomFriendTx := tx.RoomFriend.WithContext(ctx)
	uids = utils.Int64Slice{uid, deleteFriendUid}
	sort.Sort(uids)
	fun := func() (interface{}, error) {
		return roomFriendTx.Where(roomFriend.Uid1.Eq(uids[0]), roomFriend.Uid2.Eq(uids[1])).First()
	}
	roomFriendR := model.RoomFriend{}
	key = fmt.Sprintf(enum.RoomFriendCacheByUidAndFriendUid, uids[0], uids[1])
	if err := utils.GetData(key, &roomFriendR, fun); err != nil {
		if err := tx.Rollback(); err != nil {
			global.Logger.Errorf("事务回滚失败 %s", err.Error())
		}
		global.Logger.Errorf("查询好友房间失败 %s", err.Error())
		return errors.New("Business Error")
	}

	if _, err := roomFriendTx.Where(roomFriend.ID.Eq(roomFriendR.ID)).Update(roomFriend.DeleteStatus, pkgEnum.DELETED); err != nil {
		if err := tx.Rollback(); err != nil {
			global.Logger.Errorf("事务回滚失败 %s", err.Error())
		}
		global.Logger.Errorf("删除好友房间失败 %s", err.Error())
		return errors.New("Business Error")
	}
	// 删除redis缓存
	defer redisCache.RemoveRoomFriend(roomFriendR)

	// 软删除房间表
	room := global.Query.Room
	roomTx := tx.Room.WithContext(ctx)
	if _, err := roomTx.Where(room.ID.Eq(roomFriendR.RoomID)).Update(room.DeleteStatus, pkgEnum.DELETED); err != nil {
		if err := tx.Rollback(); err != nil {
			global.Logger.Errorf("事务回滚失败 %s", err.Error())
		}
		global.Logger.Errorf("删除房间失败 %s", err.Error())
		return errors.New("Business Error")
	}
	// 删除redis缓存
	roomR := model.Room{
		ID: roomFriendR.RoomID,
	}
	defer redisCache.RemoveRoomCache(roomR)

	// 删除消息表
	msg := global.Query.Message
	msgTx := tx.Message.WithContext(ctx)
	if _, err := msgTx.Where(msg.RoomID.Eq(roomFriendR.RoomID)).Update(msg.DeleteStatus, pkgEnum.DELETED); err != nil {
		if err := tx.Rollback(); err != nil {
			global.Logger.Errorf("事务回滚失败 %s", err.Error())
		}
		global.Logger.Errorf("删除消息失败 %s", err.Error())
		return errors.New("Business Error")
	}
	// TODO: 删除消息表缓存

	if err := tx.Commit(); err != nil {
		global.Logger.Errorf("事务提交失败 %s", err.Error())
		return errors.New("Business Error")
	}

	return nil
}


================================================
FILE: event/listener/friend_new_event.go
================================================
package listener

import (
	"DiTing-Go/dal/model"
	"DiTing-Go/domain/enum"
	"DiTing-Go/global"
	pkgEnum "DiTing-Go/pkg/domain/enum"
	"DiTing-Go/pkg/utils"
	"DiTing-Go/service"
	"DiTing-Go/utils/redisCache"
	"context"
	"fmt"
	"github.com/apache/rocketmq-client-go/v2"
	"github.com/apache/rocketmq-client-go/v2/consumer"
	"github.com/apache/rocketmq-client-go/v2/primitive"
	"github.com/goccy/go-json"
	"github.com/pkg/errors"
	"github.com/spf13/viper"
	"gorm.io/gorm"
	"sort"
	"strconv"
	"time"
)

func init() {
	host := viper.GetString("rocketmq.host")
	// 
Download .txt
gitextract_mkmm_a5b/

├── .github/
│   └── workflows/
│       └── reademe-contributors.yml
├── .gitignore
├── LICENSE
├── README.md
├── cmd/
│   └── gen/
│       └── generate.go
├── conf/
│   └── config_example.yml
├── controller/
│   ├── captcha_controller.go
│   ├── chat_controller.go
│   ├── contact_controller.go
│   ├── friend_controller.go
│   └── user_controller.go
├── dal/
│   ├── db.go
│   ├── model/
│   │   ├── contact.gen.go
│   │   ├── group_member.gen.go
│   │   ├── message.gen.go
│   │   ├── room.gen.go
│   │   ├── room_friend.gen.go
│   │   ├── room_group.gen.go
│   │   ├── user.gen.go
│   │   ├── user_apply.gen.go
│   │   └── user_friend.gen.go
│   └── query/
│       ├── contact.gen.go
│       ├── gen.go
│       ├── group_member.gen.go
│       ├── message.gen.go
│       ├── room.gen.go
│       ├── room_friend.gen.go
│       ├── room_group.gen.go
│       ├── user.gen.go
│       ├── user_apply.gen.go
│       └── user_friend.gen.go
├── docs/
│   ├── docs.go
│   └── swagger.json
├── domain/
│   ├── dto/
│   │   ├── contact_dto.go
│   │   ├── delete_friend_dto.go
│   │   ├── group_dto.go
│   │   └── msg_dto.go
│   ├── enum/
│   │   ├── event_bus.go
│   │   ├── login.go
│   │   ├── message.go
│   │   ├── redis.go
│   │   ├── redsync.go
│   │   ├── rocketmq.go
│   │   ├── room.go
│   │   └── user.go
│   ├── model/
│   │   └── message.go
│   └── vo/
│       ├── req/
│       │   ├── agree_friend_req.go
│       │   ├── captcha_req.go
│       │   ├── create_group_req.go
│       │   ├── delete_friend_req.go
│       │   ├── delete_group_req.go
│       │   ├── get_group_member_list_req.go
│       │   ├── get_message_list_req.go
│       │   ├── get_new_content_list_req.go
│       │   ├── get_new_msg_list_req.go
│       │   ├── get_user_info_batch_req.go
│       │   ├── get_user_info_by_name_req.go
│       │   ├── grant_administrator_req.go
│       │   ├── is_friend_req.go
│       │   ├── join_group_req.go
│       │   ├── message_req.go
│       │   ├── quit_group_req.go
│       │   ├── remove_administrator_req.go
│       │   ├── uid_req.go
│       │   ├── user_apply_req.go
│       │   ├── user_cancle_req.go
│       │   ├── user_login_req.go
│       │   └── user_register_req.go
│       └── resp/
│           ├── get_user_info_batch_resp.go
│           ├── get_user_info_by_name_resp.go
│           ├── message_resp.go
│           ├── page_list_resp.go
│           ├── pre_signed_resp.go
│           ├── user_apply_resp.go
│           ├── user_contact_resp.go
│           └── user_login_resp.go
├── event/
│   └── listener/
│       ├── friend_apply_event.go
│       ├── friend_delete_event.go
│       ├── friend_new_event.go
│       ├── new_msg_event.go
│       └── user_login_event.go
├── global/
│   ├── init_db.go
│   ├── init_distribute_lock.go
│   ├── init_evenbus.go
│   ├── init_log.go
│   ├── init_minio.go
│   ├── init_redis.go
│   ├── init_rocketmq.go
│   └── init_time.go
├── go.mod
├── go.sum
├── logic/
│   ├── captcha.go
│   ├── login.go
│   ├── register.go
│   ├── user.go
│   └── user_cancle.go
├── main.go
├── pkg/
│   ├── domain/
│   │   ├── enum/
│   │   │   ├── code.go
│   │   │   ├── common_enum.go
│   │   │   └── msg.go
│   │   └── vo/
│   │       ├── req/
│   │       │   └── page_req.go
│   │       └── resp/
│   │           ├── page_resp.go
│   │           └── response.go
│   └── utils/
│       ├── cursor_utils.go
│       ├── redis.go
│       ├── redis_lock.go
│       └── sort.go
├── routes/
│   └── init_router.go
├── service/
│   ├── adapter/
│   │   ├── build_contact_dao_list.go
│   │   ├── build_message_resp.go
│   │   └── build_user_info_by_name_resp.go
│   ├── captcha_service.go
│   ├── contact_service.go
│   ├── friend_service.go
│   ├── group_service.go
│   ├── message_service.go
│   ├── upload_service.go
│   ├── user_service.go
│   ├── user_service_integration_test.go
│   └── user_service_test.go
├── sql/
│   └── sql.sql
├── tests/
│   ├── README.md
│   ├── e2e/
│   │   └── user_workflow_e2e_test.go
│   ├── init_test.go
│   ├── integration/
│   │   └── user_integration_test.go
│   ├── performance/
│   │   └── user_performance_test.go
│   ├── scripts/
│   │   ├── run_e2e_test.sh
│   │   ├── run_tests.bat
│   │   ├── run_tests.sh
│   │   └── setup_test_env.sh
│   └── unit/
│       └── user_service_test.go
├── utils/
│   ├── jsonUtils/
│   │   └── json.go
│   ├── jwt/
│   │   ├── jwt.go
│   │   └── jwt_test.go
│   ├── middleware/
│   │   ├── cors.go
│   │   ├── jwt.go
│   │   └── log.go
│   ├── mysqlUtils.go
│   ├── passwordUtils.go
│   ├── redisCache/
│   │   └── remove_cache.go
│   ├── redisUtils.go
│   ├── setting/
│   │   └── setting.go
│   └── time_utils.go
└── websocket/
    ├── domain/
    │   ├── enum/
    │   │   └── ws_type.go
    │   └── vo/
    │       └── resp/
    │           └── new_message_resp.go
    ├── global/
    │   └── global.go
    └── service/
        └── websocket_service.go
Download .txt
SYMBOL INDEX (864 symbols across 119 files)

FILE: cmd/gen/generate.go
  function connectDB (line 16) | func connectDB(dsn string) *gorm.DB {
  function main (line 24) | func main() {

FILE: controller/captcha_controller.go
  function CaptchaController (line 10) | func CaptchaController(c *gin.Context) {

FILE: controller/user_controller.go
  function RegisterController (line 21) | func RegisterController(c *gin.Context) {
  function LoginController (line 46) | func LoginController(c *gin.Context) {
  function CancelController (line 70) | func CancelController(ctx *gin.Context) {

FILE: dal/db.go
  function ConnectDB (line 12) | func ConnectDB(dsn string) *gorm.DB {

FILE: dal/model/contact.gen.go
  constant TableNameContact (line 11) | TableNameContact = "contact"
  type Contact (line 14) | type Contact struct
    method TableName (line 26) | func (*Contact) TableName() string {

FILE: dal/model/group_member.gen.go
  constant TableNameGroupMember (line 11) | TableNameGroupMember = "group_member"
  type GroupMember (line 14) | type GroupMember struct
    method TableName (line 24) | func (*GroupMember) TableName() string {

FILE: dal/model/message.gen.go
  constant TableNameMessage (line 11) | TableNameMessage = "message"
  type Message (line 14) | type Message struct
    method TableName (line 29) | func (*Message) TableName() string {

FILE: dal/model/room.gen.go
  constant TableNameRoom (line 11) | TableNameRoom = "room"
  type Room (line 14) | type Room struct
    method TableName (line 27) | func (*Room) TableName() string {

FILE: dal/model/room_friend.gen.go
  constant TableNameRoomFriend (line 11) | TableNameRoomFriend = "room_friend"
  type RoomFriend (line 14) | type RoomFriend struct
    method TableName (line 26) | func (*RoomFriend) TableName() string {

FILE: dal/model/room_group.gen.go
  constant TableNameRoomGroup (line 11) | TableNameRoomGroup = "room_group"
  type RoomGroup (line 14) | type RoomGroup struct
    method TableName (line 26) | func (*RoomGroup) TableName() string {

FILE: dal/model/user.gen.go
  constant TableNameUser (line 11) | TableNameUser = "user"
  type User (line 14) | type User struct
    method TableName (line 31) | func (*User) TableName() string {

FILE: dal/model/user_apply.gen.go
  constant TableNameUserApply (line 11) | TableNameUserApply = "user_apply"
  type UserApply (line 14) | type UserApply struct
    method TableName (line 27) | func (*UserApply) TableName() string {

FILE: dal/model/user_friend.gen.go
  constant TableNameUserFriend (line 11) | TableNameUserFriend = "user_friend"
  type UserFriend (line 14) | type UserFriend struct
    method TableName (line 24) | func (*UserFriend) TableName() string {

FILE: dal/query/contact.gen.go
  function newContact (line 22) | func newContact(db *gorm.DB, opts ...gen.DOOption) contact {
  type contact (line 45) | type contact struct
    method Table (line 61) | func (c contact) Table(newTableName string) *contact {
    method As (line 66) | func (c contact) As(alias string) *contact {
    method updateTableName (line 71) | func (c *contact) updateTableName(table string) *contact {
    method WithContext (line 87) | func (c *contact) WithContext(ctx context.Context) IContactDo { return...
    method TableName (line 89) | func (c contact) TableName() string { return c.contactDo.TableName() }
    method Alias (line 91) | func (c contact) Alias() string { return c.contactDo.Alias() }
    method Columns (line 93) | func (c contact) Columns(cols ...field.Expr) gen.Columns { return c.co...
    method GetFieldByName (line 95) | func (c *contact) GetFieldByName(fieldName string) (field.OrderExpr, b...
    method fillFieldMap (line 104) | func (c *contact) fillFieldMap() {
    method clone (line 116) | func (c contact) clone(db *gorm.DB) contact {
    method replaceDB (line 121) | func (c contact) replaceDB(db *gorm.DB) contact {
  type contactDo (line 126) | type contactDo struct
    method Debug (line 189) | func (c contactDo) Debug() IContactDo {
    method WithContext (line 193) | func (c contactDo) WithContext(ctx context.Context) IContactDo {
    method ReadDB (line 197) | func (c contactDo) ReadDB() IContactDo {
    method WriteDB (line 201) | func (c contactDo) WriteDB() IContactDo {
    method Session (line 205) | func (c contactDo) Session(config *gorm.Session) IContactDo {
    method Clauses (line 209) | func (c contactDo) Clauses(conds ...clause.Expression) IContactDo {
    method Returning (line 213) | func (c contactDo) Returning(value interface{}, columns ...string) ICo...
    method Not (line 217) | func (c contactDo) Not(conds ...gen.Condition) IContactDo {
    method Or (line 221) | func (c contactDo) Or(conds ...gen.Condition) IContactDo {
    method Select (line 225) | func (c contactDo) Select(conds ...field.Expr) IContactDo {
    method Where (line 229) | func (c contactDo) Where(conds ...gen.Condition) IContactDo {
    method Order (line 233) | func (c contactDo) Order(conds ...field.Expr) IContactDo {
    method Distinct (line 237) | func (c contactDo) Distinct(cols ...field.Expr) IContactDo {
    method Omit (line 241) | func (c contactDo) Omit(cols ...field.Expr) IContactDo {
    method Join (line 245) | func (c contactDo) Join(table schema.Tabler, on ...field.Expr) IContac...
    method LeftJoin (line 249) | func (c contactDo) LeftJoin(table schema.Tabler, on ...field.Expr) ICo...
    method RightJoin (line 253) | func (c contactDo) RightJoin(table schema.Tabler, on ...field.Expr) IC...
    method Group (line 257) | func (c contactDo) Group(cols ...field.Expr) IContactDo {
    method Having (line 261) | func (c contactDo) Having(conds ...gen.Condition) IContactDo {
    method Limit (line 265) | func (c contactDo) Limit(limit int) IContactDo {
    method Offset (line 269) | func (c contactDo) Offset(offset int) IContactDo {
    method Scopes (line 273) | func (c contactDo) Scopes(funcs ...func(gen.Dao) gen.Dao) IContactDo {
    method Unscoped (line 277) | func (c contactDo) Unscoped() IContactDo {
    method Create (line 281) | func (c contactDo) Create(values ...*model.Contact) error {
    method CreateInBatches (line 288) | func (c contactDo) CreateInBatches(values []*model.Contact, batchSize ...
    method Save (line 294) | func (c contactDo) Save(values ...*model.Contact) error {
    method First (line 301) | func (c contactDo) First() (*model.Contact, error) {
    method Take (line 309) | func (c contactDo) Take() (*model.Contact, error) {
    method Last (line 317) | func (c contactDo) Last() (*model.Contact, error) {
    method Find (line 325) | func (c contactDo) Find() ([]*model.Contact, error) {
    method FindInBatch (line 330) | func (c contactDo) FindInBatch(batchSize int, fc func(tx gen.Dao, batc...
    method FindInBatches (line 339) | func (c contactDo) FindInBatches(result *[]*model.Contact, batchSize i...
    method Attrs (line 343) | func (c contactDo) Attrs(attrs ...field.AssignExpr) IContactDo {
    method Assign (line 347) | func (c contactDo) Assign(attrs ...field.AssignExpr) IContactDo {
    method Joins (line 351) | func (c contactDo) Joins(fields ...field.RelationField) IContactDo {
    method Preload (line 358) | func (c contactDo) Preload(fields ...field.RelationField) IContactDo {
    method FirstOrInit (line 365) | func (c contactDo) FirstOrInit() (*model.Contact, error) {
    method FirstOrCreate (line 373) | func (c contactDo) FirstOrCreate() (*model.Contact, error) {
    method FindByPage (line 381) | func (c contactDo) FindByPage(offset int, limit int) (result []*model....
    method ScanByPage (line 396) | func (c contactDo) ScanByPage(result interface{}, offset int, limit in...
    method Scan (line 406) | func (c contactDo) Scan(result interface{}) (err error) {
    method Delete (line 410) | func (c contactDo) Delete(models ...*model.Contact) (result gen.Result...
    method withDO (line 414) | func (c *contactDo) withDO(do gen.Dao) *contactDo {
  type IContactDo (line 128) | type IContactDo interface

FILE: dal/query/gen.go
  function SetDefault (line 23) | func SetDefault(db *gorm.DB, opts ...gen.DOOption) {
  function Use (line 28) | func Use(db *gorm.DB, opts ...gen.DOOption) *Query {
  type Query (line 35) | type Query struct
    method Available (line 41) | func (q *Query) Available() bool { return q.db != nil }
    method clone (line 43) | func (q *Query) clone(db *gorm.DB) *Query {
    method ReadDB (line 50) | func (q *Query) ReadDB() *Query {
    method WriteDB (line 54) | func (q *Query) WriteDB() *Query {
    method ReplaceDB (line 58) | func (q *Query) ReplaceDB(db *gorm.DB) *Query {
    method WithContext (line 69) | func (q *Query) WithContext(ctx context.Context) *queryCtx {
    method Transaction (line 75) | func (q *Query) Transaction(fc func(tx *Query) error, opts ...*sql.TxO...
    method Begin (line 79) | func (q *Query) Begin(opts ...*sql.TxOptions) *QueryTx {
  type queryCtx (line 65) | type queryCtx struct
  type QueryTx (line 84) | type QueryTx struct
    method Commit (line 89) | func (q *QueryTx) Commit() error {
    method Rollback (line 93) | func (q *QueryTx) Rollback() error {
    method SavePoint (line 97) | func (q *QueryTx) SavePoint(name string) error {
    method RollbackTo (line 101) | func (q *QueryTx) RollbackTo(name string) error {

FILE: dal/query/group_member.gen.go
  function newGroupMember (line 22) | func newGroupMember(db *gorm.DB, opts ...gen.DOOption) groupMember {
  type groupMember (line 43) | type groupMember struct
    method Table (line 57) | func (g groupMember) Table(newTableName string) *groupMember {
    method As (line 62) | func (g groupMember) As(alias string) *groupMember {
    method updateTableName (line 67) | func (g *groupMember) updateTableName(table string) *groupMember {
    method WithContext (line 81) | func (g *groupMember) WithContext(ctx context.Context) IGroupMemberDo {
    method TableName (line 85) | func (g groupMember) TableName() string { return g.groupMemberDo.Table...
    method Alias (line 87) | func (g groupMember) Alias() string { return g.groupMemberDo.Alias() }
    method Columns (line 89) | func (g groupMember) Columns(cols ...field.Expr) gen.Columns { return ...
    method GetFieldByName (line 91) | func (g *groupMember) GetFieldByName(fieldName string) (field.OrderExp...
    method fillFieldMap (line 100) | func (g *groupMember) fillFieldMap() {
    method clone (line 110) | func (g groupMember) clone(db *gorm.DB) groupMember {
    method replaceDB (line 115) | func (g groupMember) replaceDB(db *gorm.DB) groupMember {
  type groupMemberDo (line 120) | type groupMemberDo struct
    method Debug (line 183) | func (g groupMemberDo) Debug() IGroupMemberDo {
    method WithContext (line 187) | func (g groupMemberDo) WithContext(ctx context.Context) IGroupMemberDo {
    method ReadDB (line 191) | func (g groupMemberDo) ReadDB() IGroupMemberDo {
    method WriteDB (line 195) | func (g groupMemberDo) WriteDB() IGroupMemberDo {
    method Session (line 199) | func (g groupMemberDo) Session(config *gorm.Session) IGroupMemberDo {
    method Clauses (line 203) | func (g groupMemberDo) Clauses(conds ...clause.Expression) IGroupMembe...
    method Returning (line 207) | func (g groupMemberDo) Returning(value interface{}, columns ...string)...
    method Not (line 211) | func (g groupMemberDo) Not(conds ...gen.Condition) IGroupMemberDo {
    method Or (line 215) | func (g groupMemberDo) Or(conds ...gen.Condition) IGroupMemberDo {
    method Select (line 219) | func (g groupMemberDo) Select(conds ...field.Expr) IGroupMemberDo {
    method Where (line 223) | func (g groupMemberDo) Where(conds ...gen.Condition) IGroupMemberDo {
    method Order (line 227) | func (g groupMemberDo) Order(conds ...field.Expr) IGroupMemberDo {
    method Distinct (line 231) | func (g groupMemberDo) Distinct(cols ...field.Expr) IGroupMemberDo {
    method Omit (line 235) | func (g groupMemberDo) Omit(cols ...field.Expr) IGroupMemberDo {
    method Join (line 239) | func (g groupMemberDo) Join(table schema.Tabler, on ...field.Expr) IGr...
    method LeftJoin (line 243) | func (g groupMemberDo) LeftJoin(table schema.Tabler, on ...field.Expr)...
    method RightJoin (line 247) | func (g groupMemberDo) RightJoin(table schema.Tabler, on ...field.Expr...
    method Group (line 251) | func (g groupMemberDo) Group(cols ...field.Expr) IGroupMemberDo {
    method Having (line 255) | func (g groupMemberDo) Having(conds ...gen.Condition) IGroupMemberDo {
    method Limit (line 259) | func (g groupMemberDo) Limit(limit int) IGroupMemberDo {
    method Offset (line 263) | func (g groupMemberDo) Offset(offset int) IGroupMemberDo {
    method Scopes (line 267) | func (g groupMemberDo) Scopes(funcs ...func(gen.Dao) gen.Dao) IGroupMe...
    method Unscoped (line 271) | func (g groupMemberDo) Unscoped() IGroupMemberDo {
    method Create (line 275) | func (g groupMemberDo) Create(values ...*model.GroupMember) error {
    method CreateInBatches (line 282) | func (g groupMemberDo) CreateInBatches(values []*model.GroupMember, ba...
    method Save (line 288) | func (g groupMemberDo) Save(values ...*model.GroupMember) error {
    method First (line 295) | func (g groupMemberDo) First() (*model.GroupMember, error) {
    method Take (line 303) | func (g groupMemberDo) Take() (*model.GroupMember, error) {
    method Last (line 311) | func (g groupMemberDo) Last() (*model.GroupMember, error) {
    method Find (line 319) | func (g groupMemberDo) Find() ([]*model.GroupMember, error) {
    method FindInBatch (line 324) | func (g groupMemberDo) FindInBatch(batchSize int, fc func(tx gen.Dao, ...
    method FindInBatches (line 333) | func (g groupMemberDo) FindInBatches(result *[]*model.GroupMember, bat...
    method Attrs (line 337) | func (g groupMemberDo) Attrs(attrs ...field.AssignExpr) IGroupMemberDo {
    method Assign (line 341) | func (g groupMemberDo) Assign(attrs ...field.AssignExpr) IGroupMemberDo {
    method Joins (line 345) | func (g groupMemberDo) Joins(fields ...field.RelationField) IGroupMemb...
    method Preload (line 352) | func (g groupMemberDo) Preload(fields ...field.RelationField) IGroupMe...
    method FirstOrInit (line 359) | func (g groupMemberDo) FirstOrInit() (*model.GroupMember, error) {
    method FirstOrCreate (line 367) | func (g groupMemberDo) FirstOrCreate() (*model.GroupMember, error) {
    method FindByPage (line 375) | func (g groupMemberDo) FindByPage(offset int, limit int) (result []*mo...
    method ScanByPage (line 390) | func (g groupMemberDo) ScanByPage(result interface{}, offset int, limi...
    method Scan (line 400) | func (g groupMemberDo) Scan(result interface{}) (err error) {
    method Delete (line 404) | func (g groupMemberDo) Delete(models ...*model.GroupMember) (result ge...
    method withDO (line 408) | func (g *groupMemberDo) withDO(do gen.Dao) *groupMemberDo {
  type IGroupMemberDo (line 122) | type IGroupMemberDo interface

FILE: dal/query/message.gen.go
  function newMessage (line 22) | func newMessage(db *gorm.DB, opts ...gen.DOOption) message {
  type message (line 48) | type message struct
    method Table (line 67) | func (m message) Table(newTableName string) *message {
    method As (line 72) | func (m message) As(alias string) *message {
    method updateTableName (line 77) | func (m *message) updateTableName(table string) *message {
    method WithContext (line 96) | func (m *message) WithContext(ctx context.Context) IMessageDo { return...
    method TableName (line 98) | func (m message) TableName() string { return m.messageDo.TableName() }
    method Alias (line 100) | func (m message) Alias() string { return m.messageDo.Alias() }
    method Columns (line 102) | func (m message) Columns(cols ...field.Expr) gen.Columns { return m.me...
    method GetFieldByName (line 104) | func (m *message) GetFieldByName(fieldName string) (field.OrderExpr, b...
    method fillFieldMap (line 113) | func (m *message) fillFieldMap() {
    method clone (line 128) | func (m message) clone(db *gorm.DB) message {
    method replaceDB (line 133) | func (m message) replaceDB(db *gorm.DB) message {
  type messageDo (line 138) | type messageDo struct
    method Debug (line 201) | func (m messageDo) Debug() IMessageDo {
    method WithContext (line 205) | func (m messageDo) WithContext(ctx context.Context) IMessageDo {
    method ReadDB (line 209) | func (m messageDo) ReadDB() IMessageDo {
    method WriteDB (line 213) | func (m messageDo) WriteDB() IMessageDo {
    method Session (line 217) | func (m messageDo) Session(config *gorm.Session) IMessageDo {
    method Clauses (line 221) | func (m messageDo) Clauses(conds ...clause.Expression) IMessageDo {
    method Returning (line 225) | func (m messageDo) Returning(value interface{}, columns ...string) IMe...
    method Not (line 229) | func (m messageDo) Not(conds ...gen.Condition) IMessageDo {
    method Or (line 233) | func (m messageDo) Or(conds ...gen.Condition) IMessageDo {
    method Select (line 237) | func (m messageDo) Select(conds ...field.Expr) IMessageDo {
    method Where (line 241) | func (m messageDo) Where(conds ...gen.Condition) IMessageDo {
    method Order (line 245) | func (m messageDo) Order(conds ...field.Expr) IMessageDo {
    method Distinct (line 249) | func (m messageDo) Distinct(cols ...field.Expr) IMessageDo {
    method Omit (line 253) | func (m messageDo) Omit(cols ...field.Expr) IMessageDo {
    method Join (line 257) | func (m messageDo) Join(table schema.Tabler, on ...field.Expr) IMessag...
    method LeftJoin (line 261) | func (m messageDo) LeftJoin(table schema.Tabler, on ...field.Expr) IMe...
    method RightJoin (line 265) | func (m messageDo) RightJoin(table schema.Tabler, on ...field.Expr) IM...
    method Group (line 269) | func (m messageDo) Group(cols ...field.Expr) IMessageDo {
    method Having (line 273) | func (m messageDo) Having(conds ...gen.Condition) IMessageDo {
    method Limit (line 277) | func (m messageDo) Limit(limit int) IMessageDo {
    method Offset (line 281) | func (m messageDo) Offset(offset int) IMessageDo {
    method Scopes (line 285) | func (m messageDo) Scopes(funcs ...func(gen.Dao) gen.Dao) IMessageDo {
    method Unscoped (line 289) | func (m messageDo) Unscoped() IMessageDo {
    method Create (line 293) | func (m messageDo) Create(values ...*model.Message) error {
    method CreateInBatches (line 300) | func (m messageDo) CreateInBatches(values []*model.Message, batchSize ...
    method Save (line 306) | func (m messageDo) Save(values ...*model.Message) error {
    method First (line 313) | func (m messageDo) First() (*model.Message, error) {
    method Take (line 321) | func (m messageDo) Take() (*model.Message, error) {
    method Last (line 329) | func (m messageDo) Last() (*model.Message, error) {
    method Find (line 337) | func (m messageDo) Find() ([]*model.Message, error) {
    method FindInBatch (line 342) | func (m messageDo) FindInBatch(batchSize int, fc func(tx gen.Dao, batc...
    method FindInBatches (line 351) | func (m messageDo) FindInBatches(result *[]*model.Message, batchSize i...
    method Attrs (line 355) | func (m messageDo) Attrs(attrs ...field.AssignExpr) IMessageDo {
    method Assign (line 359) | func (m messageDo) Assign(attrs ...field.AssignExpr) IMessageDo {
    method Joins (line 363) | func (m messageDo) Joins(fields ...field.RelationField) IMessageDo {
    method Preload (line 370) | func (m messageDo) Preload(fields ...field.RelationField) IMessageDo {
    method FirstOrInit (line 377) | func (m messageDo) FirstOrInit() (*model.Message, error) {
    method FirstOrCreate (line 385) | func (m messageDo) FirstOrCreate() (*model.Message, error) {
    method FindByPage (line 393) | func (m messageDo) FindByPage(offset int, limit int) (result []*model....
    method ScanByPage (line 408) | func (m messageDo) ScanByPage(result interface{}, offset int, limit in...
    method Scan (line 418) | func (m messageDo) Scan(result interface{}) (err error) {
    method Delete (line 422) | func (m messageDo) Delete(models ...*model.Message) (result gen.Result...
    method withDO (line 426) | func (m *messageDo) withDO(do gen.Dao) *messageDo {
  type IMessageDo (line 140) | type IMessageDo interface

FILE: dal/query/room.gen.go
  function newRoom (line 22) | func newRoom(db *gorm.DB, opts ...gen.DOOption) room {
  type room (line 46) | type room struct
    method Table (line 63) | func (r room) Table(newTableName string) *room {
    method As (line 68) | func (r room) As(alias string) *room {
    method updateTableName (line 73) | func (r *room) updateTableName(table string) *room {
    method WithContext (line 90) | func (r *room) WithContext(ctx context.Context) IRoomDo { return r.roo...
    method TableName (line 92) | func (r room) TableName() string { return r.roomDo.TableName() }
    method Alias (line 94) | func (r room) Alias() string { return r.roomDo.Alias() }
    method Columns (line 96) | func (r room) Columns(cols ...field.Expr) gen.Columns { return r.roomD...
    method GetFieldByName (line 98) | func (r *room) GetFieldByName(fieldName string) (field.OrderExpr, bool) {
    method fillFieldMap (line 107) | func (r *room) fillFieldMap() {
    method clone (line 120) | func (r room) clone(db *gorm.DB) room {
    method replaceDB (line 125) | func (r room) replaceDB(db *gorm.DB) room {
  type roomDo (line 130) | type roomDo struct
    method Debug (line 193) | func (r roomDo) Debug() IRoomDo {
    method WithContext (line 197) | func (r roomDo) WithContext(ctx context.Context) IRoomDo {
    method ReadDB (line 201) | func (r roomDo) ReadDB() IRoomDo {
    method WriteDB (line 205) | func (r roomDo) WriteDB() IRoomDo {
    method Session (line 209) | func (r roomDo) Session(config *gorm.Session) IRoomDo {
    method Clauses (line 213) | func (r roomDo) Clauses(conds ...clause.Expression) IRoomDo {
    method Returning (line 217) | func (r roomDo) Returning(value interface{}, columns ...string) IRoomDo {
    method Not (line 221) | func (r roomDo) Not(conds ...gen.Condition) IRoomDo {
    method Or (line 225) | func (r roomDo) Or(conds ...gen.Condition) IRoomDo {
    method Select (line 229) | func (r roomDo) Select(conds ...field.Expr) IRoomDo {
    method Where (line 233) | func (r roomDo) Where(conds ...gen.Condition) IRoomDo {
    method Order (line 237) | func (r roomDo) Order(conds ...field.Expr) IRoomDo {
    method Distinct (line 241) | func (r roomDo) Distinct(cols ...field.Expr) IRoomDo {
    method Omit (line 245) | func (r roomDo) Omit(cols ...field.Expr) IRoomDo {
    method Join (line 249) | func (r roomDo) Join(table schema.Tabler, on ...field.Expr) IRoomDo {
    method LeftJoin (line 253) | func (r roomDo) LeftJoin(table schema.Tabler, on ...field.Expr) IRoomDo {
    method RightJoin (line 257) | func (r roomDo) RightJoin(table schema.Tabler, on ...field.Expr) IRoom...
    method Group (line 261) | func (r roomDo) Group(cols ...field.Expr) IRoomDo {
    method Having (line 265) | func (r roomDo) Having(conds ...gen.Condition) IRoomDo {
    method Limit (line 269) | func (r roomDo) Limit(limit int) IRoomDo {
    method Offset (line 273) | func (r roomDo) Offset(offset int) IRoomDo {
    method Scopes (line 277) | func (r roomDo) Scopes(funcs ...func(gen.Dao) gen.Dao) IRoomDo {
    method Unscoped (line 281) | func (r roomDo) Unscoped() IRoomDo {
    method Create (line 285) | func (r roomDo) Create(values ...*model.Room) error {
    method CreateInBatches (line 292) | func (r roomDo) CreateInBatches(values []*model.Room, batchSize int) e...
    method Save (line 298) | func (r roomDo) Save(values ...*model.Room) error {
    method First (line 305) | func (r roomDo) First() (*model.Room, error) {
    method Take (line 313) | func (r roomDo) Take() (*model.Room, error) {
    method Last (line 321) | func (r roomDo) Last() (*model.Room, error) {
    method Find (line 329) | func (r roomDo) Find() ([]*model.Room, error) {
    method FindInBatch (line 334) | func (r roomDo) FindInBatch(batchSize int, fc func(tx gen.Dao, batch i...
    method FindInBatches (line 343) | func (r roomDo) FindInBatches(result *[]*model.Room, batchSize int, fc...
    method Attrs (line 347) | func (r roomDo) Attrs(attrs ...field.AssignExpr) IRoomDo {
    method Assign (line 351) | func (r roomDo) Assign(attrs ...field.AssignExpr) IRoomDo {
    method Joins (line 355) | func (r roomDo) Joins(fields ...field.RelationField) IRoomDo {
    method Preload (line 362) | func (r roomDo) Preload(fields ...field.RelationField) IRoomDo {
    method FirstOrInit (line 369) | func (r roomDo) FirstOrInit() (*model.Room, error) {
    method FirstOrCreate (line 377) | func (r roomDo) FirstOrCreate() (*model.Room, error) {
    method FindByPage (line 385) | func (r roomDo) FindByPage(offset int, limit int) (result []*model.Roo...
    method ScanByPage (line 400) | func (r roomDo) ScanByPage(result interface{}, offset int, limit int) ...
    method Scan (line 410) | func (r roomDo) Scan(result interface{}) (err error) {
    method Delete (line 414) | func (r roomDo) Delete(models ...*model.Room) (result gen.ResultInfo, ...
    method withDO (line 418) | func (r *roomDo) withDO(do gen.Dao) *roomDo {
  type IRoomDo (line 132) | type IRoomDo interface

FILE: dal/query/room_friend.gen.go
  function newRoomFriend (line 22) | func newRoomFriend(db *gorm.DB, opts ...gen.DOOption) roomFriend {
  type roomFriend (line 45) | type roomFriend struct
    method Table (line 61) | func (r roomFriend) Table(newTableName string) *roomFriend {
    method As (line 66) | func (r roomFriend) As(alias string) *roomFriend {
    method updateTableName (line 71) | func (r *roomFriend) updateTableName(table string) *roomFriend {
    method WithContext (line 87) | func (r *roomFriend) WithContext(ctx context.Context) IRoomFriendDo {
    method TableName (line 91) | func (r roomFriend) TableName() string { return r.roomFriendDo.TableNa...
    method Alias (line 93) | func (r roomFriend) Alias() string { return r.roomFriendDo.Alias() }
    method Columns (line 95) | func (r roomFriend) Columns(cols ...field.Expr) gen.Columns { return r...
    method GetFieldByName (line 97) | func (r *roomFriend) GetFieldByName(fieldName string) (field.OrderExpr...
    method fillFieldMap (line 106) | func (r *roomFriend) fillFieldMap() {
    method clone (line 118) | func (r roomFriend) clone(db *gorm.DB) roomFriend {
    method replaceDB (line 123) | func (r roomFriend) replaceDB(db *gorm.DB) roomFriend {
  type roomFriendDo (line 128) | type roomFriendDo struct
    method Debug (line 191) | func (r roomFriendDo) Debug() IRoomFriendDo {
    method WithContext (line 195) | func (r roomFriendDo) WithContext(ctx context.Context) IRoomFriendDo {
    method ReadDB (line 199) | func (r roomFriendDo) ReadDB() IRoomFriendDo {
    method WriteDB (line 203) | func (r roomFriendDo) WriteDB() IRoomFriendDo {
    method Session (line 207) | func (r roomFriendDo) Session(config *gorm.Session) IRoomFriendDo {
    method Clauses (line 211) | func (r roomFriendDo) Clauses(conds ...clause.Expression) IRoomFriendDo {
    method Returning (line 215) | func (r roomFriendDo) Returning(value interface{}, columns ...string) ...
    method Not (line 219) | func (r roomFriendDo) Not(conds ...gen.Condition) IRoomFriendDo {
    method Or (line 223) | func (r roomFriendDo) Or(conds ...gen.Condition) IRoomFriendDo {
    method Select (line 227) | func (r roomFriendDo) Select(conds ...field.Expr) IRoomFriendDo {
    method Where (line 231) | func (r roomFriendDo) Where(conds ...gen.Condition) IRoomFriendDo {
    method Order (line 235) | func (r roomFriendDo) Order(conds ...field.Expr) IRoomFriendDo {
    method Distinct (line 239) | func (r roomFriendDo) Distinct(cols ...field.Expr) IRoomFriendDo {
    method Omit (line 243) | func (r roomFriendDo) Omit(cols ...field.Expr) IRoomFriendDo {
    method Join (line 247) | func (r roomFriendDo) Join(table schema.Tabler, on ...field.Expr) IRoo...
    method LeftJoin (line 251) | func (r roomFriendDo) LeftJoin(table schema.Tabler, on ...field.Expr) ...
    method RightJoin (line 255) | func (r roomFriendDo) RightJoin(table schema.Tabler, on ...field.Expr)...
    method Group (line 259) | func (r roomFriendDo) Group(cols ...field.Expr) IRoomFriendDo {
    method Having (line 263) | func (r roomFriendDo) Having(conds ...gen.Condition) IRoomFriendDo {
    method Limit (line 267) | func (r roomFriendDo) Limit(limit int) IRoomFriendDo {
    method Offset (line 271) | func (r roomFriendDo) Offset(offset int) IRoomFriendDo {
    method Scopes (line 275) | func (r roomFriendDo) Scopes(funcs ...func(gen.Dao) gen.Dao) IRoomFrie...
    method Unscoped (line 279) | func (r roomFriendDo) Unscoped() IRoomFriendDo {
    method Create (line 283) | func (r roomFriendDo) Create(values ...*model.RoomFriend) error {
    method CreateInBatches (line 290) | func (r roomFriendDo) CreateInBatches(values []*model.RoomFriend, batc...
    method Save (line 296) | func (r roomFriendDo) Save(values ...*model.RoomFriend) error {
    method First (line 303) | func (r roomFriendDo) First() (*model.RoomFriend, error) {
    method Take (line 311) | func (r roomFriendDo) Take() (*model.RoomFriend, error) {
    method Last (line 319) | func (r roomFriendDo) Last() (*model.RoomFriend, error) {
    method Find (line 327) | func (r roomFriendDo) Find() ([]*model.RoomFriend, error) {
    method FindInBatch (line 332) | func (r roomFriendDo) FindInBatch(batchSize int, fc func(tx gen.Dao, b...
    method FindInBatches (line 341) | func (r roomFriendDo) FindInBatches(result *[]*model.RoomFriend, batch...
    method Attrs (line 345) | func (r roomFriendDo) Attrs(attrs ...field.AssignExpr) IRoomFriendDo {
    method Assign (line 349) | func (r roomFriendDo) Assign(attrs ...field.AssignExpr) IRoomFriendDo {
    method Joins (line 353) | func (r roomFriendDo) Joins(fields ...field.RelationField) IRoomFriend...
    method Preload (line 360) | func (r roomFriendDo) Preload(fields ...field.RelationField) IRoomFrie...
    method FirstOrInit (line 367) | func (r roomFriendDo) FirstOrInit() (*model.RoomFriend, error) {
    method FirstOrCreate (line 375) | func (r roomFriendDo) FirstOrCreate() (*model.RoomFriend, error) {
    method FindByPage (line 383) | func (r roomFriendDo) FindByPage(offset int, limit int) (result []*mod...
    method ScanByPage (line 398) | func (r roomFriendDo) ScanByPage(result interface{}, offset int, limit...
    method Scan (line 408) | func (r roomFriendDo) Scan(result interface{}) (err error) {
    method Delete (line 412) | func (r roomFriendDo) Delete(models ...*model.RoomFriend) (result gen....
    method withDO (line 416) | func (r *roomFriendDo) withDO(do gen.Dao) *roomFriendDo {
  type IRoomFriendDo (line 130) | type IRoomFriendDo interface

FILE: dal/query/room_group.gen.go
  function newRoomGroup (line 22) | func newRoomGroup(db *gorm.DB, opts ...gen.DOOption) roomGroup {
  type roomGroup (line 45) | type roomGroup struct
    method Table (line 61) | func (r roomGroup) Table(newTableName string) *roomGroup {
    method As (line 66) | func (r roomGroup) As(alias string) *roomGroup {
    method updateTableName (line 71) | func (r *roomGroup) updateTableName(table string) *roomGroup {
    method WithContext (line 87) | func (r *roomGroup) WithContext(ctx context.Context) IRoomGroupDo {
    method TableName (line 91) | func (r roomGroup) TableName() string { return r.roomGroupDo.TableName...
    method Alias (line 93) | func (r roomGroup) Alias() string { return r.roomGroupDo.Alias() }
    method Columns (line 95) | func (r roomGroup) Columns(cols ...field.Expr) gen.Columns { return r....
    method GetFieldByName (line 97) | func (r *roomGroup) GetFieldByName(fieldName string) (field.OrderExpr,...
    method fillFieldMap (line 106) | func (r *roomGroup) fillFieldMap() {
    method clone (line 118) | func (r roomGroup) clone(db *gorm.DB) roomGroup {
    method replaceDB (line 123) | func (r roomGroup) replaceDB(db *gorm.DB) roomGroup {
  type roomGroupDo (line 128) | type roomGroupDo struct
    method Debug (line 191) | func (r roomGroupDo) Debug() IRoomGroupDo {
    method WithContext (line 195) | func (r roomGroupDo) WithContext(ctx context.Context) IRoomGroupDo {
    method ReadDB (line 199) | func (r roomGroupDo) ReadDB() IRoomGroupDo {
    method WriteDB (line 203) | func (r roomGroupDo) WriteDB() IRoomGroupDo {
    method Session (line 207) | func (r roomGroupDo) Session(config *gorm.Session) IRoomGroupDo {
    method Clauses (line 211) | func (r roomGroupDo) Clauses(conds ...clause.Expression) IRoomGroupDo {
    method Returning (line 215) | func (r roomGroupDo) Returning(value interface{}, columns ...string) I...
    method Not (line 219) | func (r roomGroupDo) Not(conds ...gen.Condition) IRoomGroupDo {
    method Or (line 223) | func (r roomGroupDo) Or(conds ...gen.Condition) IRoomGroupDo {
    method Select (line 227) | func (r roomGroupDo) Select(conds ...field.Expr) IRoomGroupDo {
    method Where (line 231) | func (r roomGroupDo) Where(conds ...gen.Condition) IRoomGroupDo {
    method Order (line 235) | func (r roomGroupDo) Order(conds ...field.Expr) IRoomGroupDo {
    method Distinct (line 239) | func (r roomGroupDo) Distinct(cols ...field.Expr) IRoomGroupDo {
    method Omit (line 243) | func (r roomGroupDo) Omit(cols ...field.Expr) IRoomGroupDo {
    method Join (line 247) | func (r roomGroupDo) Join(table schema.Tabler, on ...field.Expr) IRoom...
    method LeftJoin (line 251) | func (r roomGroupDo) LeftJoin(table schema.Tabler, on ...field.Expr) I...
    method RightJoin (line 255) | func (r roomGroupDo) RightJoin(table schema.Tabler, on ...field.Expr) ...
    method Group (line 259) | func (r roomGroupDo) Group(cols ...field.Expr) IRoomGroupDo {
    method Having (line 263) | func (r roomGroupDo) Having(conds ...gen.Condition) IRoomGroupDo {
    method Limit (line 267) | func (r roomGroupDo) Limit(limit int) IRoomGroupDo {
    method Offset (line 271) | func (r roomGroupDo) Offset(offset int) IRoomGroupDo {
    method Scopes (line 275) | func (r roomGroupDo) Scopes(funcs ...func(gen.Dao) gen.Dao) IRoomGroup...
    method Unscoped (line 279) | func (r roomGroupDo) Unscoped() IRoomGroupDo {
    method Create (line 283) | func (r roomGroupDo) Create(values ...*model.RoomGroup) error {
    method CreateInBatches (line 290) | func (r roomGroupDo) CreateInBatches(values []*model.RoomGroup, batchS...
    method Save (line 296) | func (r roomGroupDo) Save(values ...*model.RoomGroup) error {
    method First (line 303) | func (r roomGroupDo) First() (*model.RoomGroup, error) {
    method Take (line 311) | func (r roomGroupDo) Take() (*model.RoomGroup, error) {
    method Last (line 319) | func (r roomGroupDo) Last() (*model.RoomGroup, error) {
    method Find (line 327) | func (r roomGroupDo) Find() ([]*model.RoomGroup, error) {
    method FindInBatch (line 332) | func (r roomGroupDo) FindInBatch(batchSize int, fc func(tx gen.Dao, ba...
    method FindInBatches (line 341) | func (r roomGroupDo) FindInBatches(result *[]*model.RoomGroup, batchSi...
    method Attrs (line 345) | func (r roomGroupDo) Attrs(attrs ...field.AssignExpr) IRoomGroupDo {
    method Assign (line 349) | func (r roomGroupDo) Assign(attrs ...field.AssignExpr) IRoomGroupDo {
    method Joins (line 353) | func (r roomGroupDo) Joins(fields ...field.RelationField) IRoomGroupDo {
    method Preload (line 360) | func (r roomGroupDo) Preload(fields ...field.RelationField) IRoomGroup...
    method FirstOrInit (line 367) | func (r roomGroupDo) FirstOrInit() (*model.RoomGroup, error) {
    method FirstOrCreate (line 375) | func (r roomGroupDo) FirstOrCreate() (*model.RoomGroup, error) {
    method FindByPage (line 383) | func (r roomGroupDo) FindByPage(offset int, limit int) (result []*mode...
    method ScanByPage (line 398) | func (r roomGroupDo) ScanByPage(result interface{}, offset int, limit ...
    method Scan (line 408) | func (r roomGroupDo) Scan(result interface{}) (err error) {
    method Delete (line 412) | func (r roomGroupDo) Delete(models ...*model.RoomGroup) (result gen.Re...
    method withDO (line 416) | func (r *roomGroupDo) withDO(do gen.Dao) *roomGroupDo {
  type IRoomGroupDo (line 130) | type IRoomGroupDo interface

FILE: dal/query/user.gen.go
  function newUser (line 22) | func newUser(db *gorm.DB, opts ...gen.DOOption) user {
  type user (line 50) | type user struct
    method Table (line 71) | func (u user) Table(newTableName string) *user {
    method As (line 76) | func (u user) As(alias string) *user {
    method updateTableName (line 81) | func (u *user) updateTableName(table string) *user {
    method WithContext (line 102) | func (u *user) WithContext(ctx context.Context) IUserDo { return u.use...
    method TableName (line 104) | func (u user) TableName() string { return u.userDo.TableName() }
    method Alias (line 106) | func (u user) Alias() string { return u.userDo.Alias() }
    method Columns (line 108) | func (u user) Columns(cols ...field.Expr) gen.Columns { return u.userD...
    method GetFieldByName (line 110) | func (u *user) GetFieldByName(fieldName string) (field.OrderExpr, bool) {
    method fillFieldMap (line 119) | func (u *user) fillFieldMap() {
    method clone (line 136) | func (u user) clone(db *gorm.DB) user {
    method replaceDB (line 141) | func (u user) replaceDB(db *gorm.DB) user {
  type userDo (line 146) | type userDo struct
    method Debug (line 209) | func (u userDo) Debug() IUserDo {
    method WithContext (line 213) | func (u userDo) WithContext(ctx context.Context) IUserDo {
    method ReadDB (line 217) | func (u userDo) ReadDB() IUserDo {
    method WriteDB (line 221) | func (u userDo) WriteDB() IUserDo {
    method Session (line 225) | func (u userDo) Session(config *gorm.Session) IUserDo {
    method Clauses (line 229) | func (u userDo) Clauses(conds ...clause.Expression) IUserDo {
    method Returning (line 233) | func (u userDo) Returning(value interface{}, columns ...string) IUserDo {
    method Not (line 237) | func (u userDo) Not(conds ...gen.Condition) IUserDo {
    method Or (line 241) | func (u userDo) Or(conds ...gen.Condition) IUserDo {
    method Select (line 245) | func (u userDo) Select(conds ...field.Expr) IUserDo {
    method Where (line 249) | func (u userDo) Where(conds ...gen.Condition) IUserDo {
    method Order (line 253) | func (u userDo) Order(conds ...field.Expr) IUserDo {
    method Distinct (line 257) | func (u userDo) Distinct(cols ...field.Expr) IUserDo {
    method Omit (line 261) | func (u userDo) Omit(cols ...field.Expr) IUserDo {
    method Join (line 265) | func (u userDo) Join(table schema.Tabler, on ...field.Expr) IUserDo {
    method LeftJoin (line 269) | func (u userDo) LeftJoin(table schema.Tabler, on ...field.Expr) IUserDo {
    method RightJoin (line 273) | func (u userDo) RightJoin(table schema.Tabler, on ...field.Expr) IUser...
    method Group (line 277) | func (u userDo) Group(cols ...field.Expr) IUserDo {
    method Having (line 281) | func (u userDo) Having(conds ...gen.Condition) IUserDo {
    method Limit (line 285) | func (u userDo) Limit(limit int) IUserDo {
    method Offset (line 289) | func (u userDo) Offset(offset int) IUserDo {
    method Scopes (line 293) | func (u userDo) Scopes(funcs ...func(gen.Dao) gen.Dao) IUserDo {
    method Unscoped (line 297) | func (u userDo) Unscoped() IUserDo {
    method Create (line 301) | func (u userDo) Create(values ...*model.User) error {
    method CreateInBatches (line 308) | func (u userDo) CreateInBatches(values []*model.User, batchSize int) e...
    method Save (line 314) | func (u userDo) Save(values ...*model.User) error {
    method First (line 321) | func (u userDo) First() (*model.User, error) {
    method Take (line 329) | func (u userDo) Take() (*model.User, error) {
    method Last (line 337) | func (u userDo) Last() (*model.User, error) {
    method Find (line 345) | func (u userDo) Find() ([]*model.User, error) {
    method FindInBatch (line 350) | func (u userDo) FindInBatch(batchSize int, fc func(tx gen.Dao, batch i...
    method FindInBatches (line 359) | func (u userDo) FindInBatches(result *[]*model.User, batchSize int, fc...
    method Attrs (line 363) | func (u userDo) Attrs(attrs ...field.AssignExpr) IUserDo {
    method Assign (line 367) | func (u userDo) Assign(attrs ...field.AssignExpr) IUserDo {
    method Joins (line 371) | func (u userDo) Joins(fields ...field.RelationField) IUserDo {
    method Preload (line 378) | func (u userDo) Preload(fields ...field.RelationField) IUserDo {
    method FirstOrInit (line 385) | func (u userDo) FirstOrInit() (*model.User, error) {
    method FirstOrCreate (line 393) | func (u userDo) FirstOrCreate() (*model.User, error) {
    method FindByPage (line 401) | func (u userDo) FindByPage(offset int, limit int) (result []*model.Use...
    method ScanByPage (line 416) | func (u userDo) ScanByPage(result interface{}, offset int, limit int) ...
    method Scan (line 426) | func (u userDo) Scan(result interface{}) (err error) {
    method Delete (line 430) | func (u userDo) Delete(models ...*model.User) (result gen.ResultInfo, ...
    method withDO (line 434) | func (u *userDo) withDO(do gen.Dao) *userDo {
  type IUserDo (line 148) | type IUserDo interface

FILE: dal/query/user_apply.gen.go
  function newUserApply (line 22) | func newUserApply(db *gorm.DB, opts ...gen.DOOption) userApply {
  type userApply (line 46) | type userApply struct
    method Table (line 63) | func (u userApply) Table(newTableName string) *userApply {
    method As (line 68) | func (u userApply) As(alias string) *userApply {
    method updateTableName (line 73) | func (u *userApply) updateTableName(table string) *userApply {
    method WithContext (line 90) | func (u *userApply) WithContext(ctx context.Context) IUserApplyDo {
    method TableName (line 94) | func (u userApply) TableName() string { return u.userApplyDo.TableName...
    method Alias (line 96) | func (u userApply) Alias() string { return u.userApplyDo.Alias() }
    method Columns (line 98) | func (u userApply) Columns(cols ...field.Expr) gen.Columns { return u....
    method GetFieldByName (line 100) | func (u *userApply) GetFieldByName(fieldName string) (field.OrderExpr,...
    method fillFieldMap (line 109) | func (u *userApply) fillFieldMap() {
    method clone (line 122) | func (u userApply) clone(db *gorm.DB) userApply {
    method replaceDB (line 127) | func (u userApply) replaceDB(db *gorm.DB) userApply {
  type userApplyDo (line 132) | type userApplyDo struct
    method Debug (line 195) | func (u userApplyDo) Debug() IUserApplyDo {
    method WithContext (line 199) | func (u userApplyDo) WithContext(ctx context.Context) IUserApplyDo {
    method ReadDB (line 203) | func (u userApplyDo) ReadDB() IUserApplyDo {
    method WriteDB (line 207) | func (u userApplyDo) WriteDB() IUserApplyDo {
    method Session (line 211) | func (u userApplyDo) Session(config *gorm.Session) IUserApplyDo {
    method Clauses (line 215) | func (u userApplyDo) Clauses(conds ...clause.Expression) IUserApplyDo {
    method Returning (line 219) | func (u userApplyDo) Returning(value interface{}, columns ...string) I...
    method Not (line 223) | func (u userApplyDo) Not(conds ...gen.Condition) IUserApplyDo {
    method Or (line 227) | func (u userApplyDo) Or(conds ...gen.Condition) IUserApplyDo {
    method Select (line 231) | func (u userApplyDo) Select(conds ...field.Expr) IUserApplyDo {
    method Where (line 235) | func (u userApplyDo) Where(conds ...gen.Condition) IUserApplyDo {
    method Order (line 239) | func (u userApplyDo) Order(conds ...field.Expr) IUserApplyDo {
    method Distinct (line 243) | func (u userApplyDo) Distinct(cols ...field.Expr) IUserApplyDo {
    method Omit (line 247) | func (u userApplyDo) Omit(cols ...field.Expr) IUserApplyDo {
    method Join (line 251) | func (u userApplyDo) Join(table schema.Tabler, on ...field.Expr) IUser...
    method LeftJoin (line 255) | func (u userApplyDo) LeftJoin(table schema.Tabler, on ...field.Expr) I...
    method RightJoin (line 259) | func (u userApplyDo) RightJoin(table schema.Tabler, on ...field.Expr) ...
    method Group (line 263) | func (u userApplyDo) Group(cols ...field.Expr) IUserApplyDo {
    method Having (line 267) | func (u userApplyDo) Having(conds ...gen.Condition) IUserApplyDo {
    method Limit (line 271) | func (u userApplyDo) Limit(limit int) IUserApplyDo {
    method Offset (line 275) | func (u userApplyDo) Offset(offset int) IUserApplyDo {
    method Scopes (line 279) | func (u userApplyDo) Scopes(funcs ...func(gen.Dao) gen.Dao) IUserApply...
    method Unscoped (line 283) | func (u userApplyDo) Unscoped() IUserApplyDo {
    method Create (line 287) | func (u userApplyDo) Create(values ...*model.UserApply) error {
    method CreateInBatches (line 294) | func (u userApplyDo) CreateInBatches(values []*model.UserApply, batchS...
    method Save (line 300) | func (u userApplyDo) Save(values ...*model.UserApply) error {
    method First (line 307) | func (u userApplyDo) First() (*model.UserApply, error) {
    method Take (line 315) | func (u userApplyDo) Take() (*model.UserApply, error) {
    method Last (line 323) | func (u userApplyDo) Last() (*model.UserApply, error) {
    method Find (line 331) | func (u userApplyDo) Find() ([]*model.UserApply, error) {
    method FindInBatch (line 336) | func (u userApplyDo) FindInBatch(batchSize int, fc func(tx gen.Dao, ba...
    method FindInBatches (line 345) | func (u userApplyDo) FindInBatches(result *[]*model.UserApply, batchSi...
    method Attrs (line 349) | func (u userApplyDo) Attrs(attrs ...field.AssignExpr) IUserApplyDo {
    method Assign (line 353) | func (u userApplyDo) Assign(attrs ...field.AssignExpr) IUserApplyDo {
    method Joins (line 357) | func (u userApplyDo) Joins(fields ...field.RelationField) IUserApplyDo {
    method Preload (line 364) | func (u userApplyDo) Preload(fields ...field.RelationField) IUserApply...
    method FirstOrInit (line 371) | func (u userApplyDo) FirstOrInit() (*model.UserApply, error) {
    method FirstOrCreate (line 379) | func (u userApplyDo) FirstOrCreate() (*model.UserApply, error) {
    method FindByPage (line 387) | func (u userApplyDo) FindByPage(offset int, limit int) (result []*mode...
    method ScanByPage (line 402) | func (u userApplyDo) ScanByPage(result interface{}, offset int, limit ...
    method Scan (line 412) | func (u userApplyDo) Scan(result interface{}) (err error) {
    method Delete (line 416) | func (u userApplyDo) Delete(models ...*model.UserApply) (result gen.Re...
    method withDO (line 420) | func (u *userApplyDo) withDO(do gen.Dao) *userApplyDo {
  type IUserApplyDo (line 134) | type IUserApplyDo interface

FILE: dal/query/user_friend.gen.go
  function newUserFriend (line 22) | func newUserFriend(db *gorm.DB, opts ...gen.DOOption) userFriend {
  type userFriend (line 43) | type userFriend struct
    method Table (line 57) | func (u userFriend) Table(newTableName string) *userFriend {
    method As (line 62) | func (u userFriend) As(alias string) *userFriend {
    method updateTableName (line 67) | func (u *userFriend) updateTableName(table string) *userFriend {
    method WithContext (line 81) | func (u *userFriend) WithContext(ctx context.Context) IUserFriendDo {
    method TableName (line 85) | func (u userFriend) TableName() string { return u.userFriendDo.TableNa...
    method Alias (line 87) | func (u userFriend) Alias() string { return u.userFriendDo.Alias() }
    method Columns (line 89) | func (u userFriend) Columns(cols ...field.Expr) gen.Columns { return u...
    method GetFieldByName (line 91) | func (u *userFriend) GetFieldByName(fieldName string) (field.OrderExpr...
    method fillFieldMap (line 100) | func (u *userFriend) fillFieldMap() {
    method clone (line 110) | func (u userFriend) clone(db *gorm.DB) userFriend {
    method replaceDB (line 115) | func (u userFriend) replaceDB(db *gorm.DB) userFriend {
  type userFriendDo (line 120) | type userFriendDo struct
    method Debug (line 183) | func (u userFriendDo) Debug() IUserFriendDo {
    method WithContext (line 187) | func (u userFriendDo) WithContext(ctx context.Context) IUserFriendDo {
    method ReadDB (line 191) | func (u userFriendDo) ReadDB() IUserFriendDo {
    method WriteDB (line 195) | func (u userFriendDo) WriteDB() IUserFriendDo {
    method Session (line 199) | func (u userFriendDo) Session(config *gorm.Session) IUserFriendDo {
    method Clauses (line 203) | func (u userFriendDo) Clauses(conds ...clause.Expression) IUserFriendDo {
    method Returning (line 207) | func (u userFriendDo) Returning(value interface{}, columns ...string) ...
    method Not (line 211) | func (u userFriendDo) Not(conds ...gen.Condition) IUserFriendDo {
    method Or (line 215) | func (u userFriendDo) Or(conds ...gen.Condition) IUserFriendDo {
    method Select (line 219) | func (u userFriendDo) Select(conds ...field.Expr) IUserFriendDo {
    method Where (line 223) | func (u userFriendDo) Where(conds ...gen.Condition) IUserFriendDo {
    method Order (line 227) | func (u userFriendDo) Order(conds ...field.Expr) IUserFriendDo {
    method Distinct (line 231) | func (u userFriendDo) Distinct(cols ...field.Expr) IUserFriendDo {
    method Omit (line 235) | func (u userFriendDo) Omit(cols ...field.Expr) IUserFriendDo {
    method Join (line 239) | func (u userFriendDo) Join(table schema.Tabler, on ...field.Expr) IUse...
    method LeftJoin (line 243) | func (u userFriendDo) LeftJoin(table schema.Tabler, on ...field.Expr) ...
    method RightJoin (line 247) | func (u userFriendDo) RightJoin(table schema.Tabler, on ...field.Expr)...
    method Group (line 251) | func (u userFriendDo) Group(cols ...field.Expr) IUserFriendDo {
    method Having (line 255) | func (u userFriendDo) Having(conds ...gen.Condition) IUserFriendDo {
    method Limit (line 259) | func (u userFriendDo) Limit(limit int) IUserFriendDo {
    method Offset (line 263) | func (u userFriendDo) Offset(offset int) IUserFriendDo {
    method Scopes (line 267) | func (u userFriendDo) Scopes(funcs ...func(gen.Dao) gen.Dao) IUserFrie...
    method Unscoped (line 271) | func (u userFriendDo) Unscoped() IUserFriendDo {
    method Create (line 275) | func (u userFriendDo) Create(values ...*model.UserFriend) error {
    method CreateInBatches (line 282) | func (u userFriendDo) CreateInBatches(values []*model.UserFriend, batc...
    method Save (line 288) | func (u userFriendDo) Save(values ...*model.UserFriend) error {
    method First (line 295) | func (u userFriendDo) First() (*model.UserFriend, error) {
    method Take (line 303) | func (u userFriendDo) Take() (*model.UserFriend, error) {
    method Last (line 311) | func (u userFriendDo) Last() (*model.UserFriend, error) {
    method Find (line 319) | func (u userFriendDo) Find() ([]*model.UserFriend, error) {
    method FindInBatch (line 324) | func (u userFriendDo) FindInBatch(batchSize int, fc func(tx gen.Dao, b...
    method FindInBatches (line 333) | func (u userFriendDo) FindInBatches(result *[]*model.UserFriend, batch...
    method Attrs (line 337) | func (u userFriendDo) Attrs(attrs ...field.AssignExpr) IUserFriendDo {
    method Assign (line 341) | func (u userFriendDo) Assign(attrs ...field.AssignExpr) IUserFriendDo {
    method Joins (line 345) | func (u userFriendDo) Joins(fields ...field.RelationField) IUserFriend...
    method Preload (line 352) | func (u userFriendDo) Preload(fields ...field.RelationField) IUserFrie...
    method FirstOrInit (line 359) | func (u userFriendDo) FirstOrInit() (*model.UserFriend, error) {
    method FirstOrCreate (line 367) | func (u userFriendDo) FirstOrCreate() (*model.UserFriend, error) {
    method FindByPage (line 375) | func (u userFriendDo) FindByPage(offset int, limit int) (result []*mod...
    method ScanByPage (line 390) | func (u userFriendDo) ScanByPage(result interface{}, offset int, limit...
    method Scan (line 400) | func (u userFriendDo) Scan(result interface{}) (err error) {
    method Delete (line 404) | func (u userFriendDo) Delete(models ...*model.UserFriend) (result gen....
    method withDO (line 408) | func (u *userFriendDo) withDO(do gen.Dao) *userFriendDo {
  type IUserFriendDo (line 122) | type IUserFriendDo interface

FILE: docs/docs.go
  constant docTemplate (line 7) | docTemplate = `{
  function init (line 294) | func init() {

FILE: domain/dto/contact_dto.go
  type ContactDto (line 3) | type ContactDto struct

FILE: domain/dto/delete_friend_dto.go
  type DeleteFriendDto (line 3) | type DeleteFriendDto struct

FILE: domain/dto/group_dto.go
  type GetGroupMemberDto (line 5) | type GetGroupMemberDto struct

FILE: domain/dto/msg_dto.go
  type MessageBaseDto (line 3) | type MessageBaseDto struct
  type ImgMessageDto (line 12) | type ImgMessageDto struct

FILE: domain/enum/event_bus.go
  constant FriendApplyEvent (line 4) | FriendApplyEvent = "main:FriendApplyEvent"
  constant FriendNewEvent (line 5) | FriendNewEvent   = "main:FriendNewEvent"
  constant NewMessageEvent (line 6) | NewMessageEvent  = "main:NewMessageEvent"

FILE: domain/enum/login.go
  constant LoginByPassword (line 4) | LoginByPassword     = 1
  constant LoginByPhoneCaptcha (line 5) | LoginByPhoneCaptcha = 2

FILE: domain/enum/message.go
  constant TextMessage (line 4) | TextMessage = 1
  constant TextMessageType (line 8) | TextMessageType = 1
  constant ImgMessageType (line 9) | ImgMessageType  = 3

FILE: domain/enum/redis.go
  constant Project (line 6) | Project    = "diting:"
  constant User (line 7) | User       = Project + "User"
  constant UserFriend (line 8) | UserFriend = Project + "userFriend:"
  constant UserApply (line 9) | UserApply  = Project + "userApply:"
  constant RoomFriend (line 10) | RoomFriend = Project + "roomFriend:"
  constant Contact (line 11) | Contact    = Project + "contact:"
  constant Room (line 12) | Room       = Project + "room:"
  constant RoomCacheByID (line 16) | RoomCacheByID = Room + "%d"
  constant RoomFriendCacheByRoomID (line 19) | RoomFriendCacheByRoomID          = RoomFriend + "%d"
  constant RoomFriendCacheByUidAndFriendUid (line 20) | RoomFriendCacheByUidAndFriendUid = RoomFriend + "%d_%d"
  constant PhoneUidMap (line 23) | PhoneUidMap      = User + "PhoneUid:" + "%s"
  constant UserCacheByID (line 24) | UserCacheByID    = User + "%d"
  constant UserCacheByName (line 25) | UserCacheByName  = User + "%s"
  constant UserCacheByPhone (line 26) | UserCacheByPhone = User + "Phone:" + "%s"
  constant UserCaptcha (line 27) | UserCaptcha      = User + "Captcha:" + "%s"
  constant UserFriendCacheByUidAndFriendUid (line 30) | UserFriendCacheByUidAndFriendUid = UserFriend + "%d_%d"
  constant UserApplyCacheByUidAndFriendUid (line 33) | UserApplyCacheByUidAndFriendUid = UserApply + "%d_%d"
  constant ContactCacheById (line 36) | ContactCacheById = Contact + "%d"
  constant DefaultCacheTime (line 40) | DefaultCacheTime = 7 * 24 * time.Hour
  constant NotExpireTime (line 41) | NotExpireTime    = 10 * 365 * 24 * time.Hour

FILE: domain/enum/redsync.go
  constant Lock (line 4) | Lock              = "lock:"
  constant UserLock (line 5) | UserLock          = Lock + "diting-user:"
  constant UserAndFriendLock (line 6) | UserAndFriendLock = UserLock + "%d_%d"

FILE: domain/enum/rocketmq.go
  constant UserLoginTopic (line 4) | UserLoginTopic    = "diting-login"
  constant NewFriendTopic (line 5) | NewFriendTopic    = "diting-new-friend"
  constant NewMessageTopic (line 6) | NewMessageTopic   = "diting-new-message"
  constant DeleteFriendTopic (line 7) | DeleteFriendTopic = "diting-delete-friend"
  constant FriendApplyTopic (line 8) | FriendApplyTopic  = "diting-friend-apply"

FILE: domain/enum/room.go
  constant HOT (line 5) | HOT    = 1
  constant NORMAL (line 6) | NORMAL = 0
  constant GROUP (line 8) | GROUP    = 1
  constant PERSONAL (line 9) | PERSONAL = 2

FILE: domain/enum/user.go
  constant UserStatusNormal (line 4) | UserStatusNormal = 1
  constant UserStatusCancel (line 5) | UserStatusCancel = 2

FILE: domain/model/message.go
  type Message (line 8) | type Message
    method GetContactMsg (line 10) | func (msg Message) GetContactMsg() string {

FILE: domain/vo/req/agree_friend_req.go
  type AgreeFriendReq (line 3) | type AgreeFriendReq struct

FILE: domain/vo/req/captcha_req.go
  type CaptchaReq (line 3) | type CaptchaReq struct

FILE: domain/vo/req/create_group_req.go
  type CreateGroupReq (line 3) | type CreateGroupReq struct

FILE: domain/vo/req/delete_friend_req.go
  type DeleteFriendReq (line 3) | type DeleteFriendReq struct

FILE: domain/vo/req/delete_group_req.go
  type DeleteGroupReq (line 3) | type DeleteGroupReq struct

FILE: domain/vo/req/get_group_member_list_req.go
  type GetGroupMemberListReq (line 3) | type GetGroupMemberListReq struct

FILE: domain/vo/req/get_message_list_req.go
  type GetMessageListReq (line 3) | type GetMessageListReq struct

FILE: domain/vo/req/get_new_content_list_req.go
  type GetNewContentListReq (line 3) | type GetNewContentListReq struct

FILE: domain/vo/req/get_new_msg_list_req.go
  type GetNewMsgListReq (line 3) | type GetNewMsgListReq struct

FILE: domain/vo/req/get_user_info_batch_req.go
  type UserInfoBatchReqItem (line 3) | type UserInfoBatchReqItem struct
  type GetUserInfoBatchReq (line 7) | type GetUserInfoBatchReq struct

FILE: domain/vo/req/get_user_info_by_name_req.go
  type GetUserInfoByNameReq (line 3) | type GetUserInfoByNameReq struct

FILE: domain/vo/req/grant_administrator_req.go
  type GrantAdministratorReq (line 3) | type GrantAdministratorReq struct

FILE: domain/vo/req/is_friend_req.go
  type IsFriendReq (line 4) | type IsFriendReq struct

FILE: domain/vo/req/join_group_req.go
  type JoinGroupReq (line 3) | type JoinGroupReq struct

FILE: domain/vo/req/message_req.go
  type MessageBody (line 3) | type MessageBody struct
  type MessageReq (line 7) | type MessageReq struct

FILE: domain/vo/req/quit_group_req.go
  type QuitGroupReq (line 3) | type QuitGroupReq struct

FILE: domain/vo/req/remove_administrator_req.go
  type RemoveAdministratorReq (line 3) | type RemoveAdministratorReq struct

FILE: domain/vo/req/uid_req.go
  type UidReq (line 3) | type UidReq struct

FILE: domain/vo/req/user_apply_req.go
  type UserApplyReq (line 3) | type UserApplyReq struct

FILE: domain/vo/req/user_cancle_req.go
  type UserCancelReq (line 3) | type UserCancelReq struct

FILE: domain/vo/req/user_login_req.go
  type UserLoginReq (line 3) | type UserLoginReq struct

FILE: domain/vo/req/user_register_req.go
  type UserRegisterReq (line 3) | type UserRegisterReq struct

FILE: domain/vo/resp/get_user_info_batch_resp.go
  type GetUserInfoBatchResp (line 3) | type GetUserInfoBatchResp struct

FILE: domain/vo/resp/get_user_info_by_name_resp.go
  type GetUserInfoByNameResp (line 3) | type GetUserInfoByNameResp struct

FILE: domain/vo/resp/message_resp.go
  type MsgUser (line 3) | type MsgUser struct
  type Msg (line 8) | type Msg struct
  type TextBody (line 14) | type TextBody struct
  type MessageResp (line 18) | type MessageResp struct

FILE: domain/vo/resp/page_list_resp.go
  type PageListResp (line 3) | type PageListResp struct

FILE: domain/vo/resp/pre_signed_resp.go
  type PreSignedResp (line 3) | type PreSignedResp struct

FILE: domain/vo/resp/user_apply_resp.go
  type UserApplyResp (line 3) | type UserApplyResp struct

FILE: domain/vo/resp/user_contact_resp.go
  type UserContactResp (line 3) | type UserContactResp struct

FILE: domain/vo/resp/user_login_resp.go
  type UserLoginResp (line 3) | type UserLoginResp struct

FILE: event/listener/friend_apply_event.go
  function init (line 15) | func init() {
  function friendApplyEvent (line 35) | func friendApplyEvent(ctx context.Context, ext ...*primitive.MessageExt)...
  function friendApply (line 52) | func friendApply(apply model.UserApply) error {

FILE: event/listener/friend_delete_event.go
  function init (line 22) | func init() {
  function deleteFriendEvent (line 41) | func deleteFriendEvent(ctx context.Context, ext ...*primitive.MessageExt...
  function deleteFriend (line 58) | func deleteFriend(deleteFriendDto dto.DeleteFriendDto) error {

FILE: event/listener/friend_new_event.go
  function init (line 25) | func init() {
  function friendNewEvent (line 44) | func friendNewEvent(ctx context.Context, ext ...*primitive.MessageExt) (...
  function friendNew (line 64) | func friendNew(userFriend model.UserFriend) error {

FILE: event/listener/new_msg_event.go
  function init (line 22) | func init() {
  function UpdateContactEvent (line 57) | func UpdateContactEvent(ctx context.Context, ext ...*primitive.MessageEx...
  function updateContact (line 80) | func updateContact(msg model.Message) error {
  function SendMsgEvent (line 133) | func SendMsgEvent(ctx context.Context, ext ...*primitive.MessageExt) (co...
  function sendMsg (line 153) | func sendMsg(msg model.Message) error {

FILE: event/listener/user_login_event.go
  function init (line 14) | func init() {
  function test (line 27) | func test(rocketConsumer rocketmq.PushConsumer) {

FILE: global/init_db.go
  function DBInit (line 13) | func DBInit() {

FILE: global/init_log.go
  function LogInit (line 13) | func LogInit() {

FILE: global/init_redis.go
  function RedisInit (line 10) | func RedisInit() {

FILE: logic/captcha.go
  function CheckCaptcha (line 13) | func CheckCaptcha(captchaId, captchaValue string) bool {
  function GenerateCaptcha (line 38) | func GenerateCaptcha(captchaId string) (string, error) {
  function SendCaptcha (line 53) | func SendCaptcha(phone, captcha string) error {

FILE: logic/login.go
  function CheckPassword (line 17) | func CheckPassword(ctx context.Context, phone, password string) bool {
  function SetUserInfo2Redis (line 82) | func SetUserInfo2Redis(userInfo model.User) error {
  function GetUserInfo2Redis (line 95) | func GetUserInfo2Redis(userId string) (model.User, error) {
  function GetUserInfo2DB (line 118) | func GetUserInfo2DB(phone string) (model.User, error) {
  function GetUserInfo2DBById (line 134) | func GetUserInfo2DBById(ctx context.Context, userId string) (model.User,...

FILE: logic/register.go
  function CheckCaptchaProcess (line 16) | func CheckCaptchaProcess(phone, captcha string) bool {
  function CheckCaptchaExist (line 27) | func CheckCaptchaExist(phone string) bool {
  function CheckPhoneInRedis (line 44) | func CheckPhoneInRedis(phone string) bool {
  function CheckPhoneInDB (line 64) | func CheckPhoneInDB(ctx context.Context, phone string) (bool, error) {

FILE: logic/user.go
  function CreateUser (line 14) | func CreateUser(ctx context.Context, userInfo model.User) error {

FILE: logic/user_cancle.go
  function DeleteUserInfoFromRedis (line 13) | func DeleteUserInfoFromRedis(userId string) error {
  function DeleteUserInfoFromDB (line 22) | func DeleteUserInfoFromDB(ctx context.Context, userId string) error {

FILE: main.go
  function main (line 14) | func main() {

FILE: pkg/domain/enum/code.go
  constant SUCCESS (line 4) | SUCCESS        = 200
  constant ERROR (line 5) | ERROR          = 500
  constant INVALID_PARAMS (line 6) | INVALID_PARAMS = 400
  constant ERROR_EXIST_TAG (line 8) | ERROR_EXIST_TAG         = 10001
  constant ERROR_NOT_EXIST_TAG (line 9) | ERROR_NOT_EXIST_TAG     = 10002
  constant ERROR_NOT_EXIST_ARTICLE (line 10) | ERROR_NOT_EXIST_ARTICLE = 10003
  constant ERROR_AUTH_CHECK_TOKEN_FAIL (line 12) | ERROR_AUTH_CHECK_TOKEN_FAIL    = 20001
  constant ERROR_AUTH_CHECK_TOKEN_TIMEOUT (line 13) | ERROR_AUTH_CHECK_TOKEN_TIMEOUT = 20002
  constant ERROR_AUTH_TOKEN (line 14) | ERROR_AUTH_TOKEN               = 20003
  constant ERROR_AUTH (line 15) | ERROR_AUTH                     = 20004

FILE: pkg/domain/enum/common_enum.go
  constant YES (line 4) | YES     = 2
  constant NO (line 5) | NO      = 1
  constant NORMAL (line 6) | NORMAL  = 1
  constant DELETED (line 7) | DELETED = 2

FILE: pkg/domain/enum/msg.go
  function GetMsg (line 13) | func GetMsg(code int) string {

FILE: pkg/domain/vo/req/page_req.go
  type PageReq (line 3) | type PageReq struct

FILE: pkg/domain/vo/resp/page_resp.go
  type PageResp (line 3) | type PageResp struct

FILE: pkg/domain/vo/resp/response.go
  type ResponseData (line 9) | type ResponseData struct
  function ErrorResponse (line 22) | func ErrorResponse(c *gin.Context, message string) {
  function SuccessResponse (line 37) | func SuccessResponse(c *gin.Context, data interface{}) {
  function SuccessResponseWithMsg (line 46) | func SuccessResponseWithMsg(c *gin.Context, msg string) {
  function ReturnSuccessResponse (line 54) | func ReturnSuccessResponse(c *gin.Context, response ResponseData) {
  function ReturnErrorResponse (line 57) | func ReturnErrorResponse(c *gin.Context, response ResponseData) {
  function ErrorResponseData (line 62) | func ErrorResponseData(msg string) ResponseData {
  function SuccessResponseData (line 72) | func SuccessResponseData(data interface{}) ResponseData {
  function SuccessResponseDataWithMsg (line 82) | func SuccessResponseDataWithMsg(msg string) ResponseData {

FILE: pkg/utils/cursor_utils.go
  function Paginate (line 16) | func Paginate(db *gorm.DB, params pkgReq.PageReq, result interface{}, cu...
  function GetTagName (line 73) | func GetTagName(structName interface{}) (map[string]string, error) {

FILE: pkg/utils/redis.go
  function SetString (line 13) | func SetString(key string, value any) error {
  function GetString (line 22) | func GetString(key string, value any) error {
  function GetData (line 37) | func GetData(cacheKey string, value any, dbQueryFunc func() (interface{}...
  function QueryAndSet (line 54) | func QueryAndSet(cacheKey string, value any, dbQueryFunc func() (interfa...
  function RemoveData (line 73) | func RemoveData(key string) {

FILE: pkg/utils/sort.go
  type Int64Slice (line 3) | type Int64Slice
    method Len (line 5) | func (p Int64Slice) Len() int {
    method Less (line 9) | func (p Int64Slice) Less(i, j int) bool {
    method Swap (line 13) | func (p Int64Slice) Swap(i, j int) {

FILE: routes/init_router.go
  function InitRouter (line 19) | func InitRouter() {
  function initWebSocket (line 25) | func initWebSocket() {
  function initGin (line 31) | func initGin() {
  function test (line 114) | func test(c *gin.Context) {

FILE: service/adapter/build_contact_dao_list.go
  type RoomDto (line 11) | type RoomDto struct
  function BuildContactDaoList (line 18) | func BuildContactDaoList(contactList []model.Contact, userList []*model....

FILE: service/adapter/build_message_resp.go
  function BuildMessageRespByMsgAndUser (line 8) | func BuildMessageRespByMsgAndUser(msgList *[]model.Message, userMap map[...

FILE: service/adapter/build_user_info_by_name_resp.go
  function BuildUserInfoByNameResp (line 8) | func BuildUserInfoByNameResp(userList []*model.User, userApply []*model....

FILE: service/captcha_service.go
  function CaptchaService (line 11) | func CaptchaService(captchaReq req.CaptchaReq) (pkgResp.ResponseData, er...

FILE: service/user_service.go
  function RegisterService (line 23) | func RegisterService(userReq req.UserRegisterReq) (pkgResp.ResponseData,...
  function validateRegisterRequest (line 56) | func validateRegisterRequest(userReq req.UserRegisterReq) error {
  function validateRegisterCaptcha (line 81) | func validateRegisterCaptcha(phone, captcha string) error {
  function checkUserExists (line 90) | func checkUserExists(ctx context.Context, phone string) (bool, error) {
  function createNewUser (line 113) | func createNewUser(ctx context.Context, userReq req.UserRegisterReq) err...
  function LoginService (line 149) | func LoginService(loginReq req.UserLoginReq) (pkgResp.ResponseData, erro...
  function validateLoginRequest (line 188) | func validateLoginRequest(loginReq req.UserLoginReq) error {
  function validateLoginCredentials (line 204) | func validateLoginCredentials(ctx context.Context, loginReq req.UserLogi...
  function getUserInfo (line 220) | func getUserInfo(phone string) (model.User, error) {
  function CancelService (line 263) | func CancelService(ctx *gin.Context, req req.UserCancelReq) (pkgResp.Res...

FILE: service/user_service_integration_test.go
  function TestUserRegistrationFlow (line 17) | func TestUserRegistrationFlow(t *testing.T) {
  function TestUserLoginFlow (line 50) | func TestUserLoginFlow(t *testing.T) {
  function TestUserCancelFlow (line 92) | func TestUserCancelFlow(t *testing.T) {
  function TestDuplicateRegistration (line 134) | func TestDuplicateRegistration(t *testing.T) {
  function TestLoginWithWrongCredentials (line 165) | func TestLoginWithWrongCredentials(t *testing.T) {
  function TestCancelWithWrongCaptcha (line 213) | func TestCancelWithWrongCaptcha(t *testing.T) {
  function TestUserRegistrationWithValidData (line 250) | func TestUserRegistrationWithValidData(t *testing.T) {
  function setupCaptcha (line 302) | func setupCaptcha(phone, captcha string) {
  function cleanupUser (line 311) | func cleanupUser(phone string) {

FILE: service/user_service_test.go
  function TestUserLifecycleFlow (line 13) | func TestUserLifecycleFlow(t *testing.T) {
  function TestRegisterValidation (line 78) | func TestRegisterValidation(t *testing.T) {
  function TestLoginValidation (line 117) | func TestLoginValidation(t *testing.T) {

FILE: sql/sql.sql
  type contact (line 2) | create table contact
  type idx_create_time (line 18) | create index idx_create_time
  type idx_room_id_read_time (line 21) | create index idx_room_id_read_time
  type idx_update_time (line 24) | create index idx_update_time
  type idx_user_id_active_time (line 27) | create index idx_user_id_active_time
  type group_member (line 31) | create table group_member
  type idx_create_time (line 43) | create index idx_create_time
  type idx_group_id_role (line 46) | create index idx_group_id_role
  type idx_update_time (line 49) | create index idx_update_time
  type message (line 53) | create table message
  type idx_create_time (line 71) | create index idx_create_time
  type idx_from_uid (line 74) | create index idx_from_uid
  type idx_room_id (line 77) | create index idx_room_id
  type idx_update_time (line 80) | create index idx_update_time
  type room (line 84) | create table room
  type idx_create_time (line 98) | create index idx_create_time
  type idx_update_time (line 101) | create index idx_update_time
  type room_friend (line 105) | create table room_friend
  type idx_create_time (line 121) | create index idx_create_time
  type idx_room_id (line 124) | create index idx_room_id
  type idx_update_time (line 127) | create index idx_update_time
  type room_group (line 131) | create table room_group
  type idx_create_time (line 145) | create index idx_create_time
  type idx_room_id (line 148) | create index idx_room_id
  type idx_update_time (line 151) | create index idx_update_time
  type user_friend (line 155) | create table user_friend
  type idx_create_time (line 169) | create index idx_create_time
  type idx_uid_friend_uid (line 172) | create index idx_uid_friend_uid
  type idx_update_time (line 175) | create index idx_update_time
  type user_apply (line 179) | create table user_apply
  type idx_create_time (line 196) | create index idx_create_time
  type idx_target_id (line 199) | create index idx_target_id
  type idx_target_id_read_status (line 202) | create index idx_target_id_read_status
  type idx_uid_target_id (line 205) | create index idx_uid_target_id
  type idx_update_time (line 208) | create index idx_update_time

FILE: tests/e2e/user_workflow_e2e_test.go
  function init (line 19) | func init() {
  function TestUserCompleteWorkflow (line 39) | func TestUserCompleteWorkflow(t *testing.T) {
  function TestMultipleUserWorkflow (line 128) | func TestMultipleUserWorkflow(t *testing.T) {
  function TestUserErrorScenarios (line 175) | func TestUserErrorScenarios(t *testing.T) {
  function setupCaptcha (line 239) | func setupCaptcha(phone, captcha string) {
  function cleanupUser (line 248) | func cleanupUser(phone string) {

FILE: tests/init_test.go
  function TestMain (line 11) | func TestMain(m *testing.M) {
  function cleanup (line 35) | func cleanup() {

FILE: tests/integration/user_integration_test.go
  function TestUserRegistrationFlow (line 18) | func TestUserRegistrationFlow(t *testing.T) {
  function TestUserLoginFlow (line 51) | func TestUserLoginFlow(t *testing.T) {
  function TestUserCancelFlow (line 93) | func TestUserCancelFlow(t *testing.T) {
  function TestDuplicateRegistration (line 135) | func TestDuplicateRegistration(t *testing.T) {
  function TestLoginWithWrongCredentials (line 166) | func TestLoginWithWrongCredentials(t *testing.T) {
  function TestCancelWithWrongCaptcha (line 214) | func TestCancelWithWrongCaptcha(t *testing.T) {
  function TestUserRegistrationWithValidData (line 251) | func TestUserRegistrationWithValidData(t *testing.T) {
  function setupCaptcha (line 303) | func setupCaptcha(phone, captcha string) {
  function cleanupUser (line 312) | func cleanupUser(phone string) {

FILE: tests/performance/user_performance_test.go
  function BenchmarkUserRegistration (line 17) | func BenchmarkUserRegistration(b *testing.B) {
  function BenchmarkUserLogin (line 48) | func BenchmarkUserLogin(b *testing.B) {
  function TestConcurrentUserRegistration (line 87) | func TestConcurrentUserRegistration(t *testing.T) {
  function TestConcurrentUserLogin (line 149) | func TestConcurrentUserLogin(t *testing.T) {
  function TestLoadTest (line 229) | func TestLoadTest(t *testing.T) {
  function setupCaptcha (line 280) | func setupCaptcha(phone, captcha string) {
  function cleanupUser (line 289) | func cleanupUser(phone string) {

FILE: tests/unit/user_service_test.go
  function init (line 22) | func init() {
  function TestRegisterValidation (line 42) | func TestRegisterValidation(t *testing.T) {
  function TestLoginValidation (line 107) | func TestLoginValidation(t *testing.T) {
  function TestCheckPassword (line 183) | func TestCheckPassword(t *testing.T) {
  function setupCaptcha (line 248) | func setupCaptcha(phone, captcha string) {
  function cleanupUser (line 257) | func cleanupUser(phone string) {

FILE: utils/jwt/jwt.go
  type JwtClaims (line 14) | type JwtClaims struct
  function GenerateToken (line 20) | func GenerateToken(uid int64) (string, error) {
  function ParseToken (line 42) | func ParseToken(tokenString string) (*JwtClaims, error) {

FILE: utils/jwt/jwt_test.go
  function TestGenerateToken (line 9) | func TestGenerateToken(t *testing.T) {
  function TestParseToken (line 51) | func TestParseToken(t *testing.T) {
  function TestGenerateAndParseToken (line 117) | func TestGenerateAndParseToken(t *testing.T) {
  function TestTokenExpiration (line 152) | func TestTokenExpiration(t *testing.T) {

FILE: utils/middleware/cors.go
  function Cors (line 9) | func Cors() gin.HandlerFunc {

FILE: utils/middleware/jwt.go
  function JWT (line 11) | func JWT() gin.HandlerFunc {

FILE: utils/middleware/log.go
  function LoggerToFile (line 11) | func LoggerToFile() gin.HandlerFunc {

FILE: utils/mysqlUtils.go
  function QueryUserByPhone (line 14) | func QueryUserByPhone(ctx context.Context, phone string) (*model.User, e...
  function QueryUserByID (line 29) | func QueryUserByID(ctx context.Context, userId string) (*model.User, err...

FILE: utils/passwordUtils.go
  function EncryptPassword (line 9) | func EncryptPassword(password string) string {

FILE: utils/redisCache/remove_cache.go
  function RemoveRoomCache (line 11) | func RemoveRoomCache(room model.Room) {
  function RemoveRoomFriend (line 16) | func RemoveRoomFriend(roomFriend model.RoomFriend) {
  function RemoveUserCache (line 22) | func RemoveUserCache(user model.User) {
  function RemoveUserFriend (line 28) | func RemoveUserFriend(uid, friendUid int64) {
  function RemoveUserApply (line 34) | func RemoveUserApply(uid, friendUid int64) {
  function RemoveContact (line 40) | func RemoveContact(contact model.Contact) {

FILE: utils/redisUtils.go
  function MakeUserPhoneKey (line 14) | func MakeUserPhoneKey(phone string) string {
  function MakeUserCaptchaKey (line 19) | func MakeUserCaptchaKey(phone string) string {
  function SetValueToRedis (line 24) | func SetValueToRedis(key string, value string, expireTime time.Duration)...
  function GetValueFromRedis (line 38) | func GetValueFromRedis(key string) (value []byte, err error) {
  function DeleteValueFromRedis (line 47) | func DeleteValueFromRedis(key string) error {

FILE: utils/setting/setting.go
  function ConfigInit (line 11) | func ConfigInit() {
  function findProjectRoot (line 64) | func findProjectRoot(currentDir string) string {

FILE: utils/time_utils.go
  function TimestampStrToTimeStr (line 9) | func TimestampStrToTimeStr(str *string) (*string, error) {

FILE: websocket/domain/enum/ws_type.go
  constant NewMessage (line 4) | NewMessage = 4

FILE: websocket/domain/vo/resp/new_message_resp.go
  type NewMessageResp (line 3) | type NewMessageResp struct

FILE: websocket/global/global.go
  type Channels (line 9) | type Channels struct
  type User (line 14) | type User struct
  type Msg (line 18) | type Msg struct

FILE: websocket/service/websocket_service.go
  function Connect (line 37) | func Connect(w http.ResponseWriter, r *http.Request) {
  function Send (line 89) | func Send(uid int64, value []byte) error {
  function disConnect (line 108) | func disConnect(user *global.User) {
  function parseJwt (line 127) | func parseJwt(r *http.Request) (*int64, error) {
  function heatBeat (line 146) | func heatBeat(user *global.User) {
Condensed preview — 147 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (492K chars).
[
  {
    "path": ".github/workflows/reademe-contributors.yml",
    "chars": 353,
    "preview": "on:\n  push:\n    branches:\n      - main\n\nname: Generate a list of contributors\n\njobs:\n  contrib-readme-en-job:\n    runs-o"
  },
  {
    "path": ".gitignore",
    "chars": 593,
    "preview": "# If you prefer the allow list template instead of the deny list, see community template:\n# https://github.com/github/gi"
  },
  {
    "path": "LICENSE",
    "chars": 11357,
    "preview": "                                 Apache License\n                           Version 2.0, January 2004\n                   "
  },
  {
    "path": "README.md",
    "chars": 4000,
    "preview": "<div align=center>\n<img src=\"./assets/logo.png\"  width=\"40%\"/>\n</div>\n\n![Static Badge](https://img.shields.io/badge/%E4%"
  },
  {
    "path": "cmd/gen/generate.go",
    "chars": 1333,
    "preview": "package main\n\n// gorm gen configure\n\nimport (\n\t_ \"DiTing-Go/pkg/setting\"\n\t\"fmt\"\n\t\"github.com/spf13/viper\"\n\t\"gorm.io/driv"
  },
  {
    "path": "conf/config_example.yml",
    "chars": 345,
    "preview": "mysql:\n  host: xxx.xxx.xxx.xx\n  port: 3306\n  username: diting\n  password: diting\njwt:\n  secret: diting\nlog:\n  log_file_p"
  },
  {
    "path": "controller/captcha_controller.go",
    "chars": 497,
    "preview": "package controller\n\nimport (\n\t\"DiTing-Go/domain/vo/req\"\n\t\"DiTing-Go/pkg/domain/vo/resp\"\n\t\"DiTing-Go/service\"\n\t\"github.co"
  },
  {
    "path": "controller/chat_controller.go",
    "chars": 605,
    "preview": "package controller\n\n//\n//import (\n//\t\"DiTing-Go/domain/vo/req\"\n//\t\"DiTing-Go/pkg/domain/vo/resp\"\n//\t\"DiTing-Go/service\"\n"
  },
  {
    "path": "controller/contact_controller.go",
    "chars": 2775,
    "preview": "package controller\n\n//\n//import (\n//\t\"DiTing-Go/domain/vo/req\"\n//\t\"DiTing-Go/global\"\n//\tpkgReq \"DiTing-Go/pkg/domain/vo/"
  },
  {
    "path": "controller/friend_controller.go",
    "chars": 5278,
    "preview": "package controller\n\n//\n//import (\n//\t\"DiTing-Go/domain/vo/req\"\n//\tpkgReq \"DiTing-Go/pkg/domain/vo/req\"\n//\t\"DiTing-Go/pkg"
  },
  {
    "path": "controller/user_controller.go",
    "chars": 2170,
    "preview": "package controller\n\nimport (\n\t\"DiTing-Go/domain/vo/req\"\n\t\"DiTing-Go/pkg/domain/vo/resp\"\n\t\"DiTing-Go/service\"\n\t\"github.co"
  },
  {
    "path": "dal/db.go",
    "chars": 435,
    "preview": "package dal\n\nimport (\n\t\"fmt\"\n\t\"gorm.io/driver/mysql\"\n\t\"gorm.io/gorm\"\n)\n\nvar DB *gorm.DB\n\n// ConnectDB 初始化数据库连接\nfunc Conn"
  },
  {
    "path": "dal/model/contact.gen.go",
    "chars": 1409,
    "preview": "// Code generated by gorm.io/gen. DO NOT EDIT.\n// Code generated by gorm.io/gen. DO NOT EDIT.\n// Code generated by gorm."
  },
  {
    "path": "dal/model/group_member.gen.go",
    "chars": 1163,
    "preview": "// Code generated by gorm.io/gen. DO NOT EDIT.\n// Code generated by gorm.io/gen. DO NOT EDIT.\n// Code generated by gorm."
  },
  {
    "path": "dal/model/message.gen.go",
    "chars": 1815,
    "preview": "// Code generated by gorm.io/gen. DO NOT EDIT.\n// Code generated by gorm.io/gen. DO NOT EDIT.\n// Code generated by gorm."
  },
  {
    "path": "dal/model/room.gen.go",
    "chars": 1786,
    "preview": "// Code generated by gorm.io/gen. DO NOT EDIT.\n// Code generated by gorm.io/gen. DO NOT EDIT.\n// Code generated by gorm."
  },
  {
    "path": "dal/model/room_friend.gen.go",
    "chars": 1468,
    "preview": "// Code generated by gorm.io/gen. DO NOT EDIT.\n// Code generated by gorm.io/gen. DO NOT EDIT.\n// Code generated by gorm."
  },
  {
    "path": "dal/model/room_group.gen.go",
    "chars": 1433,
    "preview": "// Code generated by gorm.io/gen. DO NOT EDIT.\n// Code generated by gorm.io/gen. DO NOT EDIT.\n// Code generated by gorm."
  },
  {
    "path": "dal/model/user.gen.go",
    "chars": 2157,
    "preview": "// Code generated by gorm.io/gen. DO NOT EDIT.\n// Code generated by gorm.io/gen. DO NOT EDIT.\n// Code generated by gorm."
  },
  {
    "path": "dal/model/user_apply.gen.go",
    "chars": 1544,
    "preview": "// Code generated by gorm.io/gen. DO NOT EDIT.\n// Code generated by gorm.io/gen. DO NOT EDIT.\n// Code generated by gorm."
  },
  {
    "path": "dal/model/user_friend.gen.go",
    "chars": 1165,
    "preview": "// Code generated by gorm.io/gen. DO NOT EDIT.\n// Code generated by gorm.io/gen. DO NOT EDIT.\n// Code generated by gorm."
  },
  {
    "path": "dal/query/contact.gen.go",
    "chars": 12008,
    "preview": "// Code generated by gorm.io/gen. DO NOT EDIT.\n// Code generated by gorm.io/gen. DO NOT EDIT.\n// Code generated by gorm."
  },
  {
    "path": "dal/query/gen.go",
    "chars": 1843,
    "preview": "// Code generated by gorm.io/gen. DO NOT EDIT.\n// Code generated by gorm.io/gen. DO NOT EDIT.\n// Code generated by gorm."
  },
  {
    "path": "dal/query/group_member.gen.go",
    "chars": 12326,
    "preview": "// Code generated by gorm.io/gen. DO NOT EDIT.\n// Code generated by gorm.io/gen. DO NOT EDIT.\n// Code generated by gorm."
  },
  {
    "path": "dal/query/message.gen.go",
    "chars": 12577,
    "preview": "// Code generated by gorm.io/gen. DO NOT EDIT.\n// Code generated by gorm.io/gen. DO NOT EDIT.\n// Code generated by gorm."
  },
  {
    "path": "dal/query/room.gen.go",
    "chars": 11737,
    "preview": "// Code generated by gorm.io/gen. DO NOT EDIT.\n// Code generated by gorm.io/gen. DO NOT EDIT.\n// Code generated by gorm."
  },
  {
    "path": "dal/query/room_friend.gen.go",
    "chars": 12593,
    "preview": "// Code generated by gorm.io/gen. DO NOT EDIT.\n// Code generated by gorm.io/gen. DO NOT EDIT.\n// Code generated by gorm."
  },
  {
    "path": "dal/query/room_group.gen.go",
    "chars": 12396,
    "preview": "// Code generated by gorm.io/gen. DO NOT EDIT.\n// Code generated by gorm.io/gen. DO NOT EDIT.\n// Code generated by gorm."
  },
  {
    "path": "dal/query/user.gen.go",
    "chars": 12330,
    "preview": "// Code generated by gorm.io/gen. DO NOT EDIT.\n// Code generated by gorm.io/gen. DO NOT EDIT.\n// Code generated by gorm."
  },
  {
    "path": "dal/query/user_apply.gen.go",
    "chars": 12495,
    "preview": "// Code generated by gorm.io/gen. DO NOT EDIT.\n// Code generated by gorm.io/gen. DO NOT EDIT.\n// Code generated by gorm."
  },
  {
    "path": "dal/query/user_friend.gen.go",
    "chars": 12217,
    "preview": "// Code generated by gorm.io/gen. DO NOT EDIT.\n// Code generated by gorm.io/gen. DO NOT EDIT.\n// Code generated by gorm."
  },
  {
    "path": "docs/docs.go",
    "chars": 9236,
    "preview": "// Code generated by swaggo/swag. DO NOT EDIT.\n\npackage docs\n\nimport \"github.com/swaggo/swag\"\n\nconst docTemplate = `{\n  "
  },
  {
    "path": "docs/swagger.json",
    "chars": 8473,
    "preview": "{\n    \"swagger\": \"2.0\",\n    \"info\": {\n        \"contact\": {}\n    },\n    \"paths\": {\n        \"/api/contact/add\": {\n        "
  },
  {
    "path": "domain/dto/contact_dto.go",
    "chars": 366,
    "preview": "package dto\n\ntype ContactDto struct {\n\t// 会话ID\n\tID int64 `json:\"id\"`\n\t// 房间ID\n\tRoomID int64 `json:\"roomId\"`\n\t// 头像\n\tAvat"
  },
  {
    "path": "domain/dto/delete_friend_dto.go",
    "chars": 112,
    "preview": "package dto\n\ntype DeleteFriendDto struct {\n\tUid       int64 `json:\"uid\"`\n\tFriendUid int64 `json:\"friend_uid\"`\n}\n"
  },
  {
    "path": "domain/dto/group_dto.go",
    "chars": 291,
    "preview": "package dto\n\nimport \"time\"\n\ntype GetGroupMemberDto struct {\n\t// 用户ID\n\tUID int64 `json:\"uid\" gorm:\"column:id\"`\n\t// 用户名\n\tN"
  },
  {
    "path": "domain/dto/msg_dto.go",
    "chars": 308,
    "preview": "package dto\n\ntype MessageBaseDto struct {\n\t// 下载地址\n\tUrl string `json:\"url\"`\n\t// 文件大小\n\tSize int64 `json:\"size\"`\n\t// 文件名\n\t"
  },
  {
    "path": "domain/enum/event_bus.go",
    "chars": 153,
    "preview": "package enum\n\nconst (\n\tFriendApplyEvent = \"main:FriendApplyEvent\"\n\tFriendNewEvent   = \"main:FriendNewEvent\"\n\tNewMessageE"
  },
  {
    "path": "domain/enum/login.go",
    "chars": 97,
    "preview": "package enum\n\nconst (\n\tLoginByPassword     = 1 // 用户名密码登录\n\tLoginByPhoneCaptcha = 2 // 手机号验证码登录\n)\n"
  },
  {
    "path": "domain/enum/message.go",
    "chars": 94,
    "preview": "package enum\n\nconst (\n\tTextMessage = 1\n)\n\nconst (\n\tTextMessageType = 1\n\tImgMessageType  = 3\n)\n"
  },
  {
    "path": "domain/enum/redis.go",
    "chars": 936,
    "preview": "package enum\n\nimport \"time\"\n\nconst (\n\tProject    = \"diting:\"\n\tUser       = Project + \"User\"\n\tUserFriend = Project + \"use"
  },
  {
    "path": "domain/enum/redsync.go",
    "chars": 136,
    "preview": "package enum\n\nconst (\n\tLock              = \"lock:\"\n\tUserLock          = Lock + \"diting-user:\"\n\tUserAndFriendLock = UserL"
  },
  {
    "path": "domain/enum/rocketmq.go",
    "chars": 230,
    "preview": "package enum\n\nconst (\n\tUserLoginTopic    = \"diting-login\"\n\tNewFriendTopic    = \"diting-new-friend\"\n\tNewMessageTopic   = "
  },
  {
    "path": "domain/enum/room.go",
    "chars": 94,
    "preview": "package enum\n\nconst (\n\t// 房间状态\n\tHOT    = 1\n\tNORMAL = 0\n\t// 房间类型\n\tGROUP    = 1\n\tPERSONAL = 2\n)\n"
  },
  {
    "path": "domain/enum/user.go",
    "chars": 68,
    "preview": "package enum\n\nconst (\n\tUserStatusNormal = 1\n\tUserStatusCancel = 2\n)\n"
  },
  {
    "path": "domain/model/message.go",
    "chars": 293,
    "preview": "package model\n\nimport (\n\t\"DiTing-Go/dal/model\"\n\t\"DiTing-Go/domain/enum\"\n)\n\ntype Message model.Message\n\nfunc (msg Message"
  },
  {
    "path": "domain/vo/req/agree_friend_req.go",
    "chars": 87,
    "preview": "package req\n\ntype AgreeFriendReq struct {\n\tUid int64 `json:\"uid\" binding:\"required\"`\n}\n"
  },
  {
    "path": "domain/vo/req/captcha_req.go",
    "chars": 96,
    "preview": "package req\n\ntype CaptchaReq struct {\n\t// 手机号\n\tPhone string `json:\"phone\" binding:\"required\"`\n}\n"
  },
  {
    "path": "domain/vo/req/create_group_req.go",
    "chars": 97,
    "preview": "package req\n\ntype CreateGroupReq struct {\n\tUidList []int64 `json:\"uidList\" binding:\"required\"`\n}\n"
  },
  {
    "path": "domain/vo/req/delete_friend_req.go",
    "chars": 88,
    "preview": "package req\n\ntype DeleteFriendReq struct {\n\tUid int64 `json:\"uid\" binding:\"required\"`\n}\n"
  },
  {
    "path": "domain/vo/req/delete_group_req.go",
    "chars": 84,
    "preview": "package req\n\ntype DeleteGroupReq struct {\n\tID int64 `uri:\"id\" binding:\"required\"`\n}\n"
  },
  {
    "path": "domain/vo/req/get_group_member_list_req.go",
    "chars": 202,
    "preview": "package req\n\ntype GetGroupMemberListReq struct {\n\t// 房间ID\n\tRoomId   int64   `form:\"roomId\" binding:\"required\"`\n\tCursor  "
  },
  {
    "path": "domain/vo/req/get_message_list_req.go",
    "chars": 252,
    "preview": "package req\n\ntype GetMessageListReq struct {\n\tRoomId   int64   `json:\"roomId\" form:\"roomId\" binding:\"required\"`\n\tCursor "
  },
  {
    "path": "domain/vo/req/get_new_content_list_req.go",
    "chars": 122,
    "preview": "package req\n\ntype GetNewContentListReq struct {\n\tTimestamp int64 `json:\"timestamp\" form:\"timestamp\" binding:\"required\"`\n"
  },
  {
    "path": "domain/vo/req/get_new_msg_list_req.go",
    "chars": 187,
    "preview": "package req\n\ntype GetNewMsgListReq struct {\n\t// 房间ID\n\tRoomId int64 `json:\"roomId\" form:\"roomId\" binding:\"required\"`\n\t// "
  },
  {
    "path": "domain/vo/req/get_user_info_batch_req.go",
    "chars": 226,
    "preview": "package req\n\ntype UserInfoBatchReqItem struct {\n\tUid            int64 `json:\"uid\"`\n\tLastModifyTime int64 `json:\"lastModi"
  },
  {
    "path": "domain/vo/req/get_user_info_by_name_req.go",
    "chars": 104,
    "preview": "package req\n\ntype GetUserInfoByNameReq struct {\n\t// 用户名\n\tName string `form:\"name\" binding:\"required\"`\n}\n"
  },
  {
    "path": "domain/vo/req/grant_administrator_req.go",
    "chars": 175,
    "preview": "package req\n\ntype GrantAdministratorReq struct {\n\t// 房间ID\n\tRoomId int64 `json:\"room_id\" binding:\"required\"`\n\t// 授权用户ID\n\t"
  },
  {
    "path": "domain/vo/req/is_friend_req.go",
    "chars": 118,
    "preview": "package req\n\n// IsFriendReq 是否是好友请求\ntype IsFriendReq struct {\n\tFriendUid int64 `uri:\"friendUid\" binding:\"required\"`\n}\n"
  },
  {
    "path": "domain/vo/req/join_group_req.go",
    "chars": 83,
    "preview": "package req\n\ntype JoinGroupReq struct {\n\tID int64 `json:\"id\" binding:\"required\"`\n}\n"
  },
  {
    "path": "domain/vo/req/message_req.go",
    "chars": 403,
    "preview": "package req\n\ntype MessageBody struct {\n\tContent    string `json:\"content\" form:\"content\" binding:\"required\"`\n\tReplyMsgId"
  },
  {
    "path": "domain/vo/req/quit_group_req.go",
    "chars": 92,
    "preview": "package req\n\ntype QuitGroupReq struct {\n\t// 房间di\n\tID int64 `json:\"id\" binding:\"required\"`\n}\n"
  },
  {
    "path": "domain/vo/req/remove_administrator_req.go",
    "chars": 178,
    "preview": "package req\n\ntype RemoveAdministratorReq struct {\n\t// 房间ID\n\tRoomId int64 `json:\"room_id\" binding:\"required\"`\n\t// 移除用户ID\n"
  },
  {
    "path": "domain/vo/req/uid_req.go",
    "chars": 60,
    "preview": "package req\n\ntype UidReq struct {\n\tUid int64 `json:\"uid\"`\n}\n"
  },
  {
    "path": "domain/vo/req/user_apply_req.go",
    "chars": 92,
    "preview": "package req\n\ntype UserApplyReq struct {\n\tUid int64  `json:\"uid\"`\n\tMsg string `json:\"msg\"`\n}\n"
  },
  {
    "path": "domain/vo/req/user_cancle_req.go",
    "chars": 95,
    "preview": "package req\n\ntype UserCancelReq struct {\n\tCaptcha string `json:\"captcha\" binding:\"required\"`\n}\n"
  },
  {
    "path": "domain/vo/req/user_login_req.go",
    "chars": 388,
    "preview": "package req\n\ntype UserLoginReq struct {\n\tUserName  string `json:\"username,omitempty\"`           // 用户名可选\n\tPassword  stri"
  },
  {
    "path": "domain/vo/req/user_register_req.go",
    "chars": 302,
    "preview": "package req\n\ntype UserRegisterReq struct {\n\t// 用户名\n\tUsername string `json:\"username\" binding:\"required\"`\n\t// 密码\n\tPasswor"
  },
  {
    "path": "domain/vo/resp/get_user_info_batch_resp.go",
    "chars": 195,
    "preview": "package resp\n\ntype GetUserInfoBatchResp struct {\n\tUid         int64  `json:\"uid\"`\n\tUsername    string `json:\"name\"`\n\tAva"
  },
  {
    "path": "domain/vo/resp/get_user_info_by_name_resp.go",
    "chars": 197,
    "preview": "package resp\n\ntype GetUserInfoByNameResp struct {\n\t// 用户ID\n\tUid int64 `json:\"uid\"`\n\t// 用户名\n\tName string `json:\"name\"`\n\t/"
  },
  {
    "path": "domain/vo/resp/message_resp.go",
    "chars": 504,
    "preview": "package resp\n\ntype MsgUser struct {\n\tUid      int64  `json:\"uid\"`\n\tUsername string `json:\"username\"`\n\tAvatar   string `j"
  },
  {
    "path": "domain/vo/resp/page_list_resp.go",
    "chars": 114,
    "preview": "package resp\n\ntype PageListResp struct {\n\tList  interface{} `json:\"dataList\"`\n\tTotal int         `json:\"total\"`\n}\n"
  },
  {
    "path": "domain/vo/resp/pre_signed_resp.go",
    "chars": 125,
    "preview": "package resp\n\ntype PreSignedResp struct {\n\tUrl    string            `json:\"url\"`\n\tPolicy map[string]string `json:\"policy"
  },
  {
    "path": "domain/vo/resp/user_apply_resp.go",
    "chars": 220,
    "preview": "package resp\n\ntype UserApplyResp struct {\n\tApplyId int64  `json:\"applyId\"` // 申请ID\n\tUid     int64  `json:\"uid\"`     // 用"
  },
  {
    "path": "domain/vo/resp/user_contact_resp.go",
    "chars": 198,
    "preview": "package resp\n\ntype UserContactResp struct {\n\tUid          int64 `json:\"uid\"`          // 用户ID\n\tActiveStatus int   `json:"
  },
  {
    "path": "domain/vo/resp/user_login_resp.go",
    "chars": 162,
    "preview": "package resp\n\ntype UserLoginResp struct {\n\tToken  string `json:\"token\"`\n\tUid    int64  `json:\"uid\"`\n\tName   string `json"
  },
  {
    "path": "event/listener/friend_apply_event.go",
    "chars": 1536,
    "preview": "package listener\n\nimport (\n\t\"DiTing-Go/dal/model\"\n\t\"DiTing-Go/domain/enum\"\n\t\"DiTing-Go/global\"\n\t\"DiTing-Go/utils/jsonUti"
  },
  {
    "path": "event/listener/friend_delete_event.go",
    "chars": 4911,
    "preview": "package listener\n\nimport (\n\t\"DiTing-Go/dal/model\"\n\t\"DiTing-Go/domain/dto\"\n\t\"DiTing-Go/domain/enum\"\n\t\"DiTing-Go/global\"\n\t"
  },
  {
    "path": "event/listener/friend_new_event.go",
    "chars": 5737,
    "preview": "package listener\n\nimport (\n\t\"DiTing-Go/dal/model\"\n\t\"DiTing-Go/domain/enum\"\n\t\"DiTing-Go/global\"\n\tpkgEnum \"DiTing-Go/pkg/d"
  },
  {
    "path": "event/listener/new_msg_event.go",
    "chars": 6039,
    "preview": "package listener\n\nimport (\n\t\"DiTing-Go/dal/model\"\n\tquery \"DiTing-Go/dal/query\"\n\t\"DiTing-Go/domain/enum\"\n\t\"DiTing-Go/glob"
  },
  {
    "path": "event/listener/user_login_event.go",
    "chars": 1085,
    "preview": "package listener\n\nimport (\n\t\"DiTing-Go/domain/enum\"\n\t\"DiTing-Go/global\"\n\t\"context\"\n\t\"fmt\"\n\t\"github.com/apache/rocketmq-c"
  },
  {
    "path": "global/init_db.go",
    "chars": 531,
    "preview": "package global\n\nimport (\n\t\"DiTing-Go/dal\"\n\t\"DiTing-Go/dal/query\"\n\t\"fmt\"\n\t\"github.com/spf13/viper\"\n)\n\nvar MySQLDSN string"
  },
  {
    "path": "global/init_distribute_lock.go",
    "chars": 588,
    "preview": "package global\n\n//\n//import (\n//\tgoredislib \"github.com/go-redis/redis/v8\"\n//\t\"github.com/go-redsync/redsync/v4\"\n//\t\"git"
  },
  {
    "path": "global/init_evenbus.go",
    "chars": 134,
    "preview": "package global\n\n//\n//import \"github.com/asaskevich/EventBus\"\n//\n//var Bus EventBus.Bus\n//\n//func init() {\n//\tBus = Event"
  },
  {
    "path": "global/init_log.go",
    "chars": 883,
    "preview": "package global\n\nimport (\n\t\"github.com/sirupsen/logrus\"\n\t\"github.com/spf13/viper\"\n\t\"io\"\n\t\"os\"\n\t\"path\"\n)\n\nvar Logger *logr"
  },
  {
    "path": "global/init_minio.go",
    "chars": 592,
    "preview": "package global\n\nimport (\n\t\"github.com/minio/minio-go/v7\"\n)\n\nvar MinioClient *minio.Client\n\n//func init() {\n//\taccessKey "
  },
  {
    "path": "global/init_redis.go",
    "chars": 362,
    "preview": "package global\n\nimport (\n\t\"github.com/go-redis/redis\"\n\t\"github.com/spf13/viper\"\n)\n\nvar Rdb *redis.Client\n\nfunc RedisInit"
  },
  {
    "path": "global/init_rocketmq.go",
    "chars": 693,
    "preview": "package global\n\n//\n//import (\n//\t\"github.com/apache/rocketmq-client-go/v2\"\n//\t\"github.com/apache/rocketmq-client-go/v2/p"
  },
  {
    "path": "global/init_time.go",
    "chars": 133,
    "preview": "package global\n\n//import \"time\"\n//\n//func init() {\n//\tlocation, _ := time.LoadLocation(\"Asia/Shanghai\")\n//\ttime.Local = "
  },
  {
    "path": "go.mod",
    "chars": 4283,
    "preview": "module DiTing-Go\n\ngo 1.22.1\n\nrequire (\n\tgithub.com/apache/rocketmq-client-go/v2 v2.1.2\n\tgithub.com/gin-gonic/gin v1.9.1\n"
  },
  {
    "path": "go.sum",
    "chars": 36468,
    "preview": "filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA=\nfilippo.io/edwards25519 v1.1.0/go.mod h1:"
  },
  {
    "path": "logic/captcha.go",
    "chars": 1247,
    "preview": "package logic\n\nimport (\n\t\"DiTing-Go/global\"\n\t\"DiTing-Go/utils\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"math/rand\"\n\t\"time\"\n)\n\n// CheckC"
  },
  {
    "path": "logic/login.go",
    "chars": 4622,
    "preview": "package logic\n\nimport (\n\t\"DiTing-Go/dal/model\"\n\t\"DiTing-Go/domain/enum\"\n\t\"DiTing-Go/global\"\n\t\"DiTing-Go/utils\"\n\t\"context"
  },
  {
    "path": "logic/register.go",
    "chars": 2099,
    "preview": "package logic\n\nimport (\n\t\"DiTing-Go/domain/enum\"\n\t\"DiTing-Go/global\"\n\t\"DiTing-Go/utils\"\n\t\"context\"\n\t\"errors\"\n\t\"fmt\"\n\n\t\"g"
  },
  {
    "path": "logic/user.go",
    "chars": 1017,
    "preview": "package logic\n\nimport (\n\t\"DiTing-Go/dal/model\"\n\t\"DiTing-Go/dal/query\"\n\t\"DiTing-Go/domain/enum\"\n\t\"DiTing-Go/global\"\n\t\"con"
  },
  {
    "path": "logic/user_cancle.go",
    "chars": 894,
    "preview": "package logic\n\nimport (\n\t\"DiTing-Go/dal/query\"\n\t\"DiTing-Go/domain/enum\"\n\t\"DiTing-Go/global\"\n\t\"DiTing-Go/utils\"\n\t\"context"
  },
  {
    "path": "main.go",
    "chars": 406,
    "preview": "package main\n\nimport (\n\t//_ \"DiTing-Go/event/listener\"\n\t\"DiTing-Go/global\"\n\t\"DiTing-Go/routes\"\n\t\"DiTing-Go/utils/setting"
  },
  {
    "path": "pkg/domain/enum/code.go",
    "chars": 351,
    "preview": "package enum\n\nconst (\n\tSUCCESS        = 200\n\tERROR          = 500\n\tINVALID_PARAMS = 400\n\n\tERROR_EXIST_TAG         = 1000"
  },
  {
    "path": "pkg/domain/enum/common_enum.go",
    "chars": 76,
    "preview": "package enum\n\nconst (\n\tYES     = 2\n\tNO      = 1\n\tNORMAL  = 1\n\tDELETED = 2\n)\n"
  },
  {
    "path": "pkg/domain/enum/msg.go",
    "chars": 462,
    "preview": "package enum\n\nvar MsgFlags = map[int]string{\n\tSUCCESS:                        \"ok\",\n\tERROR:                          \"fa"
  },
  {
    "path": "pkg/domain/vo/req/page_req.go",
    "chars": 156,
    "preview": "package req\n\ntype PageReq struct {\n\tCursor   *string `json:\"cursor\" form:\"cursor\"`\n\tPageSize int     `json:\"pageSize\" fo"
  },
  {
    "path": "pkg/domain/vo/resp/page_resp.go",
    "chars": 174,
    "preview": "package resp\n\ntype PageResp struct {\n\tCursor *string `json:\"cursor\" form:\"cursor\"`\n\tIsLast bool    `json:\"isLast\" form:\""
  },
  {
    "path": "pkg/domain/vo/resp/response.go",
    "chars": 1944,
    "preview": "package resp\n\nimport (\n\t\"DiTing-Go/pkg/domain/enum\"\n\t\"github.com/gin-gonic/gin\"\n)\n\n// ResponseData 表示统一响应的JSON格式\ntype Re"
  },
  {
    "path": "pkg/utils/cursor_utils.go",
    "chars": 2415,
    "preview": "package utils\n\nimport (\n\tpkgReq \"DiTing-Go/pkg/domain/vo/req\"\n\tpkgResp \"DiTing-Go/pkg/domain/vo/resp\"\n\t\"fmt\"\n\t\"github.co"
  },
  {
    "path": "pkg/utils/redis.go",
    "chars": 1671,
    "preview": "package utils\n\nimport (\n\tdomainEnum \"DiTing-Go/domain/enum\"\n\t\"DiTing-Go/global\"\n\t\"github.com/go-redis/redis\"\n\t\"github.co"
  },
  {
    "path": "pkg/utils/redis_lock.go",
    "chars": 1300,
    "preview": "package utils\n\n//type RedSyncLock struct {\n//\tmutex  *redsync.Mutex\n//\tctx    context.Context\n//\tcancel context.CancelFu"
  },
  {
    "path": "pkg/utils/sort.go",
    "chars": 219,
    "preview": "package utils\n\ntype Int64Slice []int64\n\nfunc (p Int64Slice) Len() int {\n\treturn len(p)\n}\n\nfunc (p Int64Slice) Less(i, j "
  },
  {
    "path": "routes/init_router.go",
    "chars": 3447,
    "preview": "package routes\n\nimport (\n\t\"DiTing-Go/controller\"\n\t_ \"DiTing-Go/docs\"\n\t\"DiTing-Go/pkg/domain/vo/resp\"\n\t\"DiTing-Go/utils/m"
  },
  {
    "path": "service/adapter/build_contact_dao_list.go",
    "chars": 2285,
    "preview": "package adapter\n\nimport (\n\t\"DiTing-Go/dal/model\"\n\t\"DiTing-Go/domain/dto\"\n\t\"DiTing-Go/domain/enum\"\n\tcmap \"github.com/orca"
  },
  {
    "path": "service/adapter/build_message_resp.go",
    "chars": 867,
    "preview": "package adapter\n\nimport (\n\t\"DiTing-Go/dal/model\"\n\t\"DiTing-Go/domain/vo/resp\"\n)\n\nfunc BuildMessageRespByMsgAndUser(msgLis"
  },
  {
    "path": "service/adapter/build_user_info_by_name_resp.go",
    "chars": 1059,
    "preview": "package adapter\n\nimport (\n\t\"DiTing-Go/dal/model\"\n\t\"DiTing-Go/domain/vo/resp\"\n)\n\nfunc BuildUserInfoByNameResp(userList []"
  },
  {
    "path": "service/captcha_service.go",
    "chars": 1064,
    "preview": "package service\n\nimport (\n\t\"DiTing-Go/domain/vo/req\"\n\t\"DiTing-Go/global\"\n\t\"DiTing-Go/logic\"\n\tpkgResp \"DiTing-Go/pkg/doma"
  },
  {
    "path": "service/contact_service.go",
    "chars": 14516,
    "preview": "package service\n\n//\n//import (\n//\t\"DiTing-Go/dal\"\n//\t\"DiTing-Go/dal/model\"\n//\t\"DiTing-Go/domain/enum\"\n//\t\"DiTing-Go/doma"
  },
  {
    "path": "service/friend_service.go",
    "chars": 18159,
    "preview": "package service\n\n//\n//import (\n//\t\"DiTing-Go/dal\"\n//\t\"DiTing-Go/dal/model\"\n//\t\"DiTing-Go/domain/dto\"\n//\tdomainEnum \"DiTi"
  },
  {
    "path": "service/group_service.go",
    "chars": 22878,
    "preview": "package service\n\n//\n//import (\n//\t\"DiTing-Go/dal/model\"\n//\t\"DiTing-Go/domain/dto\"\n//\t\"DiTing-Go/domain/enum\"\n//\t\"DiTing-"
  },
  {
    "path": "service/message_service.go",
    "chars": 2044,
    "preview": "package service\n\n//\n//import (\n//\t\"DiTing-Go/dal/model\"\n//\t\"DiTing-Go/domain/enum\"\n//\t\"DiTing-Go/domain/vo/req\"\n//\tdomai"
  },
  {
    "path": "service/upload_service.go",
    "chars": 3228,
    "preview": "package service\n\n//\n//import (\n//\t\"DiTing-Go/dal/model\"\n//\t\"DiTing-Go/domain/dto\"\n//\t\"DiTing-Go/domain/enum\"\n//\tvoResp \""
  },
  {
    "path": "service/user_service.go",
    "chars": 10665,
    "preview": "package service\n\nimport (\n\t\"DiTing-Go/dal/model\"\n\tdomainEnum \"DiTing-Go/domain/enum\"\n\t\"DiTing-Go/domain/vo/req\"\n\t\"DiTing"
  },
  {
    "path": "service/user_service_integration_test.go",
    "chars": 6890,
    "preview": "package service\n\nimport (\n\t\"DiTing-Go/domain/enum\"\n\t\"DiTing-Go/domain/vo/req\"\n\t\"DiTing-Go/logic\"\n\t\"DiTing-Go/utils\"\n\t\"co"
  },
  {
    "path": "service/user_service_test.go",
    "chars": 3212,
    "preview": "package service\n\nimport (\n\t\"DiTing-Go/domain/enum\"\n\t\"DiTing-Go/domain/vo/req\"\n\t\"testing\"\n\n\t\"github.com/gin-gonic/gin\"\n\t\""
  },
  {
    "path": "sql/sql.sql",
    "chars": 8565,
    "preview": "-- auto-generated definition\ncreate table contact\n(\n    id          bigint unsigned auto_increment comment 'id'\n        "
  },
  {
    "path": "tests/README.md",
    "chars": 1524,
    "preview": "# DiTing-Go 测试文件夹结构\n\n## 概述\n\n本文件夹包含了DiTing-Go项目的所有测试文件,按照测试类型和功能模块进行了分类组织。\n\n## 文件夹结构\n\n```\ntests/\n├── unit/               "
  },
  {
    "path": "tests/e2e/user_workflow_e2e_test.go",
    "chars": 5755,
    "preview": "package e2e\n\nimport (\n\t\"DiTing-Go/domain/enum\"\n\t\"DiTing-Go/domain/vo/req\"\n\t\"DiTing-Go/global\"\n\t\"DiTing-Go/service\"\n\t\"DiT"
  },
  {
    "path": "tests/init_test.go",
    "chars": 549,
    "preview": "package tests\n\nimport (\n\t\"DiTing-Go/global\"\n\t\"log\"\n\t\"os\"\n\t\"testing\"\n)\n\n// TestMain 在所有测试运行前执行初始化\nfunc TestMain(m *testin"
  },
  {
    "path": "tests/integration/user_integration_test.go",
    "chars": 7019,
    "preview": "package integration\n\nimport (\n\t\"DiTing-Go/domain/enum\"\n\t\"DiTing-Go/domain/vo/req\"\n\t\"DiTing-Go/logic\"\n\t\"DiTing-Go/service"
  },
  {
    "path": "tests/performance/user_performance_test.go",
    "chars": 5869,
    "preview": "package performance\n\nimport (\n\t\"DiTing-Go/domain/enum\"\n\t\"DiTing-Go/domain/vo/req\"\n\t\"DiTing-Go/service\"\n\t\"DiTing-Go/utils"
  },
  {
    "path": "tests/scripts/run_e2e_test.sh",
    "chars": 1004,
    "preview": "#!/bin/bash\n\n# DiTing-Go E2E测试运行脚本\n\necho \"=== DiTing-Go E2E测试运行脚本 ===\"\necho \"\"\n\n# 检查Go环境\nif ! command -v go &> /dev/null"
  },
  {
    "path": "tests/scripts/run_tests.bat",
    "chars": 4296,
    "preview": "@echo off\nchcp 65001 >nul\nsetlocal enabledelayedexpansion\n\necho === DiTing-Go 用户服务测试 ===\necho.\n\nREM 检查Go环境\nwhere go >nul"
  },
  {
    "path": "tests/scripts/run_tests.sh",
    "chars": 5319,
    "preview": "#!/bin/bash\n\n# DiTing-Go 测试运行脚本\n\necho \"=== DiTing-Go 测试运行脚本 ===\"\necho \"\"\n\n# 检查Go环境\nif ! command -v go &> /dev/null; then"
  },
  {
    "path": "tests/scripts/setup_test_env.sh",
    "chars": 1083,
    "preview": "#!/bin/bash\n\n# DiTing-Go 测试环境设置脚本\n\necho \"=== DiTing-Go 测试环境设置 ===\"\necho \"\"\n\n# 检查Go环境\nif ! command -v go &> /dev/null; th"
  },
  {
    "path": "tests/unit/user_service_test.go",
    "chars": 5641,
    "preview": "package unit\n\nimport (\n\t\"DiTing-Go/domain/enum\"\n\t\"DiTing-Go/domain/vo/req\"\n\t\"DiTing-Go/global\"\n\t\"DiTing-Go/service\"\n\t\"Di"
  },
  {
    "path": "utils/jsonUtils/json.go",
    "chars": 1041,
    "preview": "package jsonUtils\n\n//import (\n//\t\"DiTing-Go/global\"\n//\t\"context\"\n//\t\"github.com/apache/rocketmq-client-go/v2/primitive\"\n"
  },
  {
    "path": "utils/jwt/jwt.go",
    "chars": 1276,
    "preview": "package jwt\n\nimport (\n\t\"DiTing-Go/global\"\n\t\"time\"\n\n\t\"github.com/golang-jwt/jwt/v5\"\n\t\"github.com/pkg/errors\"\n\t\"github.com"
  },
  {
    "path": "utils/jwt/jwt_test.go",
    "chars": 3613,
    "preview": "package jwt\n\nimport (\n\t\"fmt\"\n\t\"testing\"\n\t\"time\"\n)\n\nfunc TestGenerateToken(t *testing.T) {\n\ttests := []struct {\n\t\tname   "
  },
  {
    "path": "utils/middleware/cors.go",
    "chars": 1060,
    "preview": "package middleware\n\nimport (\n\t\"github.com/gin-gonic/gin\"\n\t\"net/http\"\n)\n\n// Cors 跨域中间件\nfunc Cors() gin.HandlerFunc {\n\tret"
  },
  {
    "path": "utils/middleware/jwt.go",
    "chars": 884,
    "preview": "package middleware\n\nimport (\n\t\"DiTing-Go/pkg/domain/vo/resp\"\n\t\"DiTing-Go/utils/jwt\"\n\t\"github.com/gin-gonic/gin\"\n\t\"string"
  },
  {
    "path": "utils/middleware/log.go",
    "chars": 744,
    "preview": "package middleware\n\nimport (\n\t\"DiTing-Go/global\"\n\t\"github.com/gin-gonic/gin\"\n\t\"github.com/sirupsen/logrus\"\n\t\"time\"\n)\n\n//"
  },
  {
    "path": "utils/mysqlUtils.go",
    "chars": 1132,
    "preview": "package utils\n\nimport (\n\t\"DiTing-Go/dal/model\"\n\t\"DiTing-Go/global\"\n\t\"context\"\n\t\"errors\"\n\t\"fmt\"\n\t\"gorm.io/gorm\"\n\t\"strconv"
  },
  {
    "path": "utils/passwordUtils.go",
    "chars": 248,
    "preview": "package utils\n\nimport (\n\t\"crypto/md5\"\n\t\"encoding/hex\"\n)\n\n// EncryptPassword 对密码进行md5加密\nfunc EncryptPassword(password str"
  },
  {
    "path": "utils/redisCache/remove_cache.go",
    "chars": 1335,
    "preview": "package redisCache\n\nimport (\n\t\"DiTing-Go/dal/model\"\n\t\"DiTing-Go/domain/enum\"\n\t\"DiTing-Go/pkg/utils\"\n\t\"fmt\"\n)\n\n// RemoveR"
  },
  {
    "path": "utils/redisUtils.go",
    "chars": 2277,
    "preview": "package utils\n\nimport (\n\tdomainEnum \"DiTing-Go/domain/enum\"\n\t\"DiTing-Go/global\"\n\t\"fmt\"\n\t\"time\"\n\n\t\"github.com/goccy/go-js"
  },
  {
    "path": "utils/setting/setting.go",
    "chars": 1617,
    "preview": "package setting\n\nimport (\n\t\"log\"\n\t\"os\"\n\t\"path/filepath\"\n\n\t\"github.com/spf13/viper\"\n)\n\nfunc ConfigInit() {\n\t// 设置配置文件的名字\n"
  },
  {
    "path": "utils/time_utils.go",
    "chars": 433,
    "preview": "package utils\n\nimport (\n\t\"DiTing-Go/global\"\n\t\"strconv\"\n\t\"time\"\n)\n\nfunc TimestampStrToTimeStr(str *string) (*string, erro"
  },
  {
    "path": "websocket/domain/enum/ws_type.go",
    "chars": 40,
    "preview": "package enum\n\nconst (\n\tNewMessage = 4\n)\n"
  },
  {
    "path": "websocket/domain/vo/resp/new_message_resp.go",
    "chars": 77,
    "preview": "package resp\n\ntype NewMessageResp struct {\n\tType int `json:\"type\"` // 消息类型\n}\n"
  },
  {
    "path": "websocket/global/global.go",
    "chars": 383,
    "preview": "package global\n\nimport (\n\t\"github.com/gorilla/websocket\"\n\tcmap \"github.com/orcaman/concurrent-map/v2\"\n\t\"sync\"\n)\n\ntype Ch"
  },
  {
    "path": "websocket/service/websocket_service.go",
    "chars": 3772,
    "preview": "package service\n\nimport (\n\tglobal2 \"DiTing-Go/global\"\n\t\"DiTing-Go/utils/jwt\"\n\t\"DiTing-Go/websocket/global\"\n\t\"fmt\"\n\t\"gith"
  }
]

About this extraction

This page contains the full source code of the danmuking/DiTing-Go GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 147 files (412.3 KB), approximately 134.6k tokens, and a symbol index with 864 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!