Skip to content

Commit 8ff9ca4

Browse files
committed
feat: 新增图形验证码功能
1 parent a5fbeee commit 8ff9ca4

File tree

6 files changed

+114
-2
lines changed

6 files changed

+114
-2
lines changed

app/tool/captcha/index.go

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package captcha
2+
3+
import (
4+
"github.com/quarkcloudio/quark-go/v3"
5+
"github.com/quarkcloudio/quark-go/v3/template/tool/captcha"
6+
)
7+
8+
type Index struct {
9+
captcha.Template
10+
}
11+
12+
// 初始化
13+
func (p *Index) Init(ctx *quark.Context) interface{} {
14+
15+
// 验证码长度
16+
p.Length = 4
17+
18+
return p
19+
}

app/tool/providers.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,13 @@
11
package service
22

3-
import "github.com/quarkcloudio/quark-go/v3/app/tool/upload"
3+
import (
4+
"github.com/quarkcloudio/quark-go/v3/app/tool/captcha"
5+
"github.com/quarkcloudio/quark-go/v3/app/tool/upload"
6+
)
47

58
// 注册服务
69
var Providers = []interface{}{
710
&upload.File{},
811
&upload.Image{},
12+
&captcha.Index{},
913
}

app/tool/qrcode/.keep

Whitespace-only changes.

engine.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ const (
2222
AppName = "QuarkGo"
2323

2424
// 版本号
25-
Version = "3.8.6"
25+
Version = "3.8.7"
2626

2727
// 包名
2828
PkgName = "github.com/quarkcloudio/quark-go/v3"

template/tool/captcha/captcha.go

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
package captcha
2+
3+
import (
4+
"bytes"
5+
"reflect"
6+
"time"
7+
8+
"github.com/dchest/captcha"
9+
"github.com/quarkcloudio/quark-go/v3"
10+
redisclient "github.com/quarkcloudio/quark-go/v3/dal/redis"
11+
)
12+
13+
// 文件上传
14+
type Template struct {
15+
quark.Template
16+
Length int // 验证码长度
17+
}
18+
19+
// 初始化
20+
func (p *Template) Init(ctx *quark.Context) interface{} {
21+
return p
22+
}
23+
24+
// 初始化模板
25+
func (p *Template) TemplateInit(ctx *quark.Context) interface{} {
26+
27+
// 如果启动了redis缓存,验证码使用redis缓存
28+
if redisclient.Client != nil {
29+
captcha.SetCustomStore(&CaptchaStore{
30+
RedisClient: redisclient.Client,
31+
Expiration: time.Second * 1000,
32+
})
33+
}
34+
35+
return p
36+
}
37+
38+
// 初始化路由映射
39+
func (p *Template) RouteInit() interface{} {
40+
p.GET("/api/tool/captcha/:resource/getId", p.CaptchaId) // 登录获取验证码ID路由
41+
p.GET("/api/tool/captcha/:resource/getImage/:id", p.Captcha) // 登录验证码路由
42+
p.GET("/api/captcha/:resource/getId", p.CaptchaId) // 登录获取验证码ID路由
43+
p.GET("/api/captcha/:resource/getImage/:id", p.Captcha) // 登录验证码路由
44+
45+
return p
46+
}
47+
48+
// 验证码ID
49+
func (p *Template) CaptchaId(ctx *quark.Context) error {
50+
length := int(reflect.
51+
ValueOf(ctx.Template).
52+
Elem().
53+
FieldByName("Length").Int())
54+
55+
return ctx.JSONOk("获取成功", map[string]string{
56+
"captchaId": captcha.NewLen(length),
57+
})
58+
}
59+
60+
// 生成验证码
61+
func (p *Template) Captcha(ctx *quark.Context) error {
62+
id := ctx.Param("id")
63+
writer := bytes.Buffer{}
64+
captcha.WriteImage(&writer, id, 110, 38)
65+
ctx.Write(writer.Bytes())
66+
return nil
67+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package captcha
2+
3+
import (
4+
"context"
5+
"time"
6+
7+
"github.com/redis/go-redis/v9"
8+
)
9+
10+
type CaptchaStore struct {
11+
RedisClient *redis.Client
12+
Expiration time.Duration
13+
}
14+
15+
func (store *CaptchaStore) Set(id string, digits []byte) {
16+
store.RedisClient.Set(context.Background(), id, string(digits), store.Expiration)
17+
}
18+
19+
func (store *CaptchaStore) Get(id string, clear bool) (digits []byte) {
20+
bytes, _ := store.RedisClient.Get(context.Background(), id).Bytes()
21+
return bytes
22+
}

0 commit comments

Comments
 (0)