Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 80aee2f

Browse files
committed
Go每日一题完成
1 parent 7166d61 commit 80aee2f

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+964
-59
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,5 +51,6 @@ welcome.png
5151
/env.ini
5252
ssl
5353
bin
54+
tmp
5455

5556
*.code-workspace

cmd/studygolang/background.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,8 @@ func ServeBackGround() {
7676
// 首页推荐自动调整
7777
c.AddFunc("@every 5m", logic.DefaultFeed.AutoUpdateSeq)
7878

79+
// 每日题目
80+
c.AddFunc("@daily", logic.DefaultInterview.UpdateTodayQuestionID)
7981
}
8082

8183
// 两分钟刷一次浏览数(TODO:重启丢失问题?信号控制重启?)

config/db.sql

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -840,3 +840,19 @@ CREATE TABLE `wechat_auto_reply` (
840840
KEY `word` (`word`),
841841
KEY `updated_at` (`updated_at`)
842842
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='微信自动回复';
843+
844+
CREATE TABLE `interview_question` (
845+
`id` int(11) unsigned NOT NULL AUTO_INCREMENT COMMENT '自增id',
846+
`sn` bigint unsigned NOT NULL DEFAULT 0 COMMENT '题目序号,程序生成',
847+
`question` varchar(1022) NOT NULL DEFAULT '' COMMENT '问题',
848+
`answer` varchar(2046) NOT NULL DEFAULT '' COMMENT '答案',
849+
`level` tinyint unsigned NOT NULL DEFAULT 0 COMMENT '问题难易级别:0-低;1-中;2-高',
850+
`viewnum` int unsigned NOT NULL DEFAULT 0 COMMENT '浏览数',
851+
`cmtnum` int unsigned NOT NULL DEFAULT 0 COMMENT '评论数',
852+
`likenum` int unsigned NOT NULL DEFAULT 0 COMMENT '赞数',
853+
`source` varchar(31) NOT NULL DEFAULT '' COMMENT '题目来源',
854+
`created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
855+
PRIMARY KEY (`id`),
856+
UNIQUE KEY `sn` (`sn`),
857+
KEY `created_at` (`created_at`)
858+
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='Go面试题';

go.mod

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ require (
4545
github.com/polaris1119/nosql v0.0.0-20181019111233-3852ef28d084
4646
github.com/polaris1119/set v0.1.1-0.20160423093427-654439414ced
4747
github.com/polaris1119/slices v0.0.0-20160517071324-6ecacdb3cd38
48+
github.com/polaris1119/snowflake v0.1.0
4849
github.com/polaris1119/times v0.0.0-20160420102536-14f7f3ba487e
4950
github.com/qiniu/api.v6 v6.0.9+incompatible
5051
github.com/qiniu/bytes v0.0.0-20140728010635-4887e7b2bde3 // indirect
@@ -55,6 +56,7 @@ require (
5556
github.com/tidwall/gjson v1.12.1
5657
github.com/twinj/uuid v1.0.0
5758
github.com/tylerb/graceful v1.2.15
59+
github.com/yuin/goldmark v1.2.1
5860
golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3 // indirect
5961
golang.org/x/net v0.0.0-20220107192237-5cfca573fb4d
6062
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421

go.sum

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -368,6 +368,8 @@ github.com/polaris1119/set v0.1.1-0.20160423093427-654439414ced h1:5E6fZkU0PW8RI
368368
github.com/polaris1119/set v0.1.1-0.20160423093427-654439414ced/go.mod h1:f3pW74DeWib9bLGgMImip5zikwTB5dQ53JVrmT3CYrQ=
369369
github.com/polaris1119/slices v0.0.0-20160517071324-6ecacdb3cd38 h1:DUG5gZoTQGtKgQogadMFJ2hUCchqPBchezdHsgncEj4=
370370
github.com/polaris1119/slices v0.0.0-20160517071324-6ecacdb3cd38/go.mod h1:ZHrklmzhHyC2VcV6ef41IXDRFKyUKe0XtTrYqbMe50Y=
371+
github.com/polaris1119/snowflake v0.1.0 h1:cd2CAPliM8CUeg1jOyOXPIQdqh3xzT9++ihBmFXFaR8=
372+
github.com/polaris1119/snowflake v0.1.0/go.mod h1:MnAwXKmIDEw9zxfATCTpBwFpED0R4O2m0bc/K4sHOEc=
371373
github.com/polaris1119/times v0.0.0-20160420102536-14f7f3ba487e h1:t2A6UPUvJrNLdtIJAPFlCUkOAsqm7jYdGb1X82WAu/g=
372374
github.com/polaris1119/times v0.0.0-20160420102536-14f7f3ba487e/go.mod h1:PDQN4aTOykiTCCVTRdP/Tvsjdv//fUdWP9yZ2J3Ejn8=
373375
github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI=
@@ -459,6 +461,7 @@ github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyC
459461
github.com/valyala/fasttemplate v1.2.1 h1:TVEnxayobAdVkhQfrfes2IzOB6o+z4roRkPF52WA1u4=
460462
github.com/valyala/fasttemplate v1.2.1/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ=
461463
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
464+
github.com/yuin/goldmark v1.2.1 h1:ruQGxdhGHe7FWOJPT0mKs5+pD2Xs1Bm/kdGlHO04FmM=
462465
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
463466
github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q=
464467
github.com/ziutek/mymysql v1.5.4/go.mod h1:LMSpPZ6DbqWFxNCHW77HeMg9I646SAhApZ/wKdgO/C0=

http/controller/interview.go

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
// Copyright 2022 The StudyGolang Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style
3+
// license that can be found in the LICENSE file.
4+
// https://studygolang.com
5+
// Author: polaris [email protected]
6+
7+
package controller
8+
9+
import (
10+
"net/http"
11+
"strconv"
12+
"time"
13+
14+
"github.com/studygolang/studygolang/context"
15+
. "github.com/studygolang/studygolang/http"
16+
"github.com/studygolang/studygolang/http/middleware"
17+
"github.com/studygolang/studygolang/logic"
18+
"github.com/studygolang/studygolang/model"
19+
20+
echo "github.com/labstack/echo/v4"
21+
)
22+
23+
// 在需要评论(喜欢)且要回调的地方注册评论(喜欢)对象
24+
func init() {
25+
// 注册评论(喜欢)对象
26+
logic.RegisterCommentObject(model.TypeInterview, logic.InterviewComment{})
27+
logic.RegisterLikeObject(model.TypeInterview, logic.InterviewLike{})
28+
}
29+
30+
type InterviewController struct{}
31+
32+
// RegisterRoute 注册路由
33+
func (self InterviewController) RegisterRoute(g *echo.Group) {
34+
g.GET("/interview/question", self.TodayQuestion)
35+
g.GET("/interview/question/:show_sn", self.Find)
36+
37+
g.Match([]string{"GET", "POST"}, "/interview/new", self.Create, middleware.NeedLogin(), middleware.AdminAuth())
38+
}
39+
40+
func (InterviewController) Create(ctx echo.Context) error {
41+
question := ctx.FormValue("question")
42+
// 请求新建面试题页面
43+
if question == "" || ctx.Request().Method != "POST" {
44+
interview := &model.InterviewQuestion{}
45+
return render(ctx, "interview/new.html", map[string]interface{}{"interview": interview})
46+
}
47+
48+
forms, _ := ctx.FormParams()
49+
interview, err := logic.DefaultInterview.Publish(context.EchoContext(ctx), forms)
50+
if err != nil {
51+
return fail(ctx, 1, "内部服务错误!")
52+
}
53+
return success(ctx, interview)
54+
}
55+
56+
// TodayQuestion 今日题目
57+
func (ic InterviewController) TodayQuestion(ctx echo.Context) error {
58+
question := logic.DefaultInterview.TodayQuestion(context.EchoContext(ctx))
59+
60+
data := map[string]interface{}{
61+
"title": "Go每日一题 今日(" + time.Now().Format("2006-01-02") + ")",
62+
}
63+
return ic.detail(ctx, question, data)
64+
}
65+
66+
// Find 某个题目的详情
67+
func (ic InterviewController) Find(ctx echo.Context) error {
68+
showSn := ctx.Param("show_sn")
69+
sn, err := strconv.ParseInt(showSn, 32, 64)
70+
if err != nil {
71+
return ctx.Redirect(http.StatusSeeOther, "/interview/question?"+err.Error())
72+
}
73+
74+
question, err := logic.DefaultInterview.FindOne(context.EchoContext(ctx), sn)
75+
if err != nil || question.Id == 0 {
76+
return ctx.Redirect(http.StatusSeeOther, "/interview/question")
77+
}
78+
79+
data := map[string]interface{}{
80+
"title": "Go每日一题(" + strconv.Itoa(question.Id) + ")",
81+
}
82+
83+
return ic.detail(ctx, question, data)
84+
}
85+
86+
func (InterviewController) detail(ctx echo.Context, question *model.InterviewQuestion, data map[string]interface{}) error {
87+
data["question"] = question
88+
me, ok := ctx.Get("user").(*model.Me)
89+
if ok {
90+
data["likeflag"] = logic.DefaultLike.HadLike(context.EchoContext(ctx), me.Uid, question.Id, model.TypeInterview)
91+
// data["hadcollect"] = logic.DefaultFavorite.HadFavorite(context.EchoContext(ctx), me.Uid, question.Id, model.TypeInterview)
92+
93+
logic.Views.Incr(Request(ctx), model.TypeInterview, question.Id, me.Uid)
94+
95+
go logic.DefaultViewRecord.Record(question.Id, model.TypeInterview, me.Uid)
96+
97+
if me.IsRoot {
98+
data["view_user_num"] = logic.DefaultViewRecord.FindUserNum(context.EchoContext(ctx), question.Id, model.TypeInterview)
99+
data["view_source"] = logic.DefaultViewSource.FindOne(context.EchoContext(ctx), question.Id, model.TypeInterview)
100+
}
101+
} else {
102+
logic.Views.Incr(Request(ctx), model.TypeInterview, question.Id)
103+
}
104+
105+
return render(ctx, "interview/question.html,common/comment.html", data)
106+
}

http/controller/routes.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,8 @@ func RegisterRoutes(g *echo.Group) {
3838
new(LinkController).RegisterRoute(g)
3939
new(SubjectController).RegisterRoute(g)
4040
new(GCTTController).RegisterRoute(g)
41-
4241
new(FeedController).RegisterRoute(g)
42+
new(InterviewController).RegisterRoute(g)
4343

4444
new(WechatController).RegisterRoute(g)
4545

logic/comment.go

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -181,12 +181,13 @@ func (self CommentLogic) FindRecent(ctx context.Context, uid, objtype, limit int
181181
}
182182

183183
cmtObjs := []CommentObjecter{
184-
model.TypeTopic: TopicComment{},
185-
model.TypeArticle: ArticleComment{},
186-
model.TypeResource: ResourceComment{},
187-
model.TypeWiki: nil,
188-
model.TypeProject: ProjectComment{},
189-
model.TypeBook: BookComment{},
184+
model.TypeTopic: TopicComment{},
185+
model.TypeArticle: ArticleComment{},
186+
model.TypeResource: ResourceComment{},
187+
model.TypeWiki: nil,
188+
model.TypeProject: ProjectComment{},
189+
model.TypeBook: BookComment{},
190+
model.TypeInterview: InterviewComment{},
190191
}
191192
for cmtType, cmts := range cmtMap {
192193
self.fillObjinfos(cmts, cmtObjs[cmtType])
@@ -407,12 +408,13 @@ func (self CommentLogic) FindAll(ctx context.Context, paginator *Paginator, orde
407408
}
408409

409410
cmtObjs := []CommentObjecter{
410-
model.TypeTopic: TopicComment{},
411-
model.TypeArticle: ArticleComment{},
412-
model.TypeResource: ResourceComment{},
413-
model.TypeWiki: nil,
414-
model.TypeProject: ProjectComment{},
415-
model.TypeBook: BookComment{},
411+
model.TypeTopic: TopicComment{},
412+
model.TypeArticle: ArticleComment{},
413+
model.TypeResource: ResourceComment{},
414+
model.TypeWiki: nil,
415+
model.TypeProject: ProjectComment{},
416+
model.TypeBook: BookComment{},
417+
model.TypeInterview: InterviewComment{},
416418
}
417419
for cmtType, cmts := range cmtMap {
418420
self.fillObjinfos(cmts, cmtObjs[cmtType])

logic/common.go

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,15 +22,23 @@ import (
2222
"github.com/polaris1119/goutils"
2323
"github.com/polaris1119/logger"
2424
"github.com/polaris1119/nosql"
25+
"github.com/polaris1119/snowflake"
2526
"github.com/polaris1119/times"
2627
"golang.org/x/net/context"
2728
)
2829

29-
var schemaDecoder = schema.NewDecoder()
30+
var (
31+
schemaDecoder = schema.NewDecoder()
32+
33+
snowFlake *snowflake.SnowFlake
34+
)
3035

3136
func init() {
3237
schemaDecoder.SetAliasTag("json")
3338
schemaDecoder.IgnoreUnknownKeys(true)
39+
40+
startTime, _ := time.ParseInLocation("2006-01-02 15:04:05", "2022-01-10 00:00:00", time.UTC)
41+
snowFlake = snowflake.NewWith(startTime)
3442
}
3543

3644
var (

0 commit comments

Comments
 (0)