AI prompts
base on 摸鱼岛🎣后端 基于爬虫 ➕ Netty ➕ SpringBoot ➕Redis➕ MySQL 开源🌟一站式摸鱼网 <p align="right">
<strong>中文</strong> | <a href="./README.en.md">English</a>
</p>
<p align="center">
<a href="https://github.com/lhccong/fish-island-backend"><img src="./doc/img/moyu.png" width="300" height="300" alt="摸鱼岛 logo"></a>
</p>
# 摸鱼岛
_✨ 开源🌟一站式摸鱼网 ✨_
<p align="center">
<a href="https://github.com/lhccong/fish-island-backend#部署">部署教程</a>
·
<a href="https://github.com/lhccong/fish-island-backend#目前现状">目前现状</a>
·
<a href="https://fish.codebug.icu/rank/about">意见反馈</a>
·
<a href="https://github.com/lhccong/fish-island-backend#截图展示">截图展示</a>
·
<a href="https://fish.codebug.icu/index/">在线演示</a>
·
<a href="https://github.com/lhccong/fish-island-backend#开源与贡献">开源与贡献</a>
·
<a href="https://github.com/lhccong/fish-island-backend#相关项目">相关项目</a>
·
<a href="https://fish.codebug.icu/rank/reward">赞赏支持</a>
</p>

> [!NOTE]
> 本项目为开源项目,使用者必须在网站标注作者名称以及指向本项目的链接。如果不想保留署名,必须首先获得授权。不得用于非法用途。
> [!NOTE]
>
> 在线体验地址🔗
>
> 最新版(域名 2025.09 过期):https://fish.codebug.icu/
> 稳定版:https://yucoder.cn/
>
> 后端地址🌈:https://github.com/lhccong/fish-island-backend
>
> 前端地址🏖️:https://github.com/lhccong/fish-island-frontend
> [!WARNING]
> 私部署时记得修改后端接口地址路径指向。
## 功能
1. 支持多种数据源聚合:
+ [✅] 知乎热榜
+ [✅] 微博热榜
+ [✅] 虎扑步行街热榜
+ [✅] 编程导航热榜
+ [✅] CSDN 热榜
+ [✅] 掘金热榜
+ [✅] B 站热门
+ [✅] 抖音热搜
+ [✅] 网易云热歌榜(支持网站点击播放)
+ [✅] 什么值得买热榜
+ [✅] 待补充...
2. 每日待办功能。
3. 摸鱼聊天室:
+ [✅] 发送 emoji 表情包
+ [✅] 发送搜狗在线表情包
+ [✅] 支持网站链接解析
+ [✅] 支持 markdown 文本解析
+ [✅] 支持 AI 助手回答(接入硅基流动模型)
+ [✅] 头像框功能
+ [✅] 用户地理位置显示功能
+ [✅] 用户称号功能
+ [✅] 五子棋、象棋对战邀请功能
+ [✅] 积分红包🧧发送功能
+ [✅] 支持用户 CV 发送图片功能
4. 摸鱼阅读:
+ [✅] 在线搜书功能
+ [✅] 小窗口观看功能
+ [✅] 支持自定义书源
5. 小游戏:
+ [✅] 五子棋(人机/在线对战)
+ [✅] 象棋(人机/在线对战)
+ [✅] 2048
6. 工具箱:
+ [✅] JSON 格式化
+ [✅] 文本比对
+ [✅] 聚合翻译
+ [✅] Git 提交格式生成
+ [✅] AI 智能体
+ [✅] AI 周报助手
7. 头像框兑换功能。
8. 其他:
+ [✅] 音乐播放器
+ [✅] 下班薪资计算器(放假倒计时)
+ [✅] 修改网站图标
+ [✅] 网站标题闪烁消息提醒
+ [✅] 摸鱼初始页
## Star History
[](https://www.star-history.com/#lhccong/fish-island-backend&Date)
## 截图展示
### 信息聚合
<img src="./doc/img/image-20250426170535140.png" alt="image-20250426170535140" style="zoom:33%;" />
### 每日待办
<img src="./doc/img/image-20250426170619142.png" alt="image-20250426170619142" style="zoom: 33%;" />
### 摸鱼室
<img src="./doc/img/image-20250426171114575.png" alt="image-20250426171114575" style="zoom:33%;" />
### 摸鱼阅读
<img src="./doc/img/image-20250426170827125.png" alt="image-20250426170827125" style="zoom:33%;" />
<img src="./doc/img/image-20250426170856799.png" alt="image-20250426170856799" style="zoom: 50%;" />
### 小游戏
- 五子棋
<img src="./doc/img/image-20250426171345531.png" alt="image-20250426171345531" style="zoom:33%;" />
- 象棋
<img src="./doc/img/image-20250426171248993.png" alt="image-20250426171248993" style="zoom:33%;" />
- 2048
<img src="./doc/img/image-20250426171310675.png" alt="image-20250426171310675" style="zoom: 50%;" />
### 工具箱
- JSON 格式化工具
<img src="./doc/img/image-20250426171413448.png" alt="image-20250426171413448" style="zoom:25%;" />
- 文本比对
<img src="./doc/img/image-20250426171435468.png" alt="image-20250426171435468" style="zoom:25%;" />
### 头像框兑换
<img src="./doc/img/image-20250426171832381.png" alt="image-20250426171832381" style="zoom: 33%;" />
## 目前现状
- 各大公众号转发。
<img src="./doc/img/image-wchat.png" alt="wchat" style="zoom: 50%;" />
- 用户突破 1k 的个人网站。
- 最高峰实时在线人数达 80 +。
<img src="./doc/img/image-20250426165418718.png" alt="image-20250426165418718" width="20%" style="zoom:25%;" >
## 部署教程
### 后端
- 执行初始化 SQL [create_table.sql](./sql/create_table.sql)
- 更改 MySQL 地址、Redis 地址、Minio 地址、邮箱发送配置
- Maven 打包
- docker 部署
- dockerfile 文件
```dockerfile
FROM openjdk:8
ENV workdir=/cong/fish
COPY . ${workdir}
WORKDIR ${workdir}
EXPOSE 8123
CMD ["java","-jar","-Duser.timezone=GMT+08","fish-island-backend-0.0.1-SNAPSHOT.jar"]
```
- 打包命令
```shell
docker build -f ./dockerfile -t fish .
启动命令:docker run -d -e TZ=CST -p 8123:8123 -p 8090:8090 --name "fish" fish:latest
```
- nginx 配置
```nginx
server {
listen 80;
listen [::]:80;
server_name moyuapi.codebug.icu;
rewrite ^(.*) https://$server_name$1 permanent;
}
server {
listen 443 ssl;
server_name moyuapi.codebug.icu;
ssl_certificate /etc/nginx/ssl/cert.pem;
ssl_certificate_key /etc/nginx/ssl/key.pem;
ssl_session_cache shared:SSL:1m;
ssl_session_timeout 5m;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
location / {
root /usr/share/nginx/fish;
index index.html;
try_files $uri $uri/ /index.html;
}
location /fish/ {
proxy_pass http://fish:8123/;
}
# WebSocket代理配置,处理 wss:// 请求
location /ws/ {
proxy_pass http://fish:8090/; # 后端 WebSocket 服务地址
proxy_http_version 1.1; # 使用 HTTP/1.1 协议,WebSocket 需要这个版本
proxy_set_header Upgrade $http_upgrade; # 必须设置这些头来支持 WebSocket 协议的升级
proxy_set_header Connection 'upgrade'; # 维持 WebSocket 连接
proxy_set_header Host $host; # 确保 Host 头部传递正确
proxy_cache_bypass $http_upgrade; # 禁用缓存
}
location /sogou-api/ {
proxy_pass https://pic.sogou.com/;
proxy_set_header Host pic.sogou.com;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_ssl_server_name on;
# 解决 CORS 问题
add_header Access-Control-Allow-Origin *;
add_header Access-Control-Allow-Methods "GET, POST, OPTIONS";
add_header Access-Control-Allow-Headers "DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range";
add_header Access-Control-Expose-Headers "Content-Length,Content-Range";
# 处理 OPTIONS 预检请求
if ($request_method = OPTIONS) {
return 204;
}
}
location /holiday/ {
proxy_pass https://date.appworlds.cn/;
# 保持目标 API 的 Host,避免返回默认网页
proxy_set_header Host date.appworlds.cn;
# 伪装成浏览器,防止服务器根据 User-Agent 返回 HTML
proxy_set_header User-Agent "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36";
# 强制服务器返回 JSON,而不是 HTML
proxy_set_header Accept "application/json";
# CORS 允许跨域
add_header Access-Control-Allow-Origin *;
add_header Access-Control-Allow-Methods "GET, POST, OPTIONS";
add_header Access-Control-Allow-Headers "DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range";
add_header Access-Control-Expose-Headers "Content-Length,Content-Range";
# 处理 OPTIONS 预检请求
if ($request_method = OPTIONS) {
return 204;
}
}
location /img-api/ {
proxy_pass https://i.111666.best/;
proxy_set_header Host pic.sogou.com;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_ssl_server_name on;
# 解决 CORS 问题
add_header Access-Control-Allow-Origin *;
add_header Access-Control-Allow-Methods "GET, POST, OPTIONS";
add_header Access-Control-Allow-Headers "DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range";
add_header Access-Control-Expose-Headers "Content-Length,Content-Range";
# 处理 OPTIONS 预检请求
if ($request_method = OPTIONS) {
return 204;
}
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}
```
### 前端
- 修改 src/constants/index.ts 的接口地址。
- max build --打包命令。
- 部署 dist 文件。
## 开源与贡献
### 项目支持者 🔥
<img src="./doc/img/image-20250426171939913.png" alt="image-20250426171939913" style="zoom: 33%;" />
### 前端贡献者 🌟
<a href="https://github.com/lhccong/fish-island-frontend/graphs/contributors">
<img src="https://contrib.rocks/image?repo=lhccong/fish-island-frontend" />
</a>
### 后端贡献者 🌟:
<a href="https://github.com/lhccong/fish-island-backend/graphs/contributors">
<img src="https://contrib.rocks/image?repo=lhccong/fish-island-backend" />
</a>
### 📌 贡献方式
如果你也有希望聚合的数据源不妨来参加一下贡献,将你的数据源爬取出来放入其中。
1️⃣ 页面元素抓取
📌 **适用于**:目标网站未提供 API,数据嵌入在 HTML 结构中。
✅ 贡献要求
- **推荐使用**:
- `Jsoup`(Java)
- `BeautifulSoup`(Python)
- `Cheerio`(Node.js)
- **选择器精准**:避免因页面结构变化导致抓取失败。
- **减少 HTTP 请求**:优化抓取效率,避免重复请求。
- **遵守网站爬取规则**(`robots.txt` )。
💡 示例代码
```java
Document doc = Jsoup.connect("https://example.com").get();
String title = doc.select("h1.article-title").text();
```
2️⃣ 页面接口返回数据抓取
📌 **适用于**:目标网站提供 API,可直接调用接口获取 JSON/XML 数据。
✅ 贡献要求
- **推荐使用**:
- `HttpClient`(Java)
- `axios`(Node.js)
- `requests`(Python)
- **分析 API 请求**:确保请求参数完整(`headers`、`cookies`、`token`)。
- **减少不必要的请求**:优化调用频率,避免触发反爬机制。
- **异常处理**:确保代码稳定运行。
💡 示例代码
```java
String apiUrl = "https://api.example.com/data";
String response = HttpRequest.get(apiUrl).execute().body();
JSONObject json = JSON.parseObject(response);
```
---
### 🔗 数据源注册
数据抓取完成后,需要注册数据源,以便系统能够正确使用。
🚀 注册流程
1. **添加数据源 Key**:
`/src/main/java/com/cong/fishisland/model/enums/HotDataKeyEnum.java` 定义新的数据源 Key。
2. **更新数据源映射**:
- `/src/main/java/com/lhccong/fish/backend/config/DatabaseConfig.java` 文件中,添加新的数据源配置。
3. **创建数据源类**:
- `src/main/java/com/cong/fishisland/datasource` 目录下,新建数据源类,继承 `DataSource`,实现 `getHotPost` 方法。
4. **实现数据获取逻辑**:
- 按照 `HotPostDataVO` 格式返回数据。
- 使用 `@Builder` 注解,确保数据能正确解析。
💡 示例代码
```java
HotPostDataVO.builder()
.title(title)
.url(url)
.followerCount(followerCount)
.excerpt(excerpt)
.build();
```
---
### 🚀 贡献流程
1. **Fork 仓库** ➜ 点击 GitHub 右上角 `Fork` 按钮。
2. **创建分支** ➜ 推荐使用有意义的分支名,如 `feature/data-scraper-optimization`。
3. **提交代码** ➜ 确保代码可读性高,符合规范。
4. **提交 Pull Request(PR)** ➜ 详细描述您的更改内容,并关联相关 issue(如有)。
5. **等待审核** ➜ 维护者会进行代码审核并合并。
以上讲解如果对你有帮助,不妨给我的项目点个小小的 star 🌟,成为一下我的精神股东呢
### 🎉 感谢您的贡献!
您的每一份贡献都让 **fish-island** 变得更好!💪
", Assign "at most 3 tags" to the expected json: {"id":"14797","tags":[]} "only from the tags list I provide: [{"id":77,"name":"3d"},{"id":89,"name":"agent"},{"id":17,"name":"ai"},{"id":54,"name":"algorithm"},{"id":24,"name":"api"},{"id":44,"name":"authentication"},{"id":3,"name":"aws"},{"id":27,"name":"backend"},{"id":60,"name":"benchmark"},{"id":72,"name":"best-practices"},{"id":39,"name":"bitcoin"},{"id":37,"name":"blockchain"},{"id":1,"name":"blog"},{"id":45,"name":"bundler"},{"id":58,"name":"cache"},{"id":21,"name":"chat"},{"id":49,"name":"cicd"},{"id":4,"name":"cli"},{"id":64,"name":"cloud-native"},{"id":48,"name":"cms"},{"id":61,"name":"compiler"},{"id":68,"name":"containerization"},{"id":92,"name":"crm"},{"id":34,"name":"data"},{"id":47,"name":"database"},{"id":8,"name":"declarative-gui "},{"id":9,"name":"deploy-tool"},{"id":53,"name":"desktop-app"},{"id":6,"name":"dev-exp-lib"},{"id":59,"name":"dev-tool"},{"id":13,"name":"ecommerce"},{"id":26,"name":"editor"},{"id":66,"name":"emulator"},{"id":62,"name":"filesystem"},{"id":80,"name":"finance"},{"id":15,"name":"firmware"},{"id":73,"name":"for-fun"},{"id":2,"name":"framework"},{"id":11,"name":"frontend"},{"id":22,"name":"game"},{"id":81,"name":"game-engine "},{"id":23,"name":"graphql"},{"id":84,"name":"gui"},{"id":91,"name":"http"},{"id":5,"name":"http-client"},{"id":51,"name":"iac"},{"id":30,"name":"ide"},{"id":78,"name":"iot"},{"id":40,"name":"json"},{"id":83,"name":"julian"},{"id":38,"name":"k8s"},{"id":31,"name":"language"},{"id":10,"name":"learning-resource"},{"id":33,"name":"lib"},{"id":41,"name":"linter"},{"id":28,"name":"lms"},{"id":16,"name":"logging"},{"id":76,"name":"low-code"},{"id":90,"name":"message-queue"},{"id":42,"name":"mobile-app"},{"id":18,"name":"monitoring"},{"id":36,"name":"networking"},{"id":7,"name":"node-version"},{"id":55,"name":"nosql"},{"id":57,"name":"observability"},{"id":46,"name":"orm"},{"id":52,"name":"os"},{"id":14,"name":"parser"},{"id":74,"name":"react"},{"id":82,"name":"real-time"},{"id":56,"name":"robot"},{"id":65,"name":"runtime"},{"id":32,"name":"sdk"},{"id":71,"name":"search"},{"id":63,"name":"secrets"},{"id":25,"name":"security"},{"id":85,"name":"server"},{"id":86,"name":"serverless"},{"id":70,"name":"storage"},{"id":75,"name":"system-design"},{"id":79,"name":"terminal"},{"id":29,"name":"testing"},{"id":12,"name":"ui"},{"id":50,"name":"ux"},{"id":88,"name":"video"},{"id":20,"name":"web-app"},{"id":35,"name":"web-server"},{"id":43,"name":"webassembly"},{"id":69,"name":"workflow"},{"id":87,"name":"yaml"}]" returns me the "expected json"