mirror of
https://github.com/zongzibinbin/MallChat.git
synced 2025-12-26 04:47:53 +08:00
Merge branch 'zongzibinbin:main' into main
This commit is contained in:
commit
3c1262d7ae
123
CODE_OF_CONDUCT.md
Normal file
123
CODE_OF_CONDUCT.md
Normal file
@ -0,0 +1,123 @@
|
||||
|
||||
# Contributor Covenant Code of Conduct
|
||||
|
||||
English | [简体中文](./CODE_OF_CONDUCT_CN.md)
|
||||
|
||||
## Our Pledge
|
||||
|
||||
We as members, contributors, and leaders pledge to make participation in our
|
||||
community a harassment-free experience for everyone, regardless of age, body
|
||||
size, visible or invisible disability, ethnicity, sex characteristics, gender
|
||||
identity and expression, level of experience, education, socio-economic status,
|
||||
nationality, personal appearance, race, caste, color, religion, or sexual
|
||||
identity and orientation.
|
||||
|
||||
We pledge to act and interact in ways that contribute to an open, welcoming,
|
||||
diverse, inclusive, and healthy community.
|
||||
|
||||
## Our Standards
|
||||
|
||||
Examples of behavior that contributes to a positive environment for our
|
||||
community include:
|
||||
|
||||
* Demonstrating empathy and kindness toward other people
|
||||
* Being respectful of differing opinions, viewpoints, and experiences
|
||||
* Giving and gracefully accepting constructive feedback
|
||||
* Accepting responsibility and apologizing to those affected by our mistakes,
|
||||
and learning from the experience
|
||||
* Focusing on what is best not just for us as individuals, but for the overall
|
||||
community
|
||||
|
||||
Examples of unacceptable behavior include:
|
||||
|
||||
* The use of sexualized language or imagery, and sexual attention or advances of
|
||||
any kind
|
||||
* Trolling, insulting or derogatory comments, and personal or political attacks
|
||||
* Public or private harassment
|
||||
* Publishing others' private information, such as a physical or email address,
|
||||
without their explicit permission
|
||||
* Other conduct which could reasonably be considered inappropriate in a
|
||||
professional setting
|
||||
|
||||
## Enforcement Responsibilities
|
||||
|
||||
Community leaders are responsible for clarifying and enforcing our standards of
|
||||
acceptable behavior and will take appropriate and fair corrective action in
|
||||
response to any behavior that they deem inappropriate, threatening, offensive,
|
||||
or harmful.
|
||||
|
||||
Community leaders have the right and responsibility to remove, edit, or reject
|
||||
comments, commits, code, wiki edits, issues, and other contributions that are
|
||||
not aligned to this Code of Conduct, and will communicate reasons for moderation
|
||||
decisions when appropriate.
|
||||
|
||||
## Scope
|
||||
|
||||
This Code of Conduct applies within all community spaces, and also applies when
|
||||
an individual is officially representing the community in public spaces.
|
||||
Examples of representing our community include using an official e-mail address,
|
||||
posting via an official social media account, or acting as an appointed
|
||||
representative at an online or offline event.
|
||||
|
||||
## Enforcement
|
||||
|
||||
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
||||
reported to the community leaders responsible for enforcement All complaints will be reviewed and investigated promptly and fairly.
|
||||
|
||||
All community leaders are obligated to respect the privacy and security of the
|
||||
reporter of any incident.
|
||||
|
||||
## Enforcement Guidelines
|
||||
|
||||
Community leaders will follow these Community Impact Guidelines in determining
|
||||
the consequences for any action they deem in violation of this Code of Conduct:
|
||||
|
||||
### 1. Correction
|
||||
|
||||
**Community Impact**: Use of inappropriate language or other behavior deemed
|
||||
unprofessional or unwelcome in the community.
|
||||
|
||||
**Consequence**: A private, written warning from community leaders, providing
|
||||
clarity around the nature of the violation and an explanation of why the
|
||||
behavior was inappropriate. A public apology may be requested.
|
||||
|
||||
### 2. Warning
|
||||
|
||||
**Community Impact**: A violation through a single incident or series of
|
||||
actions.
|
||||
|
||||
**Consequence**: A warning with consequences for continued behavior. No
|
||||
interaction with the people involved, including unsolicited interaction with
|
||||
those enforcing the Code of Conduct, for a specified period of time. This
|
||||
includes avoiding interactions in community spaces as well as external channels
|
||||
like social media. Violating these terms may lead to a temporary or permanent
|
||||
ban.
|
||||
|
||||
### 3. Temporary Ban
|
||||
|
||||
**Community Impact**: A serious violation of community standards, including
|
||||
sustained inappropriate behavior.
|
||||
|
||||
**Consequence**: A temporary ban from any sort of interaction or public
|
||||
communication with the community for a specified period of time. No public or
|
||||
private interaction with the people involved, including unsolicited interaction
|
||||
with those enforcing the Code of Conduct, is allowed during this period.
|
||||
Violating these terms may lead to a permanent ban.
|
||||
|
||||
### 4. Permanent Ban
|
||||
|
||||
**Community Impact**: Demonstrating a pattern of violation of community
|
||||
standards, including sustained inappropriate behavior, harassment of an
|
||||
individual, or aggression toward or disparagement of classes of individuals.
|
||||
|
||||
**Consequence**: A permanent ban from any sort of public interaction within the
|
||||
community.
|
||||
|
||||
## Attribution
|
||||
|
||||
This Code of Conduct is adapted from the [Contributor Covenantversion 2.1][homepage],
|
||||
|
||||
For answers to common questions about this code of conduct, see [https://www.contributor-covenant.org/faq][FAQ]
|
||||
|
||||
[homepage]: https://www.contributor-covenant.org/version/2/1/code_of_conduct.html
|
||||
[FAQ]: https://www.contributor-covenant.org/faq
|
||||
84
CODE_OF_CONDUCT_CN.md
Normal file
84
CODE_OF_CONDUCT_CN.md
Normal file
@ -0,0 +1,84 @@
|
||||
|
||||
# 贡献者公约
|
||||
|
||||
[English](./CODE_OF_CONDUCT.md) | 简体中文
|
||||
|
||||
## 我们的承诺
|
||||
|
||||
身为社区成员、贡献者和领袖,我们承诺使社区参与者不受骚扰,无论其年龄、体型、可见或不可见的缺陷、族裔、性征、性别认同和表达、经验水平、教育程度、社会与经济地位、国籍、相貌、种族、种姓、肤色、宗教信仰、性倾向或性取向如何。
|
||||
|
||||
我们承诺以有助于建立开放、友善、多样化、包容、健康社区的方式行事和互动。
|
||||
|
||||
## 我们的准则
|
||||
|
||||
有助于为我们的社区创造积极环境的行为例子包括但不限于:
|
||||
|
||||
* 表现出对他人的同情和善意
|
||||
* 尊重不同的主张、观点和感受
|
||||
* 提出和大方接受建设性意见
|
||||
* 承担责任并向受我们错误影响的人道歉
|
||||
* 注重社区共同诉求,而非个人得失
|
||||
|
||||
不当行为例子包括:
|
||||
|
||||
* 使用情色化的语言或图像,及性引诱或挑逗
|
||||
* 嘲弄、侮辱或诋毁性评论,以及人身或政治攻击
|
||||
* 公开或私下的骚扰行为
|
||||
* 未经他人明确许可,公布他人的私人信息,如物理或电子邮件地址
|
||||
* 其他有理由认定为违反职业操守的不当行为
|
||||
|
||||
## 责任和权力
|
||||
|
||||
社区领袖有责任解释和落实我们所认可的行为准则,并妥善公正地对他们认为不当、威胁、冒犯或有害的任何行为采取纠正措施。
|
||||
|
||||
社区领导有权力和责任删除、编辑或拒绝或拒绝与本行为准则不相符的评论(comment)、提交(commits)、代码、维基(wiki)编辑、议题(issues)或其他贡献,并在适当时机知采取措施的理由。
|
||||
|
||||
## 适用范围
|
||||
|
||||
本行为准则适用于所有社区场合,也适用于在公共场所代表社区时的个人。
|
||||
|
||||
代表社区的情形包括使用官方电子邮件地址、通过官方社交媒体帐户发帖或在线上或线下活动中担任指定代表。
|
||||
|
||||
## 监督
|
||||
|
||||
辱骂、骚扰或其他不可接受的行为可通过社区群、微信公众号等向负责监督的社区领袖报告。
|
||||
所有投诉都将得到及时和公平的审查和调查。
|
||||
|
||||
所有社区领袖都有义务尊重任何事件报告者的隐私和安全。
|
||||
|
||||
## 处理方针
|
||||
|
||||
社区领袖将遵循下列社区处理方针来明确他们所认定违反本行为准则的行为的处理方式:
|
||||
|
||||
### 1. 纠正
|
||||
|
||||
**社区影响**:使用不恰当的语言或其他在社区中被认定为不符合职业道德或不受欢迎的行为。
|
||||
|
||||
**处理意见**:由社区领袖发出非公开的书面警告,明确说明违规行为的性质,并解释举止如何不妥。或将要求公开道歉。
|
||||
|
||||
### 2. 警告
|
||||
|
||||
**社区影响**:单个或一系列违规行为。
|
||||
|
||||
**处理意见**:警告并对连续性行为进行处理。在指定时间内,不得与相关人员互动,包括主动与行为准则执行者互动。这包括避免在社区场所和外部渠道中的互动。违反这些条款可能会导致临时或永久封禁。
|
||||
|
||||
### 3. 临时封禁
|
||||
|
||||
**社区影响**: 严重违反社区准则,包括持续的不当行为。
|
||||
|
||||
**处理意见**: 在指定时间内,暂时禁止与社区进行任何形式的互动或公开交流。在此期间,不得与相关人员进行公开或私下互动,包括主动与行为准则执行者互动。违反这些条款可能会导致永久封禁。
|
||||
|
||||
### 4. 永久封禁
|
||||
|
||||
**社区影响**:行为模式表现出违反社区准则,包括持续的不当行为、骚扰个人或攻击或贬低某个类别的个体。
|
||||
|
||||
**处理意见**:永久禁止在社区内进行任何形式的公开互动。
|
||||
|
||||
## 参见
|
||||
|
||||
本行为准则改编自 [Contributor Covenant 2.1 版][homepage]。
|
||||
|
||||
有关本行为准则的常见问题的答案,参见 [https://www.contributor-covenant.org/faq][FAQ]。
|
||||
|
||||
[homepage]: https://www.contributor-covenant.org/version/2/1/code_of_conduct.html
|
||||
[FAQ]: https://www.contributor-covenant.org/faq
|
||||
120
README.md
120
README.md
@ -1,37 +1,54 @@
|
||||

|
||||
|
||||
MallChat的后端项目,是一个既能购物又能即时聊天的电商系统。致力于打造互联网企业级项目的最佳实践。电商该有的购物车,订单,支付,推荐,搜索,拉新,促活,推送,物流,客服,它都必须有。持续更新ing~~(记得star啊喂!)
|
||||
|
||||
<p align="center">
|
||||
<a href="#公众号"><img src="https://img.shields.io/badge/公众号-程序员阿斌-blue.svg?style=plasticr"></a>
|
||||
<a href="" target="_blank">
|
||||
<img src="https://s1.ax1x.com/2023/07/02/pCDR0W4.png" width="280" />
|
||||
</a>
|
||||
</p>
|
||||
|
||||
<h1 align="center">MallChat-抹茶</h1>
|
||||
<p align="center"><strong>一个既能购物又能即时聊天的电商系统。致力于打造互联网企业级项目的最佳实践。<br>电商该有的购物车、订单、支付、推荐、搜索、拉新、促活、推送、物流、客服、它都必须有。<em>持续更新 ing~</em></strong></p>
|
||||
|
||||
<div align="center">
|
||||
<a href="#公众号"><img src="https://img.shields.io/badge/公众号-程序员阿斌-blue.svg?style=plasticr"></a>
|
||||
<a href="#公众号"><img src="https://img.shields.io/badge/交流群-加入开发-green.svg?style=plasticr"></a>
|
||||
<a href="https://github.com/zongzibinbin/MallChat"><img src="https://img.shields.io/badge/github-项目地址-yellow.svg?style=plasticr"></a>
|
||||
<a href="https://gitee.com/zhongzhibinbin/MallChat"><img src="https://img.shields.io/badge/码云-项目地址-orange.svg?style=plasticr"></a>
|
||||
<a href="https://github.com/Evansy/MallChatWeb"><img src="https://img.shields.io/badge/前端-项目地址-blueviolet.svg?style=plasticr"></a>
|
||||
</p>
|
||||
|
||||
|
||||
[](https://github.com/Evansy/MallChatWeb/actions/workflows/deploy.yml)
|
||||
<a href="https://github.com/zongzibinbin/MallChat/commits" target="_blank">
|
||||
<img alt="Commit" src="https://img.shields.io/github/commit-activity/m/zongzibinbin/MallChat"></a>
|
||||
<a href="https://github.com/zongzibinbin/MallChat/issues" target="_blank">
|
||||
<img alt="Issues" src="https://img.shields.io/github/issues/zongzibinbin/MallChat"></a> [](https://github.com/zongzibinbin/MallChat/blob/master/LICENSE)
|
||||
[](https://github.com/zongzibinbin/MallChat/stargazers)
|
||||
</div>
|
||||
|
||||
## 项目导航
|
||||
|
||||
1. **快速体验地址**:[抹茶聊天首页](https://mallchat.cn)
|
||||
2. **前端项目仓库**:[MallChatWeb](https://github.com/Evansy/MallChatWeb)
|
||||
3. **项目视频记录**:[Bilibili地址](https://space.bilibili.com/146719540) 全程分享项目进度,功能选型的思考,同时征集迭代建议。
|
||||
4. **项目学习文档**:10w+字,保姆级教学路线,环境搭建、核心功能、基建轮子、接口压测、问题记录、一个不落。可点击[抹茶项目文档](https://www.yuque.com/snab/planet/cef1mcko4fve0ur3)查看(内含500人交流大群)
|
||||
5. **项目交流群**:对抹茶感兴趣的,可以加入[交流群](#公众号)。你的每一个举动,都会决定项目未来的方向。无论是提意见做产品经理,还是找bug做个测试人员,又或者加入开发小模块成为contributer,都欢迎你的加入。
|
||||
6. **码云仓库**:[https://gitee.com/zhongzhibinbin/MallChat](https://gitee.com/zhongzhibinbin/MallChat) (国内访问速度更快)
|
||||
- **快速体验地址**:[抹茶聊天首页](https://mallchat.cn)
|
||||
- **前端项目仓库**:[MallChatWeb](https://github.com/Evansy/MallChatWeb)
|
||||
- **项目视频记录**:[Bilibili地址](https://space.bilibili.com/146719540) 全程分享项目进度,功能选型的思考,同时征集迭代建议。
|
||||
- **项目学习文档**:10w+字,保姆级教学路线,环境搭建、核心功能、基建轮子、接口压测、问题记录、一个不落。可点击[抹茶项目文档](https://www.yuque.com/snab/planet/cef1mcko4fve0ur3)查看(内含500人交流大群)
|
||||
- **项目交流群**:对抹茶感兴趣的,可以加入[交流群](#公众号)。你的每一个举动,都会决定项目未来的方向。无论是提意见做产品经理,还是找bug做个测试人员,又或者加入开发小模块成为contributer,都欢迎你的加入。
|
||||
- **码云仓库**:[Gitee](https://gitee.com/zhongzhibinbin/MallChat)(国内访问速度更快)
|
||||
|
||||
## 项目介绍
|
||||
|
||||
抹茶聊天是一个IM项目,通过netty实现和前端的websocket连接。内含微信扫描登录,成员列表,上下线动画,消息列表,消息互动,还有很多实用的小轮子列如aop日志,分布式锁注解,频控注解,ip解析归属地等,持续更新中。。。
|
||||
抹茶聊天是一个IM项目,通过netty实现和前端的websocket连接。内含微信扫描登录,成员列表,消息列表,消息互动,丰富的消息类型,还有很多实用的小轮子列如aop日志,分布式锁注解,频控注解,ip解析归属地等,持续更新中。。。
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
### 项目演示
|
||||
|
||||
#### C端项目
|
||||
|
||||
- 前端项目地址:[https://github.com/Evansy/MallChatWeb](https://github.com/Evansy/MallChatWeb)
|
||||
- 前端源码地址:[https://github.com/Evansy/MallChatWeb](https://github.com/Evansy/MallChatWeb)
|
||||
- 项目演示地址:[https://mallchat.cn](https://mallchat.cn) (记住抹茶.cn,下次工作摸鱼可直接打开)
|
||||
|
||||

|
||||

|
||||
|
||||

|
||||
|
||||
### 技术选型
|
||||
|
||||
@ -52,10 +69,11 @@ MallChat的后端项目,是一个既能购物又能即时聊天的电商系统
|
||||
| Hutool | Java工具类库 | https://github.com/looly/hutool |
|
||||
| Swagger-UI | API文档生成工具 | https://github.com/swagger-api/swagger-ui |
|
||||
| Hibernate-validator | 接口校验框架 | [hibernate.org/validator/](hibernate.org/validator/) |
|
||||
| minio | 自建对象存储 | https://github.com/minio/minio |
|
||||
|
||||
#### 前端技术
|
||||
|
||||
见[MallChatWeb](https://github.com/Evansy/MallChatWeb)
|
||||
前往[MallChatWeb](https://github.com/Evansy/MallChatWeb)查看
|
||||
|
||||
### 环境搭建
|
||||
|
||||
@ -63,24 +81,80 @@ MallChat的后端项目,是一个既能购物又能即时聊天的电商系统
|
||||
|
||||
### 项目文档
|
||||
|
||||
保姆级教学路线,环境搭建、核心功能、基建轮子、接口压测、问题记录、项目亮点一个不落。点击[项目文档](https://www.yuque.com/snab/planet/cef1mcko4fve0ur3)
|
||||
保姆级教学路线,涵盖环境搭建、核心功能实现、基础架构构建、接口压力测试、问题记录以及项目的亮点。无一遗漏持续不断地更新中~
|
||||
查看[项目文档](https://www.yuque.com/snab/planet/cef1mcko4fve0ur3)
|
||||
|
||||
更多有趣功能在持续更新中。。。
|
||||
|
||||

|
||||
<div style="display: flex; align-items: center;">
|
||||
<img src="./docs/image/文档1.jpg" alt="文档1" width="50%">
|
||||
<img src="./docs/image/文档2.jpg" alt="文档2" width="47%">
|
||||
</div>
|
||||
|
||||
## star 趋势图
|
||||
|
||||

|
||||
|
||||
## 贡献者
|
||||
## 贡献
|
||||
**贡献之前请先阅读[行为准则](CODE_OF_CONDUCT.md) 和 贡献指南。感谢所有为 MallChat 做过贡献的人!**
|
||||
|
||||
#### 后端:
|
||||
|
||||
<a href="https://github.com/zongzibinbin/MallChat/graphs/contributors">
|
||||
<img src="https://contrib.rocks/image?repo=zongzibinbin/MallChat" />
|
||||
</a>
|
||||
|
||||
#### 前端:
|
||||
|
||||
<a href="https://github.com/Evansy/MallChatWeb/graphs/contributors">
|
||||
<img src="https://contrib.rocks/image?repo=Evansy/MallChatWeb" />
|
||||
</a>
|
||||
|
||||
<h4>优秀贡献者:</h4>
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<th>类别</th>
|
||||
<th>用户</th>
|
||||
<th>贡献模块</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td rowspan="3">前端</td>
|
||||
<td rowspan="3">
|
||||
<a href="https://github.com/LIjiAngChen8"><img src="https://avatars.githubusercontent.com/u/48879481?v=4" style=" width: 80px; height: 80px;"></a>
|
||||
</td>
|
||||
<td><a href="https://github.com/Evansy/MallChatWeb/pull/74">图片、语音、文件类型消息收发</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="https://github.com/Evansy/MallChatWeb/pull/50">消息互动操作(撤回、点赞、删除)</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="https://github.com/Evansy/MallChatWeb/pull/17">虚拟列表</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td rowspan="3">后端</td>
|
||||
<td rowspan="2">
|
||||
<a href="https://github.com/1045078399"><img src="https://avatars.githubusercontent.com/u/82020261?v=4" style=" width: 80px; height: 80px;"></a>
|
||||
</td>
|
||||
<td><a href="https://github.com/zongzibinbin/MallChat/pull/31">DFA敏感词检测</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="https://github.com/zongzibinbin/MallChat/pull/64">OpenAI聊天机器人</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td rowspan="1">
|
||||
<a href="https://github.com/xiaocairush"><img src="https://avatars.githubusercontent.com/u/6416523?v=4" style=" width: 80px; height: 80px;"></a>
|
||||
</td>
|
||||
<td><a href="https://github.com/zongzibinbin/MallChat/pull/99">Ac自动机敏感词检测</a></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## License
|
||||
[Apache License 2.0](./LICENSE)
|
||||
## 公众号
|
||||
|
||||
微信搜索 **阿斌Java之路** 关注我的原创公众号,后台回复「**抹茶**」即可加入抹茶交流群,一些做过公司万人群聊,高并发的小伙伴都在里面讨论方案。公众号也会经常更新项目相关的文档,等你来撩~~
|
||||
|
||||

|
||||
|
||||
|
||||
BIN
docs/image/复杂图片.jpg
Normal file
BIN
docs/image/复杂图片.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 668 KiB |
BIN
docs/image/文档1.jpg
Normal file
BIN
docs/image/文档1.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 44 KiB |
BIN
docs/image/文档2.jpg
Normal file
BIN
docs/image/文档2.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 65 KiB |
BIN
docs/image/群聊截图.jpg
Normal file
BIN
docs/image/群聊截图.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 312 KiB |
BIN
docs/image/设计模式.jpg
Normal file
BIN
docs/image/设计模式.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 22 KiB |
BIN
docs/image/项目大纲.jpg
Normal file
BIN
docs/image/项目大纲.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 82 KiB |
@ -113,7 +113,8 @@ CREATE TABLE `user` (
|
||||
INDEX `idx_create_time`(`create_time`) USING BTREE,
|
||||
INDEX `idx_update_time`(`update_time`) USING BTREE
|
||||
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '用户表' ROW_FORMAT = Dynamic;
|
||||
|
||||
INSERT INTO `mallchat`.`user` (`id`, `name`, `avatar`, `sex`, `open_id`, `last_opt_time`, `ip_info`, `item_id`, `status`, `create_time`, `update_time`) VALUES (10001, 'ChatGPT', 'https://img1.baidu.com/it/u=3613958228,3522035000&fm=253&fmt=auto&app=120&f=JPEG?w=500&h=500', 0, '??', '2023-06-29 17:03:03.357', NULL, NULL, 0, '2023-06-29 17:03:03.357', '2023-07-01 14:56:10.271');
|
||||
INSERT INTO `mallchat`.`user` (`id`, `name`, `avatar`, `sex`, `open_id`, `last_opt_time`, `ip_info`, `item_id`, `status`, `create_time`, `update_time`) VALUES (10002, 'ChatGLM2', 'http://mms1.baidu.com/it/u=1979830414,2984779047&fm=253&app=138&f=JPEG&fmt=auto&q=75?w=500&h=500', NULL, '450', '2023-07-01 11:58:24.605', NULL, NULL, 0, '2023-07-01 11:58:24.605', '2023-07-01 12:02:56.900');
|
||||
-- ----------------------------
|
||||
-- Table structure for user_backpack
|
||||
-- ----------------------------
|
||||
|
||||
2
docs/version/2023-07-01.sql
Normal file
2
docs/version/2023-07-01.sql
Normal file
@ -0,0 +1,2 @@
|
||||
INSERT INTO `mallchat`.`user` (`id`, `name`, `avatar`, `sex`, `open_id`, `last_opt_time`, `ip_info`, `item_id`, `status`, `create_time`, `update_time`) VALUES (10001, 'ChatGPT', 'https://img1.baidu.com/it/u=3613958228,3522035000&fm=253&fmt=auto&app=120&f=JPEG?w=500&h=500', 0, '??', '2023-06-29 17:03:03.357', NULL, NULL, 0, '2023-06-29 17:03:03.357', '2023-07-01 14:56:10.271');
|
||||
INSERT INTO `mallchat`.`user` (`id`, `name`, `avatar`, `sex`, `open_id`, `last_opt_time`, `ip_info`, `item_id`, `status`, `create_time`, `update_time`) VALUES (10002, 'ChatGLM2', 'http://mms1.baidu.com/it/u=1979830414,2984779047&fm=253&app=138&f=JPEG&fmt=auto&q=75?w=500&h=500', NULL, '450', '2023-07-01 11:58:24.605', NULL, NULL, 0, '2023-07-01 11:58:24.605', '2023-07-01 12:02:56.900');
|
||||
@ -1,9 +1,6 @@
|
||||
package com.abin.mallchat.common.common.config;
|
||||
|
||||
import cn.hutool.core.thread.NamedThreadFactory;
|
||||
import cn.hutool.core.thread.ThreadFactoryBuilder;
|
||||
import com.abin.mallchat.common.common.factory.MyThreadFactory;
|
||||
import com.abin.mallchat.common.common.handler.GlobalUncaughtExceptionHandler;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Primary;
|
||||
@ -11,9 +8,7 @@ import org.springframework.scheduling.annotation.AsyncConfigurer;
|
||||
import org.springframework.scheduling.annotation.EnableAsync;
|
||||
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
|
||||
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.concurrent.ThreadFactory;
|
||||
import java.util.concurrent.ThreadPoolExecutor;
|
||||
import java.util.concurrent.*;
|
||||
|
||||
/**
|
||||
* Description: 线程池配置
|
||||
@ -32,6 +27,9 @@ public class ThreadPoolConfig implements AsyncConfigurer {
|
||||
*/
|
||||
public static final String WS_EXECUTOR = "websocketExecutor";
|
||||
|
||||
|
||||
public static final String AICHAT_EXECUTOR = "aichatExecutor";
|
||||
|
||||
@Override
|
||||
public Executor getAsyncExecutor() {
|
||||
return mallchatExecutor();
|
||||
@ -64,5 +62,15 @@ public class ThreadPoolConfig implements AsyncConfigurer {
|
||||
return executor;
|
||||
}
|
||||
|
||||
|
||||
@Bean(AICHAT_EXECUTOR)
|
||||
public ThreadPoolTaskExecutor chatAiExecutor() {
|
||||
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
|
||||
executor.setCorePoolSize(10);
|
||||
executor.setMaxPoolSize(10);
|
||||
executor.setQueueCapacity(15);
|
||||
executor.setThreadNamePrefix("aichat-executor-");
|
||||
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.DiscardPolicy());//满了直接丢弃,默认为不重要消息推送
|
||||
executor.setThreadFactory(new MyThreadFactory(executor));
|
||||
return executor;
|
||||
}
|
||||
}
|
||||
|
||||
@ -26,7 +26,7 @@ public class JwtUtils {
|
||||
/**
|
||||
* token秘钥,请勿泄露,请勿随便修改
|
||||
*/
|
||||
@Value("jwt.secret")
|
||||
@Value("${mallchat.jwt.secret}")
|
||||
private String secret;
|
||||
|
||||
private static final String UID_CLAIM = "uid";
|
||||
|
||||
@ -0,0 +1,44 @@
|
||||
package com.abin.mallchat.common.common.algorithm.ac;
|
||||
|
||||
|
||||
import com.auth0.jwt.JWT;
|
||||
import com.auth0.jwt.algorithms.Algorithm;
|
||||
import com.auth0.jwt.interfaces.DecodedJWT;
|
||||
import com.auth0.jwt.interfaces.JWTVerifier;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
|
||||
@Slf4j
|
||||
public class CreateTokenTest {
|
||||
|
||||
@Test
|
||||
public void create(){
|
||||
String token = JWT.create()
|
||||
.withClaim("uid", 123L) // 只存一个uid信息,其他的自己去redis查
|
||||
.withClaim("createTime", new Date())
|
||||
.sign(Algorithm.HMAC256("dsfsdfsdfsdfsd")); // signature
|
||||
log.info("生成的token为 {}",token);
|
||||
|
||||
|
||||
try {
|
||||
JWTVerifier verifier = JWT.require(Algorithm.HMAC256("dsfsdfsdfsdfsd")).build();
|
||||
DecodedJWT jwt = verifier.verify(token);
|
||||
log.info(jwt.getClaims().toString());
|
||||
} catch (Exception e) {
|
||||
log.info("decode error,token:{}", token, e);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void verifyToken(){
|
||||
String token = JWT.create()
|
||||
.withClaim("uid", 1) // 只存一个uid信息,其他的自己去redis查
|
||||
.withClaim("createTime", new Date())
|
||||
.sign(Algorithm.HMAC256("dsfsdfsdfsdfsd")); // signature
|
||||
log.info("生成的token为{}",token);
|
||||
}
|
||||
}
|
||||
@ -1,10 +1,8 @@
|
||||
package com.abin.mallchat.custom.chatai.handler;
|
||||
|
||||
import cn.hutool.core.thread.NamedThreadFactory;
|
||||
import com.abin.mallchat.common.chat.domain.entity.Message;
|
||||
import com.abin.mallchat.common.chat.domain.enums.MessageTypeEnum;
|
||||
import com.abin.mallchat.common.common.exception.BusinessException;
|
||||
import com.abin.mallchat.common.common.handler.GlobalUncaughtExceptionHandler;
|
||||
import com.abin.mallchat.common.common.config.ThreadPoolConfig;
|
||||
import com.abin.mallchat.custom.chat.domain.vo.request.ChatMessageReq;
|
||||
import com.abin.mallchat.custom.chat.domain.vo.request.msg.TextMsgReq;
|
||||
import com.abin.mallchat.custom.chat.service.ChatService;
|
||||
@ -12,22 +10,18 @@ import com.abin.mallchat.custom.user.domain.vo.response.user.UserInfoResp;
|
||||
import com.abin.mallchat.custom.user.service.UserService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.beans.factory.DisposableBean;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import java.util.Collections;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.LinkedBlockingQueue;
|
||||
import java.util.concurrent.ThreadPoolExecutor;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
@Slf4j
|
||||
@Component
|
||||
public abstract class AbstractChatAIHandler implements DisposableBean, InitializingBean {
|
||||
public static ExecutorService EXECUTOR;
|
||||
public abstract class AbstractChatAIHandler {
|
||||
@Autowired
|
||||
@Qualifier(ThreadPoolConfig.AICHAT_EXECUTOR)
|
||||
private ThreadPoolTaskExecutor threadPoolTaskExecutor;
|
||||
|
||||
@Autowired
|
||||
protected ChatService chatService;
|
||||
@ -47,7 +41,7 @@ public abstract class AbstractChatAIHandler implements DisposableBean, Initializ
|
||||
if (!supports(message)) {
|
||||
return;
|
||||
}
|
||||
EXECUTOR.execute(() -> {
|
||||
threadPoolTaskExecutor.execute(() -> {
|
||||
String text = doChat(message);
|
||||
if (StringUtils.isNotBlank(text)) {
|
||||
answerMsg(text, message.getRoomId(), message.getFromUid());
|
||||
@ -101,30 +95,4 @@ public abstract class AbstractChatAIHandler implements DisposableBean, Initializ
|
||||
chatService.sendMsg(answerReq, getChatAIUserId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterPropertiesSet() {
|
||||
EXECUTOR = new ThreadPoolExecutor(
|
||||
10,
|
||||
10,
|
||||
0L,
|
||||
TimeUnit.MILLISECONDS,
|
||||
new LinkedBlockingQueue<>(15),
|
||||
new NamedThreadFactory("openAI-chat-gpt",
|
||||
null,
|
||||
false,
|
||||
new GlobalUncaughtExceptionHandler()),
|
||||
(r, executor) -> {
|
||||
throw new BusinessException("别问的太快了,我的脑子不够用了");
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroy() throws Exception {
|
||||
EXECUTOR.shutdown();
|
||||
if (!EXECUTOR.awaitTermination(30, TimeUnit.SECONDS)) { //最多等30秒,处理不完就拉倒
|
||||
if (log.isErrorEnabled()) {
|
||||
log.error("Timed out while waiting for executor [{}] to terminate", EXECUTOR);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -23,6 +23,7 @@ public class HttpTraceIdFilter implements Filter {
|
||||
String tid = UUID.randomUUID().toString();
|
||||
MDC.put(MDCKey.TID, tid);
|
||||
chain.doFilter(request, response);
|
||||
MDC.remove(MDCKey.TID);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -4,13 +4,11 @@ import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.channel.ChannelInboundHandlerAdapter;
|
||||
import io.netty.handler.codec.http.FullHttpRequest;
|
||||
import io.netty.handler.codec.http.HttpHeaders;
|
||||
import io.netty.util.AttributeKey;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.net.InetSocketAddress;
|
||||
|
||||
public class HttpHeadersHandler extends ChannelInboundHandlerAdapter {
|
||||
private AttributeKey<String> key = AttributeKey.valueOf("Id");
|
||||
|
||||
@Override
|
||||
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
|
||||
@ -22,6 +20,7 @@ public class HttpHeadersHandler extends ChannelInboundHandlerAdapter {
|
||||
ip = address.getAddress().getHostAddress();
|
||||
}
|
||||
NettyUtil.setAttr(ctx.channel(), NettyUtil.IP, ip);
|
||||
ctx.pipeline().remove(this);
|
||||
}
|
||||
ctx.fireChannelRead(msg);
|
||||
}
|
||||
|
||||
@ -12,6 +12,7 @@ import io.netty.util.AttributeKey;
|
||||
|
||||
public class NettyUtil {
|
||||
|
||||
public static AttributeKey<String> TOKEN = AttributeKey.valueOf("token");
|
||||
public static AttributeKey<String> IP = AttributeKey.valueOf("ip");
|
||||
public static AttributeKey<Long> UID = AttributeKey.valueOf("uid");
|
||||
|
||||
|
||||
@ -10,7 +10,6 @@ import io.netty.channel.socket.SocketChannel;
|
||||
import io.netty.channel.socket.nio.NioServerSocketChannel;
|
||||
import io.netty.handler.codec.http.HttpObjectAggregator;
|
||||
import io.netty.handler.codec.http.HttpServerCodec;
|
||||
import io.netty.handler.codec.http.websocketx.WebSocketServerProtocolHandler;
|
||||
import io.netty.handler.logging.LogLevel;
|
||||
import io.netty.handler.logging.LoggingHandler;
|
||||
import io.netty.handler.stream.ChunkedWriteHandler;
|
||||
@ -89,7 +88,7 @@ public class NettyWebSocketServer {
|
||||
* 4. WebSocketServerProtocolHandler 核心功能是把 http协议升级为 ws 协议,保持长连接;
|
||||
* 是通过一个状态码 101 来切换的
|
||||
*/
|
||||
pipeline.addLast(new WebSocketServerProtocolHandler("/"));
|
||||
pipeline.addLast(new WebSocketHandshakeHandler());
|
||||
// 自定义handler ,处理业务逻辑
|
||||
pipeline.addLast(new NettyWebSocketServerHandler());
|
||||
}
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
package com.abin.mallchat.custom.user.websocket;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.extra.spring.SpringUtil;
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import com.abin.mallchat.custom.user.domain.enums.WSReqTypeEnum;
|
||||
@ -66,6 +67,10 @@ public class NettyWebSocketServerHandler extends SimpleChannelInboundHandler<Tex
|
||||
}
|
||||
} else if (evt == WebSocketServerProtocolHandler.ServerHandshakeStateEvent.HANDSHAKE_COMPLETE) {
|
||||
getService().connect(ctx.channel());
|
||||
String token = NettyUtil.getAttr(ctx.channel(), NettyUtil.TOKEN);
|
||||
if (StrUtil.isNotBlank(token)) {
|
||||
getService().authorize(ctx.channel(), new WSAuthorize(token));
|
||||
}
|
||||
}
|
||||
super.userEventTriggered(ctx, evt);
|
||||
}
|
||||
|
||||
@ -0,0 +1,42 @@
|
||||
package com.abin.mallchat.custom.user.websocket;
|
||||
|
||||
|
||||
import io.netty.channel.ChannelFuture;
|
||||
import io.netty.channel.ChannelFutureListener;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.channel.ChannelInboundHandlerAdapter;
|
||||
import io.netty.handler.codec.http.FullHttpRequest;
|
||||
import io.netty.handler.codec.http.websocketx.WebSocketServerHandshaker;
|
||||
import io.netty.handler.codec.http.websocketx.WebSocketServerHandshakerFactory;
|
||||
import io.netty.handler.codec.http.websocketx.WebSocketServerProtocolHandler;
|
||||
|
||||
public class WebSocketHandshakeHandler extends ChannelInboundHandlerAdapter {
|
||||
@Override
|
||||
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
|
||||
if (msg instanceof FullHttpRequest) {
|
||||
FullHttpRequest request = (FullHttpRequest) msg;
|
||||
String token = request.headers().get("Sec-Websocket-Protocol");
|
||||
NettyUtil.setAttr(ctx.channel(), NettyUtil.TOKEN, token);
|
||||
// 构建WebSocket握手处理器
|
||||
WebSocketServerHandshakerFactory handshakeFactory = new WebSocketServerHandshakerFactory(
|
||||
request.uri(), token, false);
|
||||
WebSocketServerHandshaker handshake = handshakeFactory.newHandshaker(request);
|
||||
final ChannelFuture handshakeFuture = handshake.handshake(ctx.channel(), request);
|
||||
ctx.pipeline().remove(this);
|
||||
handshakeFuture.addListener(new ChannelFutureListener() {
|
||||
@Override
|
||||
public void operationComplete(ChannelFuture future) {
|
||||
if (!future.isSuccess()) {
|
||||
ctx.fireExceptionCaught(future.cause());
|
||||
} else {
|
||||
// 手动触发WebSocket握手状态事件
|
||||
ctx.fireUserEventTriggered(
|
||||
WebSocketServerProtocolHandler.ServerHandshakeStateEvent.HANDSHAKE_COMPLETE);
|
||||
}
|
||||
}
|
||||
});
|
||||
} else {
|
||||
super.channelRead(ctx, msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user