Browse Source

add:2025年6月18日-lihui学习笔记

master
lihui 2 weeks ago
parent
commit
a98b611445
  1. 2
      GO学习/GOFrame.md
  2. 439
      GO学习/Gin框架.md
  3. BIN
      GO学习/assets/Gin框架/image-20250617112721609-17501308421881.png
  4. BIN
      GO学习/assets/Gin框架/image-20250617112721609.png
  5. BIN
      GO学习/assets/Gin框架/image-20250617112936947.png
  6. BIN
      GO学习/assets/Gin框架/image-20250617114457929.png
  7. BIN
      GO学习/assets/Gin框架/image-20250617115733445.png
  8. 89
      Git命令.md
  9. BIN
      assets/6-16_李慧学习记录/image-20250616180459370.png
  10. BIN
      assets/6-16_李慧学习记录/image-20250616180518835.png
  11. BIN
      assets/6-16股票学习/image-20250616114324156.png
  12. 0
      git
  13. 0
      学习记录/2025年6月11日学习记录.md
  14. 2
      学习记录/6-12_李慧学习记录.md
  15. 0
      学习记录/6-13_李慧学习报告.md
  16. 0
      学习记录/6-15_李慧学习记录.md
  17. 8
      学习记录/6-16_李慧学习记录.md
  18. 583
      学习记录/6-17_李慧学习记录.md
  19. BIN
      学习记录/assets/6-16_李慧学习记录/image-20250617150826018.png
  20. BIN
      学习记录/assets/6-16_李慧学习记录/image-20250617150903922.png
  21. BIN
      学习记录/assets/6-16_李慧学习记录/image-20250617150917522.png
  22. BIN
      学习记录/assets/6-17_李慧学习记录/image-20250617180547018.png
  23. 2
      股票/6-16股票学习.md
  24. 137
      股票/6-17股票学习.md
  25. BIN
      股票/assets/6-16股票学习/image-20250617150944307.png
  26. BIN
      股票/assets/6-17股票学习/image-20250617171603320.png
  27. BIN
      股票/assets/6-17股票学习/image-20250617172405667.png
  28. BIN
      股票/assets/6-17股票学习/image-20250617174011011.png
  29. BIN
      股票/assets/6-17股票学习/image-20250617175850502.png
  30. BIN
      股票/assets/6-17股票学习/image-20250617180042083.png

2
GO学习/GOFrame.md

@ -0,0 +1,2 @@
# GoFrame框架

439
GO学习/Gin框架.md

@ -0,0 +1,439 @@
# Gin框架的基本使用
## 下载与安装
> 更改环境变量 GOPATH
>
> 方便将包下载到其他的盘符目录
>
> 参考:[2024年go安装教程(Windows)包括配置GOPATH-CSDN博客](https://blog.csdn.net/weixin_63860405/article/details/139732041)
### 下载
```shell
go get -u github.com/gin-gonic/gin
```
![image-20250617112721609](assets/Gin框架/image-20250617112721609-17501308421881.png)
## 基础使用
### GET请求
```go
package main
import "github.com/gin-gonic/gin"
func main() {
router := gin.Default()
router.GET("/ping", func(c *gin.Context) {
c.JSON(200, gin.H{
"message": "Hello World!",
})
})
router.Run() // 监听并在 0.0.0.0:8080 上启动服务
// 默认是在8080端口启动服务,如果8080端口被占用,则自动寻找可用端口启动服务,可以指定端口
}
```
![image-20250617112936947](assets/Gin框架/image-20250617112936947.png)
### ANY请求
根据请求来选择(使用if else)
```go
// Any 请求
router.Any("/any", func(c *gin.Context) {
if c.Request.Method == "POST" {
c.JSON(200, gin.H{
"message": "POST",
})
} else if c.Request.Method == "GET" {
c.JSON(200, gin.H{
"message": "GET",
})
} else {
c.JSON(200, gin.H{
"message": "Any",
})
}
})
```
### POST请求
```go
// POST 请求
router.POST("/post", func(c *gin.Context) {
c.JSON(200, gin.H{
"message": "POST",
})
})
```
![image-20250617114457929](assets/Gin框架/image-20250617114457929.png)
## 参数获取
### 获取query string 参数
格式:URL `?`后携带参数
例如:/user/searcher?username=xxx&address=xxx
```go
// 获取参数,query string
router.GET("/user/search", func(c *gin.Context) {
username := c.DefaultQuery("username", "lihuibear")
address := c.Query("address")
// 返回json数据
c.JSON(200, gin.H{
"username": username,
"address": address,
})
})
```
![image-20250617115733445](assets/Gin框架/image-20250617115733445.png)
### 获取 form参数
当前端请求的数据通过form表单提交时,例如向`/user/search`发送一个POST请求,获取请求数据的方式如下:
```go
router.POST("/user/search_by_form", func(c *gin.Context) {
// DefaultPostForm取不到值时会返回指定的默认值
//username := c.DefaultPostForm("username", "小王子")
username := c.PostForm("username")
address := c.PostForm("address")
//输出json结果给调用方
c.JSON(http.StatusOK, gin.H{
"message": "ok",
"username": username,
"address": address,
})
})
```
### 获取JSON参数
当前端请求的数据通过JSON提交时,例如向`/json`发送一个JSON格式的POST请求,则获取请求参数的方式如下:
```go
//获取JSON参数
router.POST("/json", func(c *gin.Context) {
// 注意:下面为了举例子方便,暂时忽略了错误处理
b, _ := c.GetRawData() // 从c.Request.Body读取请求数据
// 定义map或结构体
var m map[string]interface{}
// 反序列化
_ = json.Unmarshal(b, &m)
c.JSON(http.StatusOK, m)
})
```
### 获取path参数
请求的参数通过URL路径传递,例如:`/user/search/小王子/沙河`。 获取请求URL路径中的参数的方式如下:
```go
// 获取path参数
router.GET("/user/search/:username/:address", func(c *gin.Context) {
username := c.Param("username")
address := c.Param("address")
//输出json结果给调用方
c.JSON(http.StatusOK, gin.H{
"message": "ok",
"username": username,
"address": address,
})
})
```
### 参数绑定 ShouldBind()
为了能够更方便的获取请求相关参数,提高开发效率,我们可以基于请求的`Content-Type`识别请求数据类型并利用反射机制自动提取请求中`QueryString`、`form表单`、`JSON`、`XML`等参数到结构体中。
```go
// 参数绑定
// 绑定JSON的示例 ({"user": "q1mi", "password": "123456"})
router.POST("/login_by_JSON", func(c *gin.Context) {
var login Login
if err := c.ShouldBind(&login); err == nil {
fmt.Printf("login info:%#v\n", login)
c.JSON(http.StatusOK, gin.H{
"user": login.User,
"password": login.Password,
})
} else {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
}
})
// 绑定form表单示例 (user=q1mi&password=123456)
router.POST("/login_by_form", func(c *gin.Context) {
var login Login
// ShouldBind()会根据请求的Content-Type自行选择绑定器
if err := c.ShouldBind(&login); err == nil {
c.JSON(http.StatusOK, gin.H{
"user": login.User,
"password": login.Password,
})
} else {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
}
})
// 绑定QueryString示例 (/loginQuery?user=q1mi&password=123456)
router.GET("/login_by_query", func(c *gin.Context) {
var login Login
// ShouldBind()会根据请求的Content-Type自行选择绑定器
if err := c.ShouldBind(&login); err == nil {
c.JSON(http.StatusOK, gin.H{
"user": login.User,
"password": login.Password,
})
} else {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
}
})
```
`ShouldBind`会按照下面的顺序解析请求中的数据完成绑定:
1. 如果是 `GET` 请求,只使用 `Form` 绑定引擎(`query`)。
2. 如果是 `POST` 请求,首先检查 `content-type` 是否为 `JSON``XML`,然后再使用 `Form`(`form-data`)。
## Gin渲染
我们首先定义一个存放模板文件的`templates`文件夹,然后在其内部按照业务分别定义一个`posts`文件夹和一个`users`文件夹。 `posts/index.html`文件的内容如下:
```template
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>posts/index</title>
</head>
<body>
{{.title}}
</body>
</html>
{{end}}
```
`users/index.html`文件的内容如下:
```template
{{define "users/index.html"}}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>users/index</title>
</head>
<body>
{{.title}}
</body>
</html>
{{end}}
```
Gin框架中使用`LoadHTMLGlob()`或者`LoadHTMLFiles()`方法进行HTML模板渲染。
```go
func main() {
r := gin.Default()
r.LoadHTMLGlob("templates/**/*")
//r.LoadHTMLFiles("templates/posts/index.html", "templates/users/index.html")
r.GET("/posts/index", func(c *gin.Context) {
c.HTML(http.StatusOK, "posts/index.html", gin.H{
"title": "posts/index",
})
})
r.GET("users/index", func(c *gin.Context) {
c.HTML(http.StatusOK, "users/index.html", gin.H{
"title": "users/index",
})
})
r.Run(":8080")
}
```
## 文件上传
### 单文件上传
```go
// 加载模板
router.LoadHTMLFiles("./templates/upload.html")
// 上传文件
router.GET("/upload", func(c *gin.Context) {
c.HTML(http.StatusOK, "upload.html", nil)
})
router.POST("/upload", func(c *gin.Context) {
// 接收用户上传文件的post请求
f, err := c.FormFile("avatar")
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{
"message": err.Error(),
})
return
}
// 保存到指定目录 dst
dst := "./upload/" + f.Filename
c.SaveUploadedFile(f, dst)
// 返回响应
c.JSON(http.StatusOK, gin.H{
"message": fmt.Sprintf("'%s' uploaded!", f.Filename),
})
})
```
### 多文件上传
```go
// 多文件上传
// 加载模板
router.LoadHTMLFiles("./templates/uploads.html")
// 显示多文件上传页面
router.GET("/multi-upload", func(c *gin.Context) {
c.HTML(http.StatusOK, "uploads.html", nil)
})
// 多文件上传
router.POST("/multi-upload", func(c *gin.Context) {
// Multipart form
form, err := c.MultipartForm()
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": "failed to parse multipart form"})
return
}
files := form.File["file"]
for index, file := range files {
log.Println(file.Filename)
dst := fmt.Sprintf("./upload/%s_%d", file.Filename, index)
if err := c.SaveUploadedFile(file, dst); err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
}
c.JSON(http.StatusOK, gin.H{
"message": fmt.Sprintf("%d files uploaded!", len(files)),
})
})
```
## 重定向
### http重定向
```go
// http 重定向
router.GET("/abc", func(c *gin.Context) {
c.Redirect(http.StatusMovedPermanently, "http://www.baidu.com/")
})
```
### 路由重定向
```go
// 路由重定向
router.GET("/def", func(c *gin.Context) {
c.Request.URL.Path = "/ping"
router.HandleContext(c)
})
```
## Gin路由
### 普通路由
```go
r.GET("/index", func(c *gin.Context) {...})
r.GET("/login", func(c *gin.Context) {...})
r.POST("/login", func(c *gin.Context) {...})
```
### any
```go
r.Any("/test", func(c *gin.Context) {...})
```
### 404页面
```go
r.NoRoute(func(c *gin.Context) {
c.HTML(http.StatusNotFound, "views/404.html", nil)
})
```
### 路由组
我们可以将拥有共同URL前缀的路由划分为一个路由组。习惯性一对`{}`包裹同组的路由,这只是为了看着清晰,你用不用`{}`包裹功能上没什么区别。
```go
func main() {
r := gin.Default()
userGroup := r.Group("/user")
{
userGroup.GET("/index", func(c *gin.Context) {...})
userGroup.GET("/login", func(c *gin.Context) {...})
userGroup.POST("/login", func(c *gin.Context) {...})
}
shopGroup := r.Group("/shop")
{
shopGroup.GET("/index", func(c *gin.Context) {...})
shopGroup.GET("/cart", func(c *gin.Context) {...})
shopGroup.POST("/checkout", func(c *gin.Context) {...})
}
r.Run()
}
```
路由组也是支持嵌套的,例如:
```go
shopGroup := r.Group("/shop")
{
shopGroup.GET("/index", func(c *gin.Context) {...})
shopGroup.GET("/cart", func(c *gin.Context) {...})
shopGroup.POST("/checkout", func(c *gin.Context) {...})
// 嵌套路由组
xx := shopGroup.Group("xx")
xx.GET("/oo", func(c *gin.Context) {...})
}
```
通常我们将路由分组用在划分业务逻辑或划分API版本时。
### 路由原理
Gin框架中的路由使用的是[httprouter](https://github.com/julienschmidt/httprouter)这个库。
其基本原理就是构造一个路由地址的前缀树。

BIN
GO学习/assets/Gin框架/image-20250617112721609-17501308421881.png

After

Width: 722  |  Height: 393  |  Size: 58 KiB

BIN
GO学习/assets/Gin框架/image-20250617112721609.png

After

Width: 722  |  Height: 393  |  Size: 58 KiB

BIN
GO学习/assets/Gin框架/image-20250617112936947.png

After

Width: 389  |  Height: 152  |  Size: 6.0 KiB

BIN
GO学习/assets/Gin框架/image-20250617114457929.png

After

Width: 587  |  Height: 476  |  Size: 22 KiB

BIN
GO学习/assets/Gin框架/image-20250617115733445.png

After

Width: 861  |  Height: 237  |  Size: 15 KiB

89
Git命令.md

@ -0,0 +1,89 @@
# Git命令
## 一、仓库初始化与克隆
- **`git init`** —— 初始化本地仓库
- **`git clone <url>`** —— 克隆远程仓库
## 二、文件操作与提交
- **`git add <file>`** —— 添加单个文件到暂存区
- **`git add .`** —— 添加所有文件到暂存区
- **`git commit -m "msg"`** —— 提交暂存区到本地仓库
- **`git status`** —— 查看工作区状态
- **`git log`** —— 查看提交历史
- **`git diff`** —— 查看工作区与暂存区的差异
## 三、分支管理
- **查看分支**
- `git branch` —— 查看本地分支
- **创建分支**
- `git branch <name>` —— 创建新分支
- `git checkout -b <name>` —— 创建并切换分支
- **切换分支**
- `git checkout <name>` —— 切换分支
- **合并分支**
- `git merge <name>` —— 合并指定分支到当前分支
- **删除分支**
- `git branch -d <name>` —— 删除已合并分支
- `git branch -D <name>` —— 强制删除分支
## 四、远程仓库操作
- **查看远程信息**
- `git remote -v` —— 查看远程仓库信息
- **添加远程仓库**
- `git remote add <name> <url>` —— 添加远程仓库
- **拉取与推送**
- `git pull <remote> <branch>` —— 拉取远程分支并合并
- `git push <remote> <branch>` —— 推送本地分支到远程
- `git push -u <remote> <branch>` —— 首次推送并关联上游分支
- **获取远程分支**
- `git fetch <remote>` —— 仅获取远程分支(不合并)
## 五、版本回退与撤销
- **撤销修改**
- `git checkout -- <file>` —— 撤销工作区修改
- `git reset HEAD <file>` —— 撤销暂存区修改
- **回退版本**
- `git reset --hard <commit>` —— 回退到指定提交
- `git revert <commit>` —— 撤销指定提交(生成新提交)
## 六、临时存储与标签
- **临时存储**
- `git stash` —— 临时保存当前修改
- `git stash pop` —— 恢复最近一次 stash
- **标签操作**
- `git tag <name>` —— 创建轻量标签
- `git tag -a <name> -m "msg"` —— 创建带注释标签
- `git tag` —— 查看所有标签
- `git push <remote> <tag>` —— 推送单个标签到远程
- `git push <remote> --tags` —— 推送所有标签
## 七、高级操作
- **变基与提交管理**
- `git rebase <branch>` —— 变基(线性化提交历史)
- `git cherry-pick <commit>` —— 复制指定提交到当前分支
- **代码追溯**
- `git blame <file>` —— 查看文件每行的修改历史
- `git bisect` —— 二分查找定位问题提交
## 八、配置管理
- **用户配置**
- `git config --global user.name "Your Name"` —— 设置用户名
- `git config --global user.email "you@example.com"` —— 设置邮箱
- **查看配置**
- `git config --list` —— 查看所有配置信息

BIN
assets/6-16_李慧学习记录/image-20250616180459370.png

Before

Width: 218  |  Height: 376  |  Size: 14 KiB

BIN
assets/6-16_李慧学习记录/image-20250616180518835.png

Before

Width: 240  |  Height: 441  |  Size: 11 KiB

BIN
assets/6-16股票学习/image-20250616114324156.png

Before

Width: 638  |  Height: 343  |  Size: 74 KiB

0
git

0
2025年6月11日学习记录.md → 学习记录/2025年6月11日学习记录.md

2
6-12_李慧学习记录.md → 学习记录/6-12_李慧学习记录.md

@ -35,7 +35,7 @@
| ------------------------------------------------------------ | | ------------------------------------------------------------ |
| 财务审核-充值审核:接口recharge/recharge问题,原测试服务器redis服务可能挂了 | | 财务审核-充值审核:接口recharge/recharge问题,原测试服务器redis服务可能挂了 |
| 财务审核-充值审核:支付凭证不显示,不显示图片,报502 原因:怀疑是代理问题 尝试:尝试ping 地址 ping [54.251.137.151](http://54.251.137.151) 可以 但是无法访问,是之前在服务器上的地址 | | 财务审核-充值审核:支付凭证不显示,不显示图片,报502 原因:怀疑是代理问题 尝试:尝试ping 地址 ping [54.251.137.151](http://54.251.137.151) 可以 但是无法访问,是之前在服务器上的地址 |
| 财务审核-充值审核:通过 接口 /audit/audit/goldedit java.lang.Exception: Failed to insert recharge data 数据插入异常 原因 审核状态为空时,进行通过或者驳回会出现(根本是有数据库的脏数据,recharge表和audit表数据不一致) |
| 财务审核-充值审核:通过 接口 /audit/audit/goldedit Java.lang.Exception: Failed to insert recharge data 数据插入异常 原因 审核状态为空时,进行通过或者驳回会出现(根本是有数据库的脏数据,recharge表和audit表数据不一致) |
| 财务审核-充值审核:驳回 接口 /audit/audit/edit无法使用 SQLSyntaxErrorException错误 | | 财务审核-充值审核:驳回 接口 /audit/audit/edit无法使用 SQLSyntaxErrorException错误 |
| 财务审核-充值审核:前后端数据不统一(调用了两个接口导致) | | 财务审核-充值审核:前后端数据不统一(调用了两个接口导致) |
| 财务审核-退款审核:驳回不显示驳回理由remark | | 财务审核-退款审核:驳回不显示驳回理由remark |

0
6-13_李慧学习报告.md → 学习记录/6-13_李慧学习报告.md

0
6-15_李慧学习记录.md → 学习记录/6-15_李慧学习记录.md

8
6-16_李慧学习记录.md → 学习记录/6-16_李慧学习记录.md

@ -67,7 +67,7 @@
#### 波浪的形态 #### 波浪的形态
<img src="assets/6-16股票学习/image-20250616114324156.png" alt="image-20250616114324156" style="zoom:50%;" />
![image-20250617150826018](assets/6-16_李慧学习记录/image-20250617150826018.png)
#### 波浪之间的比例 #### 波浪之间的比例
@ -132,14 +132,14 @@
# 工作内容 # 工作内容
![image-20250616180459370](assets/6-16_李慧学习记录/image-20250616180459370.png)
![image-20250617150903922](assets/6-16_李慧学习记录/image-20250617150903922.png)
# 学习内容 # 学习内容
![image-20250616180518835](assets/6-16_李慧学习记录/image-20250616180518835.png)
![image-20250617150917522](assets/6-16_李慧学习记录/image-20250617150917522.png)
# 明日计划 # 明日计划
1. 了解金币需求 1. 了解金币需求
2. 学习15-20页 `股票分析学从入门到精通` 2. 学习15-20页 `股票分析学从入门到精通`
3. 学习Gin框架
3. 学习Gin框架

583
学习记录/6-17_李慧学习记录.md

@ -0,0 +1,583 @@
# 股票知识
## 趋势理论
根据道氏理论,股票价格运动有三种趋势
主要趋势、次要趋势和短暂趋势
### 主要趋势
主要趋势是股票价格广泛或全面性上升或下降的变动情形,持续时间通常为一年或以上。
从大的角度来看上涨和下跌的变动
主要趋势上升的,被称为多头市场
主要趋势下降的,被称为空头市场
#### 多头市场
多头市场是指主要趋势为上升的市场状态,也称为主要上升趋势。
三阶段:进货期->十分稳定的上升和增多的交易量->交易沸腾,成交量上升
#### 空头市场
也称为主要下跌趋势,是股票市场的一种状态,其主要特征是股价普遍下降。
三阶段:出货期->恐慌期->下跌期(继续下跌)
### 次要趋势(修正趋势)
次要趋势是主要趋势的调整,与主要趋势方向相反,持续时间从3周到数月不等。
### 短暂趋势
短暂趋势是短期的波动,很少超过三个星期,通常少于6天
每日行情的波动,
长期投资者关注股价基本趋势,投机者关注修正趋势,短暂趋势重要性小,容易受人操控,一般不关注
### 道氏理论基本要点
#### 评价价格包容消化一切
### 如何判断大趋势运行方向
![image-20250617171603320](../股票/assets/6-17股票学习/image-20250617171603320.png)
通过趋势线
## 趋势理论延伸——趋势线
### 百分比回撤
通常,市场不会直线上升,也不会竖直跌落
![image-20250617172405667](../股票/assets/6-17股票学习/image-20250617172405667.png)
百分比回撤+蜡烛图结合 很有用
## 股票价格的运行规律
### 股价运行规律
1. 股价应在多空双方均衡位置上下波动。
2. 原有的平衡被打破后,股价将寻找新的平衡。
持续整理保持平衡—打破平衡—新的平衡—再打破平衡-……
### 支撑线和压力线
支撑线又称为抵抗线。股价下跌到某个位置,股价停止下跌,
压力线又称为阻力线。当股价上涨到某价位附近时,股价会停止上涨
![image-20250617174011011](../股票/assets/6-17股票学习/image-20250617174011011.png)
前期的高点和低点都是很重要的压力和支持
一条支撑线和压力线对当前时期股价变化影响的重要性有三方面的考虑:
1. 股价在这个区域持续时间的长短
2. 股价在这个区域伴随的成交量大小
3. 这个支撑区域或压力区域发生的时间,距离当前这个时期的远近
持续时间长,成交量大,离现在近,则影响大
### 趋势线和轨道线
#### 趋势线
趋势线是衡量价格变化趋势的
上升趋势,两个显著的低点连成一条直线,就是上升趋势线
下降趋势,两个显著的高点连成一条直线,就是下降趋势线
上升趋势线是支持线的一种下降趋势线是压力线的一种
##### 趋势线两种作用
1. 对股价今后的变动起约束
2. 趋势线被突破后,就说明股价下一步的趋势将要反向,越有效的趋势线被突破,其转势的信号越强烈
##### 怎么才算对趋势线的突破
1. 收盘价突破趋势线比日内的最高最低价突破趋势线重要;
2. 穿越趋势线后,离趋势线越远,突破越有效。人们可以根据各个股票的具体情况,自己制定一个界限,一般是用突破的幅度,如3%;
3. 穿越趋势线后,在趋势线的另一方停留的时间越长,突破越有效。
#### 轨道线
又称通道线,管道线
两条平行线组成一个轨道,这就是常说的上升和下降轨道即趋势线的平行线
管道线持续的时间越长,其意义越重大,一个长期的上升通道和下降通道被有效突破,它将代表着一个新趋势的开始。
#### 买卖法则
##### 上升趋势:一买三卖法则
一买:接触到趋势线买
三卖:接触到轨道线卖,突破管道线卖,跌破趋势线卖
![image-20250617175850502](../股票/assets/6-17股票学习/image-20250617175850502.png)
##### 下降趋势:一卖三买法则
一卖:接触趋势线卖
三买:接触管道线买,跌破管道线买,突破趋势线买
![image-20250617180547018](assets/6-17_李慧学习记录/image-20250617180547018.png)
# 学习内容-Gin框架的基本使用
## 下载与安装
> 更改环境变量 GOPATH
>
> 方便将包下载到其他的盘符目录
>
> 参考:[2024年go安装教程(Windows)包括配置GOPATH-CSDN博客](https://blog.csdn.net/weixin_63860405/article/details/139732041)
### 下载
```shell
go get -u github.com/gin-gonic/gin
```
![image-20250617112721609](../GO学习/assets/Gin框架/image-20250617112721609-17501308421881.png)
## 基础使用
### GET请求
```go
package main
import "github.com/gin-gonic/gin"
func main() {
router := gin.Default()
router.GET("/ping", func(c *gin.Context) {
c.JSON(200, gin.H{
"message": "Hello World!",
})
})
router.Run() // 监听并在 0.0.0.0:8080 上启动服务
// 默认是在8080端口启动服务,如果8080端口被占用,则自动寻找可用端口启动服务,可以指定端口
}
```
![image-20250617112936947](../GO学习/assets/Gin框架/image-20250617112936947.png)
### ANY请求
根据请求来选择(使用if else)
```go
// Any 请求
router.Any("/any", func(c *gin.Context) {
if c.Request.Method == "POST" {
c.JSON(200, gin.H{
"message": "POST",
})
} else if c.Request.Method == "GET" {
c.JSON(200, gin.H{
"message": "GET",
})
} else {
c.JSON(200, gin.H{
"message": "Any",
})
}
})
```
### POST请求
```go
// POST 请求
router.POST("/post", func(c *gin.Context) {
c.JSON(200, gin.H{
"message": "POST",
})
})
```
![image-20250617114457929](../GO学习/assets/Gin框架/image-20250617114457929.png)
## 参数获取
### 获取query string 参数
格式:URL `?`后携带参数
例如:/user/searcher?username=xxx&address=xxx
```go
// 获取参数,query string
router.GET("/user/search", func(c *gin.Context) {
username := c.DefaultQuery("username", "lihuibear")
address := c.Query("address")
// 返回json数据
c.JSON(200, gin.H{
"username": username,
"address": address,
})
})
```
![image-20250617115733445](../GO学习/assets/Gin框架/image-20250617115733445.png)
### 获取 form参数
当前端请求的数据通过form表单提交时,例如向`/user/search`发送一个POST请求,获取请求数据的方式如下:
```go
router.POST("/user/search_by_form", func(c *gin.Context) {
// DefaultPostForm取不到值时会返回指定的默认值
//username := c.DefaultPostForm("username", "小王子")
username := c.PostForm("username")
address := c.PostForm("address")
//输出json结果给调用方
c.JSON(http.StatusOK, gin.H{
"message": "ok",
"username": username,
"address": address,
})
})
```
### 获取JSON参数
当前端请求的数据通过JSON提交时,例如向`/json`发送一个JSON格式的POST请求,则获取请求参数的方式如下:
```go
//获取JSON参数
router.POST("/json", func(c *gin.Context) {
// 注意:下面为了举例子方便,暂时忽略了错误处理
b, _ := c.GetRawData() // 从c.Request.Body读取请求数据
// 定义map或结构体
var m map[string]interface{}
// 反序列化
_ = json.Unmarshal(b, &m)
c.JSON(http.StatusOK, m)
})
```
### 获取path参数
请求的参数通过URL路径传递,例如:`/user/search/小王子/沙河`。 获取请求URL路径中的参数的方式如下:
```go
// 获取path参数
router.GET("/user/search/:username/:address", func(c *gin.Context) {
username := c.Param("username")
address := c.Param("address")
//输出json结果给调用方
c.JSON(http.StatusOK, gin.H{
"message": "ok",
"username": username,
"address": address,
})
})
```
### 参数绑定 ShouldBind()
为了能够更方便的获取请求相关参数,提高开发效率,我们可以基于请求的`Content-Type`识别请求数据类型并利用反射机制自动提取请求中`QueryString`、`form表单`、`JSON`、`XML`等参数到结构体中。
```go
// 参数绑定
// 绑定JSON的示例 ({"user": "q1mi", "password": "123456"})
router.POST("/login_by_JSON", func(c *gin.Context) {
var login Login
if err := c.ShouldBind(&login); err == nil {
fmt.Printf("login info:%#v\n", login)
c.JSON(http.StatusOK, gin.H{
"user": login.User,
"password": login.Password,
})
} else {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
}
})
// 绑定form表单示例 (user=q1mi&password=123456)
router.POST("/login_by_form", func(c *gin.Context) {
var login Login
// ShouldBind()会根据请求的Content-Type自行选择绑定器
if err := c.ShouldBind(&login); err == nil {
c.JSON(http.StatusOK, gin.H{
"user": login.User,
"password": login.Password,
})
} else {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
}
})
// 绑定QueryString示例 (/loginQuery?user=q1mi&password=123456)
router.GET("/login_by_query", func(c *gin.Context) {
var login Login
// ShouldBind()会根据请求的Content-Type自行选择绑定器
if err := c.ShouldBind(&login); err == nil {
c.JSON(http.StatusOK, gin.H{
"user": login.User,
"password": login.Password,
})
} else {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
}
})
```
`ShouldBind`会按照下面的顺序解析请求中的数据完成绑定:
1. 如果是 `GET` 请求,只使用 `Form` 绑定引擎(`query`)。
2. 如果是 `POST` 请求,首先检查 `content-type` 是否为 `JSON``XML`,然后再使用 `Form`(`form-data`)。
## Gin渲染
我们首先定义一个存放模板文件的`templates`文件夹,然后在其内部按照业务分别定义一个`posts`文件夹和一个`users`文件夹。 `posts/index.html`文件的内容如下:
```template
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>posts/index</title>
</head>
<body>
{{.title}}
</body>
</html>
{{end}}
```
`users/index.html`文件的内容如下:
```template
{{define "users/index.html"}}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>users/index</title>
</head>
<body>
{{.title}}
</body>
</html>
{{end}}
```
Gin框架中使用`LoadHTMLGlob()`或者`LoadHTMLFiles()`方法进行HTML模板渲染。
```go
func main() {
r := gin.Default()
r.LoadHTMLGlob("templates/**/*")
//r.LoadHTMLFiles("templates/posts/index.html", "templates/users/index.html")
r.GET("/posts/index", func(c *gin.Context) {
c.HTML(http.StatusOK, "posts/index.html", gin.H{
"title": "posts/index",
})
})
r.GET("users/index", func(c *gin.Context) {
c.HTML(http.StatusOK, "users/index.html", gin.H{
"title": "users/index",
})
})
r.Run(":8080")
}
```
## 文件上传
### 单文件上传
```go
// 加载模板
router.LoadHTMLFiles("./templates/upload.html")
// 上传文件
router.GET("/upload", func(c *gin.Context) {
c.HTML(http.StatusOK, "upload.html", nil)
})
router.POST("/upload", func(c *gin.Context) {
// 接收用户上传文件的post请求
f, err := c.FormFile("avatar")
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{
"message": err.Error(),
})
return
}
// 保存到指定目录 dst
dst := "./upload/" + f.Filename
c.SaveUploadedFile(f, dst)
// 返回响应
c.JSON(http.StatusOK, gin.H{
"message": fmt.Sprintf("'%s' uploaded!", f.Filename),
})
})
```
### 多文件上传
```go
// 多文件上传
// 加载模板
router.LoadHTMLFiles("./templates/uploads.html")
// 显示多文件上传页面
router.GET("/multi-upload", func(c *gin.Context) {
c.HTML(http.StatusOK, "uploads.html", nil)
})
// 多文件上传
router.POST("/multi-upload", func(c *gin.Context) {
// Multipart form
form, err := c.MultipartForm()
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": "failed to parse multipart form"})
return
}
files := form.File["file"]
for index, file := range files {
log.Println(file.Filename)
dst := fmt.Sprintf("./upload/%s_%d", file.Filename, index)
if err := c.SaveUploadedFile(file, dst); err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
}
c.JSON(http.StatusOK, gin.H{
"message": fmt.Sprintf("%d files uploaded!", len(files)),
})
})
```
## 重定向
### http重定向
```go
// http 重定向
router.GET("/abc", func(c *gin.Context) {
c.Redirect(http.StatusMovedPermanently, "http://www.baidu.com/")
})
```
### 路由重定向
```go
// 路由重定向
router.GET("/def", func(c *gin.Context) {
c.Request.URL.Path = "/ping"
router.HandleContext(c)
})
```
## Gin路由
### 普通路由
```go
r.GET("/index", func(c *gin.Context) {...})
r.GET("/login", func(c *gin.Context) {...})
r.POST("/login", func(c *gin.Context) {...})
```
### any
```go
r.Any("/test", func(c *gin.Context) {...})
```
### 404页面
```go
r.NoRoute(func(c *gin.Context) {
c.HTML(http.StatusNotFound, "views/404.html", nil)
})
```
### 路由组
我们可以将拥有共同URL前缀的路由划分为一个路由组。习惯性一对`{}`包裹同组的路由,这只是为了看着清晰,你用不用`{}`包裹功能上没什么区别。
```go
func main() {
r := gin.Default()
userGroup := r.Group("/user")
{
userGroup.GET("/index", func(c *gin.Context) {...})
userGroup.GET("/login", func(c *gin.Context) {...})
userGroup.POST("/login", func(c *gin.Context) {...})
}
shopGroup := r.Group("/shop")
{
shopGroup.GET("/index", func(c *gin.Context) {...})
shopGroup.GET("/cart", func(c *gin.Context) {...})
shopGroup.POST("/checkout", func(c *gin.Context) {...})
}
r.Run()
}
```
路由组也是支持嵌套的,例如:
```go
shopGroup := r.Group("/shop")
{
shopGroup.GET("/index", func(c *gin.Context) {...})
shopGroup.GET("/cart", func(c *gin.Context) {...})
shopGroup.POST("/checkout", func(c *gin.Context) {...})
// 嵌套路由组
xx := shopGroup.Group("xx")
xx.GET("/oo", func(c *gin.Context) {...})
}
```
通常我们将路由分组用在划分业务逻辑或划分API版本时。
### 路由原理
Gin框架中的路由使用的是[httprouter](https://github.com/julienschmidt/httprouter)这个库。
其基本原理就是构造一个路由地址的前缀树。
# 明日计划
1. 学习Goframe框架
2. 学习股票知识

BIN
学习记录/assets/6-16_李慧学习记录/image-20250617150826018.png

After

Width: 632  |  Height: 338  |  Size: 74 KiB

BIN
学习记录/assets/6-16_李慧学习记录/image-20250617150903922.png

After

Width: 234  |  Height: 413  |  Size: 48 KiB

BIN
学习记录/assets/6-16_李慧学习记录/image-20250617150917522.png

After

Width: 251  |  Height: 459  |  Size: 27 KiB

BIN
学习记录/assets/6-17_李慧学习记录/image-20250617180547018.png

After

Width: 450  |  Height: 297  |  Size: 43 KiB

2
6-16股票学习.md → 股票/6-16股票学习.md

@ -65,7 +65,7 @@
### 波浪的形态 ### 波浪的形态
![image-20250616114324156](assets/6-16股票学习/image-20250616114324156.png)
![image-20250617150944307](assets/6-16股票学习/image-20250617150944307.png)
### 波浪之间的比例 ### 波浪之间的比例

137
股票/6-17股票学习.md

@ -0,0 +1,137 @@
# 趋势理论
根据道氏理论,股票价格运动有三种趋势
主要趋势、次要趋势和短暂趋势
## 主要趋势
主要趋势是股票价格广泛或全面性上升或下降的变动情形,持续时间通常为一年或以上。
从大的角度来看上涨和下跌的变动
主要趋势上升的,被称为多头市场
主要趋势下降的,被称为空头市场
### 多头市场
多头市场是指主要趋势为上升的市场状态,也称为主要上升趋势。
三阶段:进货期->十分稳定的上升和增多的交易量->交易沸腾,成交量上升
### 空头市场
也称为主要下跌趋势,是股票市场的一种状态,其主要特征是股价普遍下降。
三阶段:出货期->恐慌期->下跌期(继续下跌)
## 次要趋势(修正趋势)
次要趋势是主要趋势的调整,与主要趋势方向相反,持续时间从3周到数月不等。
## 短暂趋势
短暂趋势是短期的波动,很少超过三个星期,通常少于6天
每日行情的波动,
长期投资者关注股价基本趋势,投机者关注修正趋势,短暂趋势重要性小,容易受人操控,一般不关注
## 道氏理论基本要点
### 评价价格包容消化一切
## 如何判断大趋势运行方向
![image-20250617171603320](assets/6-17股票学习/image-20250617171603320.png)
通过趋势线
# 趋势理论延伸——趋势线
## 百分比回撤
通常,市场不会直线上升,也不会竖直跌落
![image-20250617172405667](assets/6-17股票学习/image-20250617172405667.png)
百分比回撤+蜡烛图结合 很有用
# 股票价格的运行规律
## 股价运行规律
1. 股价应在多空双方均衡位置上下波动。
2. 原有的平衡被打破后,股价将寻找新的平衡。
持续整理保持平衡—打破平衡—新的平衡—再打破平衡-……
## 支撑线和压力线
支撑线又称为抵抗线。股价下跌到某个位置,股价停止下跌,
压力线又称为阻力线。当股价上涨到某价位附近时,股价会停止上涨
![image-20250617174011011](assets/6-17股票学习/image-20250617174011011.png)
前期的高点和低点都是很重要的压力和支持
一条支撑线和压力线对当前时期股价变化影响的重要性有三方面的考虑:
1. 股价在这个区域持续时间的长短
2. 股价在这个区域伴随的成交量大小
3. 这个支撑区域或压力区域发生的时间,距离当前这个时期的远近
持续时间长,成交量大,离现在近,则影响大
## 趋势线和轨道线
### 趋势线
趋势线是衡量价格变化趋势的
上升趋势,两个显著的低点连成一条直线,就是上升趋势线
下降趋势,两个显著的高点连成一条直线,就是下降趋势线
上升趋势线是支持线的一种下降趋势线是压力线的一种
#### 趋势线两种作用
1. 对股价今后的变动起约束
2. 趋势线被突破后,就说明股价下一步的趋势将要反向,越有效的趋势线被突破,其转势的信号越强烈
#### 怎么才算对趋势线的突破
1. 收盘价突破趋势线比日内的最高最低价突破趋势线重要;
2. 穿越趋势线后,离趋势线越远,突破越有效。人们可以根据各个股票的具体情况,自己制定一个界限,一般是用突破的幅度,如3%;
3. 穿越趋势线后,在趋势线的另一方停留的时间越长,突破越有效。
### 轨道线
又称通道线,管道线
两条平行线组成一个轨道,这就是常说的上升和下降轨道即趋势线的平行线
管道线持续的时间越长,其意义越重大,一个长期的上升通道和下降通道被有效突破,它将代表着一个新趋势的开始。
### 买卖法则
#### 上升趋势:一买三卖法则
一买:接触到趋势线买
三卖:接触到轨道线卖,突破管道线卖,跌破趋势线卖
![image-20250617175850502](assets/6-17股票学习/image-20250617175850502.png)
#### 下降趋势:一卖三买法则
一卖:接触趋势线卖
三买:接触管道线买,跌破管道线买,突破趋势线买
![image-20250617180042083](assets/6-17股票学习/image-20250617180042083.png)

BIN
股票/assets/6-16股票学习/image-20250617150944307.png

After

Width: 632  |  Height: 338  |  Size: 74 KiB

BIN
股票/assets/6-17股票学习/image-20250617171603320.png

After

Width: 441  |  Height: 258  |  Size: 70 KiB

BIN
股票/assets/6-17股票学习/image-20250617172405667.png

After

Width: 437  |  Height: 674  |  Size: 131 KiB

BIN
股票/assets/6-17股票学习/image-20250617174011011.png

After

Width: 423  |  Height: 312  |  Size: 35 KiB

BIN
股票/assets/6-17股票学习/image-20250617175850502.png

After

Width: 503  |  Height: 340  |  Size: 46 KiB

BIN
股票/assets/6-17股票学习/image-20250617180042083.png

After

Width: 530  |  Height: 313  |  Size: 46 KiB

Loading…
Cancel
Save