feat: add scrap

pull/376/head
textworld 1 year ago
parent 927be7bd76
commit 6012ea73d6

2
.gitmodules vendored

@ -1,3 +1,3 @@
[submodule "resources/template/theme/default-theme-anatole"]
path = resources/template/theme/default-theme-anatole
url = https://github.com/go-sonic/default-theme-anatole.git
url = https://github.com/textworld/default-theme-anatole.git

@ -5,8 +5,8 @@ server:
logging:
filename: sonic.log
level:
app: debug # debug,info,warn,error
gorm: info # info,warn,error,silent
app: error # debug,info,warn,error
gorm: error # info,warn,error,silent
maxsize: 10 # 单位 megabytes
maxage: 30 #单位 天
compress: false # 是否对旧日志使用gzip进行压缩
@ -16,17 +16,17 @@ logging:
### The Database configuration,You should choose one between MySQL and SQLite3,if both MySQL and SQLite3 are configured ,use Sqlite3 first
sqlite3:
enable: true
enable: false
### mysql数据库配置,请将用户名、密码、ip地址、端口、数据库名称替换为你自己的配置
### mysql database configuration, please replace the user name, password, ip address, port, database name to your own configuration.
mysql:
dsn: root:12345678@tcp(127.0.0.1:3306)/sonicdb?charset=utf8mb4&parseTime=True&loc=Local&interpolateParams=true
dsn: wordpress:wordpress@tcp(127.0.0.1:33306)/wordpress?charset=utf8mb4&parseTime=True&loc=Local&interpolateParams=true
sonic:
mode: "development"
mode: "production"
work_dir: "./" # 不填默认为当前路径,用来存放日志文件、数据库文件、模板、上传的附件等(The default is the current directory. Used to store log files, database files, templates, upload files)
log_dir: "./logs" # 不填则使用work_dir 路径下的log路径 (If it is empty, use the "log" path under work_dir)
admin_url_path: admin_random

@ -16,29 +16,31 @@ import (
)
var (
Q = new(Query)
Attachment *attachment
Category *category
Comment *comment
CommentBlack *commentBlack
Journal *journal
Link *link
Log *log
Menu *menu
Meta *meta
Option *option
Photo *photo
Post *post
PostCategory *postCategory
PostTag *postTag
ScrapPage *scrapPage
Tag *tag
ThemeSetting *themeSetting
User *user
Q = new(Query)
ApplicationPassword *applicationPassword
Attachment *attachment
Category *category
Comment *comment
CommentBlack *commentBlack
Journal *journal
Link *link
Log *log
Menu *menu
Meta *meta
Option *option
Photo *photo
Post *post
PostCategory *postCategory
PostTag *postTag
ScrapPage *scrapPage
Tag *tag
ThemeSetting *themeSetting
User *user
)
func SetDefault(db *gorm.DB, opts ...gen.DOOption) {
*Q = *Use(db, opts...)
ApplicationPassword = &Q.ApplicationPassword
Attachment = &Q.Attachment
Category = &Q.Category
Comment = &Q.Comment
@ -61,74 +63,77 @@ func SetDefault(db *gorm.DB, opts ...gen.DOOption) {
func Use(db *gorm.DB, opts ...gen.DOOption) *Query {
return &Query{
db: db,
Attachment: newAttachment(db, opts...),
Category: newCategory(db, opts...),
Comment: newComment(db, opts...),
CommentBlack: newCommentBlack(db, opts...),
Journal: newJournal(db, opts...),
Link: newLink(db, opts...),
Log: newLog(db, opts...),
Menu: newMenu(db, opts...),
Meta: newMeta(db, opts...),
Option: newOption(db, opts...),
Photo: newPhoto(db, opts...),
Post: newPost(db, opts...),
PostCategory: newPostCategory(db, opts...),
PostTag: newPostTag(db, opts...),
ScrapPage: newScrapPage(db, opts...),
Tag: newTag(db, opts...),
ThemeSetting: newThemeSetting(db, opts...),
User: newUser(db, opts...),
db: db,
ApplicationPassword: newApplicationPassword(db, opts...),
Attachment: newAttachment(db, opts...),
Category: newCategory(db, opts...),
Comment: newComment(db, opts...),
CommentBlack: newCommentBlack(db, opts...),
Journal: newJournal(db, opts...),
Link: newLink(db, opts...),
Log: newLog(db, opts...),
Menu: newMenu(db, opts...),
Meta: newMeta(db, opts...),
Option: newOption(db, opts...),
Photo: newPhoto(db, opts...),
Post: newPost(db, opts...),
PostCategory: newPostCategory(db, opts...),
PostTag: newPostTag(db, opts...),
ScrapPage: newScrapPage(db, opts...),
Tag: newTag(db, opts...),
ThemeSetting: newThemeSetting(db, opts...),
User: newUser(db, opts...),
}
}
type Query struct {
db *gorm.DB
Attachment attachment
Category category
Comment comment
CommentBlack commentBlack
Journal journal
Link link
Log log
Menu menu
Meta meta
Option option
Photo photo
Post post
PostCategory postCategory
PostTag postTag
ScrapPage scrapPage
Tag tag
ThemeSetting themeSetting
User user
ApplicationPassword applicationPassword
Attachment attachment
Category category
Comment comment
CommentBlack commentBlack
Journal journal
Link link
Log log
Menu menu
Meta meta
Option option
Photo photo
Post post
PostCategory postCategory
PostTag postTag
ScrapPage scrapPage
Tag tag
ThemeSetting themeSetting
User user
}
func (q *Query) Available() bool { return q.db != nil }
func (q *Query) clone(db *gorm.DB) *Query {
return &Query{
db: db,
Attachment: q.Attachment.clone(db),
Category: q.Category.clone(db),
Comment: q.Comment.clone(db),
CommentBlack: q.CommentBlack.clone(db),
Journal: q.Journal.clone(db),
Link: q.Link.clone(db),
Log: q.Log.clone(db),
Menu: q.Menu.clone(db),
Meta: q.Meta.clone(db),
Option: q.Option.clone(db),
Photo: q.Photo.clone(db),
Post: q.Post.clone(db),
PostCategory: q.PostCategory.clone(db),
PostTag: q.PostTag.clone(db),
ScrapPage: q.ScrapPage.clone(db),
Tag: q.Tag.clone(db),
ThemeSetting: q.ThemeSetting.clone(db),
User: q.User.clone(db),
db: db,
ApplicationPassword: q.ApplicationPassword.clone(db),
Attachment: q.Attachment.clone(db),
Category: q.Category.clone(db),
Comment: q.Comment.clone(db),
CommentBlack: q.CommentBlack.clone(db),
Journal: q.Journal.clone(db),
Link: q.Link.clone(db),
Log: q.Log.clone(db),
Menu: q.Menu.clone(db),
Meta: q.Meta.clone(db),
Option: q.Option.clone(db),
Photo: q.Photo.clone(db),
Post: q.Post.clone(db),
PostCategory: q.PostCategory.clone(db),
PostTag: q.PostTag.clone(db),
ScrapPage: q.ScrapPage.clone(db),
Tag: q.Tag.clone(db),
ThemeSetting: q.ThemeSetting.clone(db),
User: q.User.clone(db),
}
}
@ -142,69 +147,72 @@ func (q *Query) WriteDB() *Query {
func (q *Query) ReplaceDB(db *gorm.DB) *Query {
return &Query{
db: db,
Attachment: q.Attachment.replaceDB(db),
Category: q.Category.replaceDB(db),
Comment: q.Comment.replaceDB(db),
CommentBlack: q.CommentBlack.replaceDB(db),
Journal: q.Journal.replaceDB(db),
Link: q.Link.replaceDB(db),
Log: q.Log.replaceDB(db),
Menu: q.Menu.replaceDB(db),
Meta: q.Meta.replaceDB(db),
Option: q.Option.replaceDB(db),
Photo: q.Photo.replaceDB(db),
Post: q.Post.replaceDB(db),
PostCategory: q.PostCategory.replaceDB(db),
PostTag: q.PostTag.replaceDB(db),
ScrapPage: q.ScrapPage.replaceDB(db),
Tag: q.Tag.replaceDB(db),
ThemeSetting: q.ThemeSetting.replaceDB(db),
User: q.User.replaceDB(db),
db: db,
ApplicationPassword: q.ApplicationPassword.replaceDB(db),
Attachment: q.Attachment.replaceDB(db),
Category: q.Category.replaceDB(db),
Comment: q.Comment.replaceDB(db),
CommentBlack: q.CommentBlack.replaceDB(db),
Journal: q.Journal.replaceDB(db),
Link: q.Link.replaceDB(db),
Log: q.Log.replaceDB(db),
Menu: q.Menu.replaceDB(db),
Meta: q.Meta.replaceDB(db),
Option: q.Option.replaceDB(db),
Photo: q.Photo.replaceDB(db),
Post: q.Post.replaceDB(db),
PostCategory: q.PostCategory.replaceDB(db),
PostTag: q.PostTag.replaceDB(db),
ScrapPage: q.ScrapPage.replaceDB(db),
Tag: q.Tag.replaceDB(db),
ThemeSetting: q.ThemeSetting.replaceDB(db),
User: q.User.replaceDB(db),
}
}
type queryCtx struct {
Attachment *attachmentDo
Category *categoryDo
Comment *commentDo
CommentBlack *commentBlackDo
Journal *journalDo
Link *linkDo
Log *logDo
Menu *menuDo
Meta *metaDo
Option *optionDo
Photo *photoDo
Post *postDo
PostCategory *postCategoryDo
PostTag *postTagDo
ScrapPage *scrapPageDo
Tag *tagDo
ThemeSetting *themeSettingDo
User *userDo
ApplicationPassword *applicationPasswordDo
Attachment *attachmentDo
Category *categoryDo
Comment *commentDo
CommentBlack *commentBlackDo
Journal *journalDo
Link *linkDo
Log *logDo
Menu *menuDo
Meta *metaDo
Option *optionDo
Photo *photoDo
Post *postDo
PostCategory *postCategoryDo
PostTag *postTagDo
ScrapPage *scrapPageDo
Tag *tagDo
ThemeSetting *themeSettingDo
User *userDo
}
func (q *Query) WithContext(ctx context.Context) *queryCtx {
return &queryCtx{
Attachment: q.Attachment.WithContext(ctx),
Category: q.Category.WithContext(ctx),
Comment: q.Comment.WithContext(ctx),
CommentBlack: q.CommentBlack.WithContext(ctx),
Journal: q.Journal.WithContext(ctx),
Link: q.Link.WithContext(ctx),
Log: q.Log.WithContext(ctx),
Menu: q.Menu.WithContext(ctx),
Meta: q.Meta.WithContext(ctx),
Option: q.Option.WithContext(ctx),
Photo: q.Photo.WithContext(ctx),
Post: q.Post.WithContext(ctx),
PostCategory: q.PostCategory.WithContext(ctx),
PostTag: q.PostTag.WithContext(ctx),
ScrapPage: q.ScrapPage.WithContext(ctx),
Tag: q.Tag.WithContext(ctx),
ThemeSetting: q.ThemeSetting.WithContext(ctx),
User: q.User.WithContext(ctx),
ApplicationPassword: q.ApplicationPassword.WithContext(ctx),
Attachment: q.Attachment.WithContext(ctx),
Category: q.Category.WithContext(ctx),
Comment: q.Comment.WithContext(ctx),
CommentBlack: q.CommentBlack.WithContext(ctx),
Journal: q.Journal.WithContext(ctx),
Link: q.Link.WithContext(ctx),
Log: q.Log.WithContext(ctx),
Menu: q.Menu.WithContext(ctx),
Meta: q.Meta.WithContext(ctx),
Option: q.Option.WithContext(ctx),
Photo: q.Photo.WithContext(ctx),
Post: q.Post.WithContext(ctx),
PostCategory: q.PostCategory.WithContext(ctx),
PostTag: q.PostTag.WithContext(ctx),
ScrapPage: q.ScrapPage.WithContext(ctx),
Tag: q.Tag.WithContext(ctx),
ThemeSetting: q.ThemeSetting.WithContext(ctx),
User: q.User.WithContext(ctx),
}
}

@ -28,14 +28,17 @@ func newScrapPage(db *gorm.DB, opts ...gen.DOOption) scrapPage {
tableName := _scrapPage.scrapPageDo.TableName()
_scrapPage.ALL = field.NewAsterisk(tableName)
_scrapPage.ID = field.NewInt32(tableName, "id")
_scrapPage.CreateTime = field.NewTime(tableName, "create_time")
_scrapPage.UpdateTime = field.NewTime(tableName, "update_time")
_scrapPage.Title = field.NewString(tableName, "title")
_scrapPage.Md5 = field.NewString(tableName, "md5")
_scrapPage.URL = field.NewString(tableName, "url")
_scrapPage.OriginURL = field.NewString(tableName, "origin_url")
_scrapPage.Content = field.NewString(tableName, "content")
_scrapPage.Summary = field.NewString(tableName, "summary")
_scrapPage.CreateAt = field.NewInt64(tableName, "create_at")
_scrapPage.Domain = field.NewString(tableName, "domain")
_scrapPage.OutLink = field.NewString(tableName, "out_link")
_scrapPage.Resource = field.NewString(tableName, "resource")
_scrapPage.Attachment = field.NewInt32(tableName, "attachment")
_scrapPage.fillFieldMap()
@ -45,16 +48,19 @@ func newScrapPage(db *gorm.DB, opts ...gen.DOOption) scrapPage {
type scrapPage struct {
scrapPageDo scrapPageDo
ALL field.Asterisk
ID field.Int32
Title field.String
Md5 field.String
URL field.String
Content field.String
Summary field.String
CreateAt field.Int64
Domain field.String
OutLink field.String
ALL field.Asterisk
ID field.Int32
CreateTime field.Time
UpdateTime field.Time
Title field.String
Md5 field.String
URL field.String
OriginURL field.String
Content field.String
Summary field.String
Domain field.String
Resource field.String
Attachment field.Int32 // 附件
fieldMap map[string]field.Expr
}
@ -72,14 +78,17 @@ func (s scrapPage) As(alias string) *scrapPage {
func (s *scrapPage) updateTableName(table string) *scrapPage {
s.ALL = field.NewAsterisk(table)
s.ID = field.NewInt32(table, "id")
s.CreateTime = field.NewTime(table, "create_time")
s.UpdateTime = field.NewTime(table, "update_time")
s.Title = field.NewString(table, "title")
s.Md5 = field.NewString(table, "md5")
s.URL = field.NewString(table, "url")
s.OriginURL = field.NewString(table, "origin_url")
s.Content = field.NewString(table, "content")
s.Summary = field.NewString(table, "summary")
s.CreateAt = field.NewInt64(table, "create_at")
s.Domain = field.NewString(table, "domain")
s.OutLink = field.NewString(table, "out_link")
s.Resource = field.NewString(table, "resource")
s.Attachment = field.NewInt32(table, "attachment")
s.fillFieldMap()
@ -106,16 +115,19 @@ func (s *scrapPage) GetFieldByName(fieldName string) (field.OrderExpr, bool) {
}
func (s *scrapPage) fillFieldMap() {
s.fieldMap = make(map[string]field.Expr, 9)
s.fieldMap = make(map[string]field.Expr, 12)
s.fieldMap["id"] = s.ID
s.fieldMap["create_time"] = s.CreateTime
s.fieldMap["update_time"] = s.UpdateTime
s.fieldMap["title"] = s.Title
s.fieldMap["md5"] = s.Md5
s.fieldMap["url"] = s.URL
s.fieldMap["origin_url"] = s.OriginURL
s.fieldMap["content"] = s.Content
s.fieldMap["summary"] = s.Summary
s.fieldMap["create_at"] = s.CreateAt
s.fieldMap["domain"] = s.Domain
s.fieldMap["out_link"] = s.OutLink
s.fieldMap["resource"] = s.Resource
s.fieldMap["attachment"] = s.Attachment
}
func (s scrapPage) clone(db *gorm.DB) scrapPage {

@ -48,6 +48,7 @@ require (
github.com/Microsoft/go-winio v0.6.1 // indirect
github.com/ProtonMail/go-crypto v0.0.0-20230923063757-afb1ddc0824c // indirect
github.com/acomagu/bufpipe v1.0.4 // indirect
github.com/aws/aws-sdk-go v1.49.6 // indirect
github.com/boombuler/barcode v1.0.1 // indirect
github.com/bytedance/sonic v1.10.2 // indirect
github.com/chenzhuoyu/base64x v0.0.0-20230717121745-296ad89f973d // indirect
@ -71,6 +72,7 @@ require (
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect
github.com/jinzhu/inflection v1.0.0 // indirect
github.com/jinzhu/now v1.1.5 // indirect
github.com/jmespath/go-jmespath v0.4.0 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/kevinburke/ssh_config v1.2.0 // indirect
github.com/klauspost/compress v1.17.1 // indirect

@ -61,6 +61,8 @@ github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be h1:9AeTilPcZAjCFI
github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be/go.mod h1:ySMOLuWl6zY27l47sB3qLNK6tF2fkHG55UZxx8oIVo4=
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio=
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs=
github.com/aws/aws-sdk-go v1.49.6 h1:yNldzF5kzLBRvKlKz1S0bkvc2+04R1kt13KfBWQBfFA=
github.com/aws/aws-sdk-go v1.49.6/go.mod h1:LF8svs817+Nz+DmiMQKTO3ubZ/6IaTpq3TjupRn3Eqk=
github.com/benbjohnson/clock v1.3.0 h1:ip6w0uFQkncKQ979AypyG0ER7mqUSBdKLOgAle/AT8A=
github.com/benbjohnson/clock v1.3.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
github.com/boombuler/barcode v1.0.1-0.20190219062509-6c824513bacc/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8=
@ -255,6 +257,9 @@ github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkr
github.com/jinzhu/now v1.1.4/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ=
github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg=
github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo=
github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U=
github.com/jordan-wright/email v4.0.1-0.20210109023952-943e75fe5223+incompatible h1:jdpOPRN1zP63Td1hDQbZW73xKmzDvZHzVdNYxhnTMDA=
github.com/jordan-wright/email v4.0.1-0.20210109023952-943e75fe5223+incompatible/go.mod h1:1c7szIrayyPPB/987hsnvNzLushdWf4o/79s3P08L8A=
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
@ -794,6 +799,7 @@ gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24
gopkg.in/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME=
gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=

@ -26,5 +26,6 @@ func init() {
NewUserHandler,
NewEmailHandler,
NewApplicationPasswordHandler,
NewScrapPageHandler,
)
}

@ -3,8 +3,11 @@ package admin
import (
"github.com/gin-gonic/gin"
"github.com/go-sonic/sonic/handler/binding"
"github.com/go-sonic/sonic/model/dto"
"github.com/go-sonic/sonic/model/param"
"github.com/go-sonic/sonic/service"
"github.com/go-sonic/sonic/util"
"github.com/go-sonic/sonic/util/xerr"
)
@ -23,16 +26,55 @@ func (handler *ScrapPageHandler) QueryMd5List(ctx *gin.Context) (interface{}, er
}
func (handler *ScrapPageHandler) Create(ctx *gin.Context) (interface{}, error) {
file, err := ctx.FormFile("file")
if err != nil {
return nil, xerr.BadParam.New("empty file").WithStatus(xerr.StatusBadRequest).WithMsg("empty files")
}
scrapPageParam := param.ScrapPage{}
err := ctx.ShouldBindJSON(&scrapPageParam)
err = ctx.ShouldBindWith(&scrapPageParam, binding.CustomFormBinding)
if err != nil {
return nil, xerr.BadParam.Wrap(err)
}
err = handler.ScrapService.Create(ctx, &scrapPageParam)
pageDTO, err := handler.ScrapService.Create(ctx, &scrapPageParam, file)
if err != nil {
return nil, err
}
return pageDTO, nil
}
func (handler *ScrapPageHandler) Get(ctx *gin.Context) {
pageID, err := util.ParamInt32(ctx, "id")
if err != nil {
ctx.String(400, "invalid pageId")
return
}
pageDTO, err := handler.ScrapService.Get(ctx, pageID)
if err != nil {
ctx.String(500, "fail ")
return
}
if len(pageDTO.Content) > 0 {
ctx.Header("Content-Type", "text/html; charset=utf-8")
ctx.String(200, pageDTO.Content)
} else {
ctx.String(200, "<p>empty</p>")
}
}
func (handler *ScrapPageHandler) Query(ctx *gin.Context) (interface{}, error) {
query := param.ScrapPageQuery{}
err := ctx.ShouldBindWith(&query, binding.CustomFormBinding)
if err != nil {
return nil, xerr.WithStatus(err, xerr.StatusBadRequest).WithMsg("Parameter error")
}
result, total, err := handler.ScrapService.Query(ctx, &query)
if err != nil {
return nil, err
}
return true, nil
return dto.NewPage(result, total, query.Page), nil
}

@ -15,5 +15,6 @@ func init() {
NewPhotoHandler,
NewJournalHandler,
NewSearchHandler,
NewScrapHandler,
)
}

@ -0,0 +1,50 @@
package content
import (
"github.com/gin-gonic/gin"
"github.com/go-sonic/sonic/model/dto"
"github.com/go-sonic/sonic/model/param"
"github.com/go-sonic/sonic/service"
"github.com/go-sonic/sonic/template"
"github.com/go-sonic/sonic/util"
"github.com/go-sonic/sonic/util/xerr"
)
type ScrapHandler struct {
ScrapService service.ScrapService
ThemeService service.ThemeService
OptionService service.OptionService
}
func NewScrapHandler(scrapService service.ScrapService, themeService service.ThemeService, optionService service.OptionService) *ScrapHandler {
return &ScrapHandler{
ScrapService: scrapService,
ThemeService: themeService,
OptionService: optionService,
}
}
func (handler *ScrapHandler) Index(ctx *gin.Context, model template.Model) (string, error) {
pageSize := handler.OptionService.GetIndexPageSize(ctx)
page, err := util.GetQueryInt32(ctx, "page", 1)
if err != nil {
return "", xerr.WithStatus(nil, int(xerr.StatusBadRequest)).WithMsg("查询不到文章信息")
}
query := &param.ScrapPageQuery{
Page: param.Page{
PageNum: int(page),
PageSize: pageSize,
},
}
pageList, total, err := handler.ScrapService.Query(ctx, query)
if err != nil {
return "", err
}
model["pages"] = dto.NewPage(pageList, total, param.Page{
PageNum: int(page),
PageSize: pageSize,
})
return handler.ThemeService.Render(ctx, "scrap")
}

@ -74,7 +74,7 @@ func (a *ApplicationPasswordMiddleware) GetWrapHandler() gin.HandlerFunc {
return
}
err = a.PasswordService.Update(ctx, *pwdEntity.ID, ctx.ClientIP())
err = a.PasswordService.Update(ctx, pwdEntity.ID, ctx.ClientIP())
if err != nil {
ctx.AbortWithStatusJSON(http.StatusInternalServerError, &dto.BaseDTO{
Status: http.StatusInternalServerError,

@ -64,6 +64,14 @@ func (s *Server) RegisterRouters() {
wpCompatibleRouter.GET("/categories", s.wrapWpHandler(s.WpCategoryHandler.List))
}
}
{
restAPIRouter := router.Group("/rest-api/")
restAPIRouter.Use(s.ApplicationPasswordMiddleware.GetWrapHandler())
{
restAPIRouter.GET("/scrap_page/md5_list", s.wrapHandler(s.ScrapPageHandler.QueryMd5List))
restAPIRouter.POST("/scrap_page", s.wrapHandler(s.ScrapPageHandler.Create))
}
}
{
adminAPIRouter := router.Group("/api/admin")
adminAPIRouter.Use(s.LogMiddleware.LoggerWithConfig(middleware.GinLoggerConfig{}), s.RecoveryMiddleware.RecoveryWithLogger(), s.InstallRedirectMiddleware.InstallRedirect())
@ -373,6 +381,11 @@ func (s *Server) RegisterRouters() {
contentAPIRouter.GET("/options/comment", s.wrapHandler(s.ContentAPIOptionHandler.Comment))
}
{
router.GET("/scrap_page/:id", s.ScrapPageHandler.Get)
router.GET("/api/scrap_page", s.wrapHandler(s.ScrapPageHandler.Query))
router.GET("/scrap_page", s.wrapHTMLHandler(s.ContentScrapHandler.Index))
}
}
}

@ -2,6 +2,7 @@ package handler
import (
"context"
"errors"
"fmt"
"net/http"
"os"
@ -62,6 +63,7 @@ type Server struct {
UserHandler *admin.UserHandler
EmailHandler *admin.EmailHandler
ApplicationPasswordHandler *admin.ApplicationPasswordHandler
ScrapPageHandler *admin.ScrapPageHandler
IndexHandler *content.IndexHandler
FeedHandler *content.FeedHandler
ArchiveHandler *content.ArchiveHandler
@ -73,6 +75,7 @@ type Server struct {
ContentPhotoHandler *content.PhotoHandler
ContentJournalHandler *content.JournalHandler
ContentSearchHandler *content.SearchHandler
ContentScrapHandler *content.ScrapHandler
ContentAPIArchiveHandler *api.ArchiveHandler
ContentAPICategoryHandler *api.CategoryHandler
ContentAPIJournalHandler *api.JournalHandler
@ -123,6 +126,7 @@ type ServerParams struct {
UserHandler *admin.UserHandler
EmailHandler *admin.EmailHandler
ApplicationPasswordHandler *admin.ApplicationPasswordHandler
ScrapPageHandler *admin.ScrapPageHandler
IndexHandler *content.IndexHandler
FeedHandler *content.FeedHandler
ArchiveHandler *content.ArchiveHandler
@ -134,6 +138,7 @@ type ServerParams struct {
ContentPhotoHandler *content.PhotoHandler
ContentJournalHandler *content.JournalHandler
ContentSearchHandler *content.SearchHandler
ContentScrapHandler *content.ScrapHandler
ContentAPIArchiveHandler *api.ArchiveHandler
ContentAPICategoryHandler *api.CategoryHandler
ContentAPIJournalHandler *api.JournalHandler
@ -183,6 +188,7 @@ func NewServer(param ServerParams, lifecycle fx.Lifecycle) *Server {
PhotoHandler: param.PhotoHandler,
PostHandler: param.PostHandler,
PostCommentHandler: param.PostCommentHandler,
ScrapPageHandler: param.ScrapPageHandler,
SheetHandler: param.SheetHandler,
SheetCommentHandler: param.SheetCommentHandler,
StatisticHandler: param.StatisticHandler,
@ -211,6 +217,7 @@ func NewServer(param ServerParams, lifecycle fx.Lifecycle) *Server {
ContentAPISheetHandler: param.ContentAPISheetHandler,
ContentAPIOptionHandler: param.ContentAPIOptionHandler,
ContentSearchHandler: param.ContentSearchHandler,
ContentScrapHandler: param.ContentScrapHandler,
ContentAPIPhotoHandler: param.ContentAPIPhotoHandler,
ApplicationPasswordHandler: param.ApplicationPasswordHandler,
WpPostHandler: param.WpPostHandler,
@ -230,7 +237,7 @@ func (s *Server) Run(ctx context.Context) error {
gin.SetMode(gin.DebugMode)
}
go func() {
if err := s.HTTPServer.ListenAndServe(); err != nil && err != http.ErrServerClosed {
if err := s.HTTPServer.ListenAndServe(); err != nil && !errors.Is(err, http.ErrServerClosed) {
// print err info when httpServer start failed
s.logger.Error("unexpected error from ListenAndServe", zap.Error(err))
fmt.Printf("http server start error:%s\n", err.Error())
@ -299,6 +306,8 @@ func (s *Server) wrapHTMLHandler(handler wrapperHTMLHandler) gin.HandlerFunc {
err = s.Template.ExecuteTemplate(ctx.Writer, templateName, model)
if err != nil {
s.logger.Error("render template err", zap.Error(err))
s.handleError(ctx, err)
return
}
}
}

@ -23,6 +23,8 @@ type BaseWpDTO struct {
type Page struct {
Content interface{} `json:"content"`
Pages int `json:"pages"`
PrePage int `json:"pre_page"`
NextPage int `json:"next_page"`
Total int64 `json:"total"`
RPP int `json:"rpp"`
PageNum int `json:"pageNum"`
@ -48,12 +50,14 @@ func NewPage(content interface{}, totalCount int64, page param.Page) *Page {
Content: content,
Total: totalCount,
Pages: totalPage,
PrePage: page.PageNum - 1,
NextPage: page.PageNum + 1,
PageNum: page.PageNum,
RPP: page.PageNum,
HasNext: page.PageNum+1 < totalPage,
HasPrevious: page.PageNum > 0,
IsFirst: page.PageNum == 0,
IsLast: page.PageNum+1 == totalPage,
HasNext: page.PageNum < totalPage,
HasPrevious: page.PageNum > 1,
IsFirst: page.PageNum == 1,
IsLast: page.PageNum == totalPage,
IsEmpty: contentLen == 0,
HasContent: contentLen > 0,
}

@ -0,0 +1,9 @@
package dto
type ScrapPageDTO struct {
ID int32 `json:"id"`
Content string `json:"content"`
Title string `json:"title"`
Summary string `json:"summary"`
URL string `json:"url"`
}

@ -12,14 +12,14 @@ const TableNameApplicationPassword = "application_password"
// ApplicationPassword mapped from table <application_password>
type ApplicationPassword struct {
ID *int32 `gorm:"column:id;type:INTEGER" json:"id"`
CreateTime time.Time `gorm:"column:create_time;type:datetime;not null" json:"create_time"`
UpdateTime *time.Time `gorm:"column:update_time;type:datetime" json:"update_time"`
ID int32 `gorm:"column:id;type:int(11);primaryKey;autoIncrement:true" json:"id"`
CreateTime time.Time `gorm:"column:create_time;type:datetime(6);not null" json:"create_time"`
UpdateTime *time.Time `gorm:"column:update_time;type:datetime(6)" json:"update_time"`
Name string `gorm:"column:name;type:varchar(32);not null" json:"name"`
Password string `gorm:"column:password;type:varchar(256);not null" json:"password"`
UserID int32 `gorm:"column:user_id;type:integer;not null" json:"user_id"`
LastActivateTime *time.Time `gorm:"column:last_activate_time;type:datetime" json:"last_activate_time"`
LastActivateIP string `gorm:"column:last_activate_ip;type:varchar(128);not null;default:'' not null" json:"last_activate_ip"`
UserID int32 `gorm:"column:user_id;type:int(11);not null" json:"user_id"`
LastActivateTime *time.Time `gorm:"column:last_activate_time;type:datetime(6)" json:"last_activate_time"`
LastActivateIP string `gorm:"column:last_activate_ip;type:varchar(128);not null" json:"last_activate_ip"`
}
// TableName ApplicationPassword's table name

@ -14,19 +14,19 @@ const TableNameAttachment = "attachment"
// Attachment mapped from table <attachment>
type Attachment struct {
ID int32 `gorm:"column:id;type:integer;primaryKey" json:"id"`
CreateTime time.Time `gorm:"column:create_time;type:datetime;not null" json:"create_time"`
UpdateTime *time.Time `gorm:"column:update_time;type:datetime" json:"update_time"`
ID int32 `gorm:"column:id;type:int(11);primaryKey;autoIncrement:true" json:"id"`
CreateTime time.Time `gorm:"column:create_time;type:datetime(6);not null;index:attachment_create_time,priority:1" json:"create_time"`
UpdateTime *time.Time `gorm:"column:update_time;type:datetime(6)" json:"update_time"`
FileKey string `gorm:"column:file_key;type:varchar(2047);not null" json:"file_key"`
Height int32 `gorm:"column:height;type:integer;not null" json:"height"`
MediaType string `gorm:"column:media_type;type:varchar(127);not null" json:"media_type"`
Height int32 `gorm:"column:height;type:int(11);not null" json:"height"`
MediaType string `gorm:"column:media_type;type:varchar(127);not null;index:attachment_media_type,priority:1" json:"media_type"`
Name string `gorm:"column:name;type:varchar(255);not null" json:"name"`
Path string `gorm:"column:path;type:varchar(1023);not null" json:"path"`
Size int64 `gorm:"column:size;type:bigint;not null" json:"size"`
Size int64 `gorm:"column:size;type:bigint(20);not null" json:"size"`
Suffix string `gorm:"column:suffix;type:varchar(50);not null" json:"suffix"`
ThumbPath string `gorm:"column:thumb_path;type:varchar(1023);not null" json:"thumb_path"`
Type consts.AttachmentType `gorm:"column:type;type:bigint;not null" json:"type"`
Width int32 `gorm:"column:width;type:integer;not null" json:"width"`
Type consts.AttachmentType `gorm:"column:type;type:bigint(20);not null" json:"type"`
Width int32 `gorm:"column:width;type:int(11);not null" json:"width"`
}
// TableName Attachment's table name

@ -14,17 +14,17 @@ const TableNameCategory = "category"
// Category mapped from table <category>
type Category struct {
ID int32 `gorm:"column:id;type:integer;primaryKey" json:"id"`
CreateTime time.Time `gorm:"column:create_time;type:datetime;not null" json:"create_time"`
UpdateTime *time.Time `gorm:"column:update_time;type:datetime" json:"update_time"`
ID int32 `gorm:"column:id;type:int(11);primaryKey;autoIncrement:true" json:"id"`
CreateTime time.Time `gorm:"column:create_time;type:datetime(6);not null" json:"create_time"`
UpdateTime *time.Time `gorm:"column:update_time;type:datetime(6)" json:"update_time"`
Description string `gorm:"column:description;type:varchar(100);not null" json:"description"`
Type consts.CategoryType `gorm:"column:type;type:tinyint;not null" json:"type"`
Name string `gorm:"column:name;type:varchar(255);not null" json:"name"`
ParentID int32 `gorm:"column:parent_id;type:integer;not null" json:"parent_id"`
Type consts.CategoryType `gorm:"column:type;type:tinyint(4);not null" json:"type"`
Name string `gorm:"column:name;type:varchar(255);not null;index:category_name,priority:1" json:"name"`
ParentID int32 `gorm:"column:parent_id;type:int(11);not null;index:category_parent_id,priority:1" json:"parent_id"`
Password string `gorm:"column:password;type:varchar(255);not null" json:"password"`
Slug string `gorm:"column:slug;type:varchar(255);not null" json:"slug"`
Slug string `gorm:"column:slug;type:varchar(255);not null;uniqueIndex:uniq_category_slug,priority:1" json:"slug"`
Thumbnail string `gorm:"column:thumbnail;type:varchar(1023);not null" json:"thumbnail"`
Priority int32 `gorm:"column:priority;type:integer;not null" json:"priority"`
Priority int32 `gorm:"column:priority;type:int(11);not null" json:"priority"`
}
// TableName Category's table name

@ -14,11 +14,11 @@ const TableNameComment = "comment"
// Comment mapped from table <comment>
type Comment struct {
ID int32 `gorm:"column:id;type:integer;primaryKey" json:"id"`
Type consts.CommentType `gorm:"column:type;type:bigint;not null" json:"type"`
CreateTime time.Time `gorm:"column:create_time;type:datetime;not null" json:"create_time"`
UpdateTime *time.Time `gorm:"column:update_time;type:datetime" json:"update_time"`
AllowNotification bool `gorm:"column:allow_notification;type:tinyint(1);not null;default:true" json:"allow_notification"`
ID int32 `gorm:"column:id;type:int(11);primaryKey;autoIncrement:true" json:"id"`
Type consts.CommentType `gorm:"column:type;type:bigint(20);not null;index:comment_type_status,priority:1" json:"type"`
CreateTime time.Time `gorm:"column:create_time;type:datetime(6);not null" json:"create_time"`
UpdateTime *time.Time `gorm:"column:update_time;type:datetime(6)" json:"update_time"`
AllowNotification bool `gorm:"column:allow_notification;type:tinyint(1);not null;default:1" json:"allow_notification"`
Author string `gorm:"column:author;type:varchar(50);not null" json:"author"`
AuthorURL string `gorm:"column:author_url;type:varchar(511);not null" json:"author_url"`
Content string `gorm:"column:content;type:varchar(1023);not null" json:"content"`
@ -26,10 +26,10 @@ type Comment struct {
GravatarMd5 string `gorm:"column:gravatar_md5;type:varchar(127);not null" json:"gravatar_md5"`
IPAddress string `gorm:"column:ip_address;type:varchar(127);not null" json:"ip_address"`
IsAdmin bool `gorm:"column:is_admin;type:tinyint(1);not null" json:"is_admin"`
ParentID int32 `gorm:"column:parent_id;type:integer;not null" json:"parent_id"`
PostID int32 `gorm:"column:post_id;type:integer;not null" json:"post_id"`
Status consts.CommentStatus `gorm:"column:status;type:bigint;not null" json:"status"`
TopPriority int32 `gorm:"column:top_priority;type:integer;not null" json:"top_priority"`
ParentID int32 `gorm:"column:parent_id;type:int(11);not null;index:comment_parent_id,priority:1" json:"parent_id"`
PostID int32 `gorm:"column:post_id;type:int(11);not null;index:comment_post_id,priority:1" json:"post_id"`
Status consts.CommentStatus `gorm:"column:status;type:bigint(20);not null;index:comment_type_status,priority:2" json:"status"`
TopPriority int32 `gorm:"column:top_priority;type:int(11);not null" json:"top_priority"`
UserAgent string `gorm:"column:user_agent;type:varchar(511);not null" json:"user_agent"`
}

@ -12,10 +12,10 @@ const TableNameCommentBlack = "comment_black"
// CommentBlack mapped from table <comment_black>
type CommentBlack struct {
ID *int32 `gorm:"column:id;type:integer;primaryKey" json:"id"`
CreateTime time.Time `gorm:"column:create_time;type:datetime;not null" json:"create_time"`
UpdateTime *time.Time `gorm:"column:update_time;type:datetime" json:"update_time"`
BanTime time.Time `gorm:"column:ban_time;type:datetime;not null" json:"ban_time"`
ID int32 `gorm:"column:id;type:int(11);primaryKey;autoIncrement:true" json:"id"`
CreateTime time.Time `gorm:"column:create_time;type:datetime(6);not null" json:"create_time"`
UpdateTime *time.Time `gorm:"column:update_time;type:datetime(6)" json:"update_time"`
BanTime time.Time `gorm:"column:ban_time;type:datetime(6);not null" json:"ban_time"`
IPAddress string `gorm:"column:ip_address;type:varchar(127);not null" json:"ip_address"`
}

@ -14,13 +14,13 @@ const TableNameJournal = "journal"
// Journal mapped from table <journal>
type Journal struct {
ID int32 `gorm:"column:id;type:integer;primaryKey" json:"id"`
CreateTime time.Time `gorm:"column:create_time;type:datetime;not null" json:"create_time"`
UpdateTime *time.Time `gorm:"column:update_time;type:datetime" json:"update_time"`
ID int32 `gorm:"column:id;type:int(11);primaryKey;autoIncrement:true" json:"id"`
CreateTime time.Time `gorm:"column:create_time;type:datetime(6);not null" json:"create_time"`
UpdateTime *time.Time `gorm:"column:update_time;type:datetime(6)" json:"update_time"`
Content string `gorm:"column:content;type:text;not null" json:"content"`
Likes int64 `gorm:"column:likes;type:bigint;not null" json:"likes"`
Likes int64 `gorm:"column:likes;type:bigint(20);not null" json:"likes"`
SourceContent string `gorm:"column:source_content;type:longtext;not null" json:"source_content"`
Type consts.JournalType `gorm:"column:type;type:bigint;not null" json:"type"`
Type consts.JournalType `gorm:"column:type;type:bigint(20);not null" json:"type"`
}
// TableName Journal's table name

@ -12,13 +12,13 @@ const TableNameLink = "link"
// Link mapped from table <link>
type Link struct {
ID int32 `gorm:"column:id;type:integer;primaryKey" json:"id"`
CreateTime time.Time `gorm:"column:create_time;type:datetime;not null" json:"create_time"`
UpdateTime *time.Time `gorm:"column:update_time;type:datetime" json:"update_time"`
ID int32 `gorm:"column:id;type:int(11);primaryKey;autoIncrement:true" json:"id"`
CreateTime time.Time `gorm:"column:create_time;type:datetime(6);not null" json:"create_time"`
UpdateTime *time.Time `gorm:"column:update_time;type:datetime(6)" json:"update_time"`
Description string `gorm:"column:description;type:varchar(255);not null" json:"description"`
Logo string `gorm:"column:logo;type:varchar(1023);not null" json:"logo"`
Name string `gorm:"column:name;type:varchar(255);not null" json:"name"`
Priority int32 `gorm:"column:priority;type:integer;not null" json:"priority"`
Name string `gorm:"column:name;type:varchar(255);not null;index:link_name,priority:1" json:"name"`
Priority int32 `gorm:"column:priority;type:int(11);not null" json:"priority"`
Team string `gorm:"column:team;type:varchar(255);not null" json:"team"`
URL string `gorm:"column:url;type:varchar(1023);not null" json:"url"`
}

@ -14,13 +14,13 @@ const TableNameLog = "log"
// Log mapped from table <log>
type Log struct {
ID int64 `gorm:"column:id;type:bigint;primaryKey" json:"id"`
CreateTime time.Time `gorm:"column:create_time;type:datetime;not null" json:"create_time"`
UpdateTime *time.Time `gorm:"column:update_time;type:datetime" json:"update_time"`
ID int64 `gorm:"column:id;type:bigint(20);primaryKey;autoIncrement:true" json:"id"`
CreateTime time.Time `gorm:"column:create_time;type:datetime(6);not null;index:log_create_time,priority:1" json:"create_time"`
UpdateTime *time.Time `gorm:"column:update_time;type:datetime(6)" json:"update_time"`
Content string `gorm:"column:content;type:varchar(1023);not null" json:"content"`
IPAddress string `gorm:"column:ip_address;type:varchar(127);not null" json:"ip_address"`
LogKey string `gorm:"column:log_key;type:varchar(1023);not null" json:"log_key"`
Type consts.LogType `gorm:"column:type;type:bigint;not null" json:"type"`
Type consts.LogType `gorm:"column:type;type:bigint(20);not null" json:"type"`
}
// TableName Log's table name

@ -12,13 +12,13 @@ const TableNameMenu = "menu"
// Menu mapped from table <menu>
type Menu struct {
ID int32 `gorm:"column:id;type:integer;primaryKey" json:"id"`
CreateTime time.Time `gorm:"column:create_time;type:datetime;not null" json:"create_time"`
UpdateTime *time.Time `gorm:"column:update_time;type:datetime" json:"update_time"`
ID int32 `gorm:"column:id;type:int(11);primaryKey;autoIncrement:true" json:"id"`
CreateTime time.Time `gorm:"column:create_time;type:datetime(6);not null" json:"create_time"`
UpdateTime *time.Time `gorm:"column:update_time;type:datetime(6)" json:"update_time"`
Icon string `gorm:"column:icon;type:varchar(50);not null" json:"icon"`
Name string `gorm:"column:name;type:varchar(50);not null" json:"name"`
ParentID int32 `gorm:"column:parent_id;type:integer;not null" json:"parent_id"`
Priority int32 `gorm:"column:priority;type:integer;not null" json:"priority"`
Name string `gorm:"column:name;type:varchar(50);not null;index:menu_name,priority:1" json:"name"`
ParentID int32 `gorm:"column:parent_id;type:int(11);not null;index:menu_parent_id,priority:1" json:"parent_id"`
Priority int32 `gorm:"column:priority;type:int(11);not null" json:"priority"`
Target string `gorm:"column:target;type:varchar(20);not null;default:_self" json:"target"`
Team string `gorm:"column:team;type:varchar(255);not null" json:"team"`
URL string `gorm:"column:url;type:varchar(1023);not null" json:"url"`

@ -14,12 +14,12 @@ const TableNameMeta = "meta"
// Meta mapped from table <meta>
type Meta struct {
ID int32 `gorm:"column:id;type:integer;primaryKey" json:"id"`
Type consts.MetaType `gorm:"column:type;type:bigint;not null" json:"type"`
CreateTime time.Time `gorm:"column:create_time;type:datetime;not null" json:"create_time"`
UpdateTime *time.Time `gorm:"column:update_time;type:datetime" json:"update_time"`
ID int32 `gorm:"column:id;type:int(11);primaryKey;autoIncrement:true" json:"id"`
Type consts.MetaType `gorm:"column:type;type:bigint(20);not null" json:"type"`
CreateTime time.Time `gorm:"column:create_time;type:datetime(6);not null" json:"create_time"`
UpdateTime *time.Time `gorm:"column:update_time;type:datetime(6)" json:"update_time"`
MetaKey string `gorm:"column:meta_key;type:varchar(255);not null" json:"meta_key"`
PostID int32 `gorm:"column:post_id;type:integer;not null" json:"post_id"`
PostID int32 `gorm:"column:post_id;type:int(11);not null" json:"post_id"`
MetaValue string `gorm:"column:meta_value;type:varchar(1023);not null" json:"meta_value"`
}

@ -14,11 +14,11 @@ const TableNameOption = "option"
// Option mapped from table <option>
type Option struct {
ID int32 `gorm:"column:id;type:integer;primaryKey" json:"id"`
CreateTime time.Time `gorm:"column:create_time;type:datetime;not null" json:"create_time"`
UpdateTime *time.Time `gorm:"column:update_time;type:datetime" json:"update_time"`
ID int32 `gorm:"column:id;type:int(11);primaryKey;autoIncrement:true" json:"id"`
CreateTime time.Time `gorm:"column:create_time;type:datetime(6);not null" json:"create_time"`
UpdateTime *time.Time `gorm:"column:update_time;type:datetime(6)" json:"update_time"`
OptionKey string `gorm:"column:option_key;type:varchar(100);not null" json:"option_key"`
Type consts.OptionType `gorm:"column:type;type:bigint;not null" json:"type"`
Type consts.OptionType `gorm:"column:type;type:bigint(20);not null" json:"type"`
OptionValue string `gorm:"column:option_value;type:longtext;not null" json:"option_value"`
}

@ -12,17 +12,17 @@ const TableNamePhoto = "photo"
// Photo mapped from table <photo>
type Photo struct {
ID *int32 `gorm:"column:id;type:integer;primaryKey" json:"id"`
CreateTime time.Time `gorm:"column:create_time;type:datetime;not null" json:"create_time"`
UpdateTime *time.Time `gorm:"column:update_time;type:datetime" json:"update_time"`
ID int32 `gorm:"column:id;type:int(11);primaryKey;autoIncrement:true" json:"id"`
CreateTime time.Time `gorm:"column:create_time;type:datetime(6);not null;index:photo_create_time,priority:1" json:"create_time"`
UpdateTime *time.Time `gorm:"column:update_time;type:datetime(6)" json:"update_time"`
Description string `gorm:"column:description;type:varchar(255);not null" json:"description"`
Location string `gorm:"column:location;type:varchar(255);not null" json:"location"`
Name string `gorm:"column:name;type:varchar(255);not null" json:"name"`
TakeTime *time.Time `gorm:"column:take_time;type:datetime" json:"take_time"`
Team string `gorm:"column:team;type:varchar(255);not null" json:"team"`
TakeTime *time.Time `gorm:"column:take_time;type:datetime(6)" json:"take_time"`
Team string `gorm:"column:team;type:varchar(255);not null;index:photo_team,priority:1" json:"team"`
Thumbnail string `gorm:"column:thumbnail;type:varchar(1023);not null" json:"thumbnail"`
URL string `gorm:"column:url;type:varchar(1023);not null" json:"url"`
Likes int64 `gorm:"column:likes;type:bigint;not null" json:"likes"`
Likes int64 `gorm:"column:likes;type:bigint(20);not null" json:"likes"`
}
// TableName Photo's table name

@ -14,28 +14,28 @@ const TableNamePost = "post"
// Post mapped from table <post>
type Post struct {
ID int32 `gorm:"column:id;type:integer;primaryKey" json:"id"`
Type consts.PostType `gorm:"column:type;type:bigint;not null" json:"type"`
CreateTime time.Time `gorm:"column:create_time;type:datetime;not null" json:"create_time"`
UpdateTime *time.Time `gorm:"column:update_time;type:datetime" json:"update_time"`
ID int32 `gorm:"column:id;type:int(11);primaryKey;autoIncrement:true" json:"id"`
Type consts.PostType `gorm:"column:type;type:bigint(20);not null;index:post_type_status,priority:1" json:"type"`
CreateTime time.Time `gorm:"column:create_time;type:datetime(6);not null;index:post_create_time,priority:1" json:"create_time"`
UpdateTime *time.Time `gorm:"column:update_time;type:datetime(6)" json:"update_time"`
DisallowComment bool `gorm:"column:disallow_comment;type:tinyint(1);not null" json:"disallow_comment"`
EditTime *time.Time `gorm:"column:edit_time;type:datetime" json:"edit_time"`
EditorType consts.EditorType `gorm:"column:editor_type;type:bigint;not null" json:"editor_type"`
EditTime *time.Time `gorm:"column:edit_time;type:datetime(6)" json:"edit_time"`
EditorType consts.EditorType `gorm:"column:editor_type;type:bigint(20);not null" json:"editor_type"`
FormatContent string `gorm:"column:format_content;type:longtext;not null" json:"format_content"`
Likes int64 `gorm:"column:likes;type:bigint;not null" json:"likes"`
Likes int64 `gorm:"column:likes;type:bigint(20);not null" json:"likes"`
MetaDescription string `gorm:"column:meta_description;type:varchar(1023);not null" json:"meta_description"`
MetaKeywords string `gorm:"column:meta_keywords;type:varchar(511);not null" json:"meta_keywords"`
OriginalContent string `gorm:"column:original_content;type:longtext;not null" json:"original_content"`
Password string `gorm:"column:password;type:varchar(255);not null" json:"password"`
Slug string `gorm:"column:slug;type:varchar(255);not null" json:"slug"`
Status consts.PostStatus `gorm:"column:status;type:bigint;not null;default:1" json:"status"`
Slug string `gorm:"column:slug;type:varchar(255);not null;uniqueIndex:uniq_post_slug,priority:1" json:"slug"`
Status consts.PostStatus `gorm:"column:status;type:bigint(20);not null;index:post_type_status,priority:2;default:1" json:"status"`
Summary string `gorm:"column:summary;type:longtext;not null" json:"summary"`
Template string `gorm:"column:template;type:varchar(255);not null" json:"template"`
Thumbnail string `gorm:"column:thumbnail;type:varchar(1023);not null" json:"thumbnail"`
Title string `gorm:"column:title;type:varchar(255);not null" json:"title"`
TopPriority int32 `gorm:"column:top_priority;type:integer;not null" json:"top_priority"`
Visits int64 `gorm:"column:visits;type:bigint;not null" json:"visits"`
WordCount int64 `gorm:"column:word_count;type:bigint;not null" json:"word_count"`
TopPriority int32 `gorm:"column:top_priority;type:int(11);not null" json:"top_priority"`
Visits int64 `gorm:"column:visits;type:bigint(20);not null" json:"visits"`
WordCount int64 `gorm:"column:word_count;type:bigint(20);not null" json:"word_count"`
}
// TableName Post's table name

@ -12,11 +12,11 @@ const TableNamePostCategory = "post_category"
// PostCategory mapped from table <post_category>
type PostCategory struct {
ID *int32 `gorm:"column:id;type:integer;primaryKey" json:"id"`
CreateTime time.Time `gorm:"column:create_time;type:datetime;not null" json:"create_time"`
UpdateTime *time.Time `gorm:"column:update_time;type:datetime" json:"update_time"`
CategoryID int32 `gorm:"column:category_id;type:integer;not null" json:"category_id"`
PostID int32 `gorm:"column:post_id;type:integer;not null" json:"post_id"`
ID int32 `gorm:"column:id;type:int(11);primaryKey;autoIncrement:true" json:"id"`
CreateTime time.Time `gorm:"column:create_time;type:datetime(6);not null" json:"create_time"`
UpdateTime *time.Time `gorm:"column:update_time;type:datetime(6)" json:"update_time"`
CategoryID int32 `gorm:"column:category_id;type:int(11);not null;index:post_category_category_id,priority:1" json:"category_id"`
PostID int32 `gorm:"column:post_id;type:int(11);not null;index:post_category_post_id,priority:1" json:"post_id"`
}
// TableName PostCategory's table name

@ -12,11 +12,11 @@ const TableNamePostTag = "post_tag"
// PostTag mapped from table <post_tag>
type PostTag struct {
ID *int32 `gorm:"column:id;type:integer;primaryKey" json:"id"`
CreateTime time.Time `gorm:"column:create_time;type:datetime;not null" json:"create_time"`
UpdateTime *time.Time `gorm:"column:update_time;type:datetime" json:"update_time"`
PostID int32 `gorm:"column:post_id;type:integer;not null" json:"post_id"`
TagID int32 `gorm:"column:tag_id;type:integer;not null" json:"tag_id"`
ID int32 `gorm:"column:id;type:int(11);primaryKey;autoIncrement:true" json:"id"`
CreateTime time.Time `gorm:"column:create_time;type:datetime(6);not null" json:"create_time"`
UpdateTime *time.Time `gorm:"column:update_time;type:datetime(6)" json:"update_time"`
PostID int32 `gorm:"column:post_id;type:int(11);not null;index:post_tag_post_id,priority:1" json:"post_id"`
TagID int32 `gorm:"column:tag_id;type:int(11);not null;index:post_tag_tag_id,priority:1" json:"tag_id"`
}
// TableName PostTag's table name

@ -4,19 +4,26 @@
package entity
import (
"time"
)
const TableNameScrapPage = "scrap_page"
// ScrapPage mapped from table <scrap_page>
type ScrapPage struct {
ID *int32 `gorm:"column:id;type:INTEGER" json:"id"`
Title string `gorm:"column:title;type:varchar(128);not null" json:"title"`
Md5 string `gorm:"column:md5;type:varchar(128);not null" json:"md5"`
URL string `gorm:"column:url;type:text;not null" json:"url"`
Content string `gorm:"column:content;type:text;not null" json:"content"`
Summary *string `gorm:"column:summary;type:text" json:"summary"`
CreateAt *int64 `gorm:"column:create_at;type:bigint" json:"create_at"`
Domain string `gorm:"column:domain;type:varchar(128);not null" json:"domain"`
OutLink *string `gorm:"column:out_link;type:text" json:"out_link"`
ID int32 `gorm:"column:id;type:int(11);primaryKey;autoIncrement:true" json:"id"`
CreateTime time.Time `gorm:"column:create_time;type:datetime(6);not null" json:"create_time"`
UpdateTime *time.Time `gorm:"column:update_time;type:datetime(6)" json:"update_time"`
Title string `gorm:"column:title;type:varchar(128);not null" json:"title"`
Md5 string `gorm:"column:md5;type:varchar(128);not null" json:"md5"`
URL string `gorm:"column:url;type:text;not null" json:"url"`
OriginURL *string `gorm:"column:origin_url;type:text" json:"origin_url"`
Content *string `gorm:"column:content;type:longtext" json:"content"`
Summary *string `gorm:"column:summary;type:text" json:"summary"`
Domain string `gorm:"column:domain;type:varchar(128);not null" json:"domain"`
Resource *string `gorm:"column:resource;type:text" json:"resource"`
Attachment *int32 `gorm:"column:attachment;type:int(11);comment:附件" json:"attachment"` // 附件
}
// TableName ScrapPage's table name

@ -12,11 +12,11 @@ const TableNameTag = "tag"
// Tag mapped from table <tag>
type Tag struct {
ID int32 `gorm:"column:id;type:integer;primaryKey" json:"id"`
CreateTime time.Time `gorm:"column:create_time;type:datetime;not null" json:"create_time"`
UpdateTime *time.Time `gorm:"column:update_time;type:datetime" json:"update_time"`
Name string `gorm:"column:name;type:varchar(255);not null" json:"name"`
Slug string `gorm:"column:slug;type:varchar(50);not null" json:"slug"`
ID int32 `gorm:"column:id;type:int(11);primaryKey;autoIncrement:true" json:"id"`
CreateTime time.Time `gorm:"column:create_time;type:datetime(6);not null" json:"create_time"`
UpdateTime *time.Time `gorm:"column:update_time;type:datetime(6)" json:"update_time"`
Name string `gorm:"column:name;type:varchar(255);not null;index:tag_name,priority:1" json:"name"`
Slug string `gorm:"column:slug;type:varchar(50);not null;uniqueIndex:uniq_tag_slug,priority:1" json:"slug"`
Thumbnail string `gorm:"column:thumbnail;type:varchar(1023);not null" json:"thumbnail"`
Color string `gorm:"column:color;type:varchar(25);not null" json:"color"`
}

@ -12,11 +12,11 @@ const TableNameThemeSetting = "theme_setting"
// ThemeSetting mapped from table <theme_setting>
type ThemeSetting struct {
ID int32 `gorm:"column:id;type:integer;primaryKey" json:"id"`
CreateTime time.Time `gorm:"column:create_time;type:datetime;not null" json:"create_time"`
UpdateTime *time.Time `gorm:"column:update_time;type:datetime" json:"update_time"`
SettingKey string `gorm:"column:setting_key;type:varchar(255);not null" json:"setting_key"`
ThemeID string `gorm:"column:theme_id;type:varchar(255);not null" json:"theme_id"`
ID int32 `gorm:"column:id;type:int(11);primaryKey;autoIncrement:true" json:"id"`
CreateTime time.Time `gorm:"column:create_time;type:datetime(6);not null" json:"create_time"`
UpdateTime *time.Time `gorm:"column:update_time;type:datetime(6)" json:"update_time"`
SettingKey string `gorm:"column:setting_key;type:varchar(255);not null;index:theme_setting_setting_key,priority:1" json:"setting_key"`
ThemeID string `gorm:"column:theme_id;type:varchar(255);not null;index:theme_setting_theme_id,priority:1" json:"theme_id"`
SettingValue string `gorm:"column:setting_value;type:longtext;not null" json:"setting_value"`
}

@ -14,15 +14,15 @@ const TableNameUser = "user"
// User mapped from table <user>
type User struct {
ID int32 `gorm:"column:id;type:integer;primaryKey" json:"id"`
CreateTime time.Time `gorm:"column:create_time;type:datetime;not null" json:"create_time"`
UpdateTime *time.Time `gorm:"column:update_time;type:datetime" json:"update_time"`
ID int32 `gorm:"column:id;type:int(11);primaryKey;autoIncrement:true" json:"id"`
CreateTime time.Time `gorm:"column:create_time;type:datetime(6);not null" json:"create_time"`
UpdateTime *time.Time `gorm:"column:update_time;type:datetime(6)" json:"update_time"`
Avatar string `gorm:"column:avatar;type:varchar(1023);not null" json:"avatar"`
Description string `gorm:"column:description;type:varchar(1023);not null" json:"description"`
Email string `gorm:"column:email;type:varchar(127);not null" json:"email"`
ExpireTime *time.Time `gorm:"column:expire_time;type:datetime" json:"expire_time"`
ExpireTime *time.Time `gorm:"column:expire_time;type:datetime(6)" json:"expire_time"`
MfaKey string `gorm:"column:mfa_key;type:varchar(64);not null" json:"mfa_key"`
MfaType consts.MFAType `gorm:"column:mfa_type;type:bigint;not null" json:"mfa_type"`
MfaType consts.MFAType `gorm:"column:mfa_type;type:bigint(20);not null" json:"mfa_type"`
Nickname string `gorm:"column:nickname;type:varchar(255);not null" json:"nickname"`
Password string `gorm:"column:password;type:varchar(255);not null" json:"password"`
Username string `gorm:"column:username;type:varchar(50);not null" json:"username"`

@ -1,11 +1,18 @@
package param
type ScrapPage struct {
Title string `json:"title"`
Summary *string `json:"summary"`
URL string `json:"url"`
OriginURL string `json:"origin_url"`
AddAt *int64 `json:"add_at"`
Md5 string `json:"md_5"`
Content string `json:"content"`
Title string `json:"title" form:"title"`
Summary *string `json:"summary" form:"summary"`
URL string `json:"url" form:"url"`
OriginURL string `json:"origin_url" form:"origin_url"`
AddAt *int64 `json:"add_at" form:"add_at"`
Md5 string `json:"md_5" form:"md_5"`
Content *string `json:"content" form:"content"`
Resource *string `json:"resource" form:"resource"`
}
type ScrapPageQuery struct {
Page
*Sort
KeyWord string `json:"key_word"`
}

@ -1,4 +1,5 @@
FROM golang:1.19.3-alpine as builder
RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.tuna.tsinghua.edu.cn/g' /etc/apk/repositories
RUN apk --no-cache add git ca-certificates gcc g++
COPY . /go/src/github.com/go-sonic/sonic/

@ -308,17 +308,21 @@ create table if not exists application_password
DEFAULT charset = utf8mb4;
create table scrap_page
create table if not exists scrap_page
(
id INTEGER
constraint scrap_page_pk
primary key,
title varchar(128) not null,
md5 varchar(128) not null,
url text not null,
content text not null,
summary text,
create_at bigint,
domain varchar(128) not null,
out_link text
);
id int auto_increment
primary key,
create_time datetime(6) not null,
update_time datetime(6) null,
title text not null,
md5 varchar(128) not null,
url text not null,
origin_url text null,
content longtext null,
summary text null,
domain varchar(128) not null,
resource text null,
attachment int null comment '附件'
)
charset = utf8mb4;

@ -41,5 +41,6 @@ func init() {
NewExportImport,
storage.NewFileStorageComposite,
NewApplicationPasswordService,
NewScrapService,
)
}

@ -2,19 +2,26 @@ package impl
import (
"context"
"mime/multipart"
"net/url"
"time"
"github.com/go-sonic/sonic/dal"
"github.com/go-sonic/sonic/model/dto"
"github.com/go-sonic/sonic/model/entity"
"github.com/go-sonic/sonic/model/param"
"github.com/go-sonic/sonic/service"
"github.com/go-sonic/sonic/util/xerr"
)
type scrapServiceImpl struct{}
type scrapServiceImpl struct {
AttachmentService service.AttachmentService
}
func NewScrapService() service.ScrapService {
return &scrapServiceImpl{}
func NewScrapService(attachmentService service.AttachmentService) service.ScrapService {
return &scrapServiceImpl{
AttachmentService: attachmentService,
}
}
func (impl *scrapServiceImpl) QueryMd5List(ctx context.Context) ([]string, error) {
@ -32,19 +39,84 @@ func (impl *scrapServiceImpl) QueryMd5List(ctx context.Context) ([]string, error
return md5List, nil
}
func (impl *scrapServiceImpl) Create(ctx context.Context, pageParam *param.ScrapPage) error {
func (impl *scrapServiceImpl) Create(ctx context.Context, pageParam *param.ScrapPage, file *multipart.FileHeader) (*dto.ScrapPageDTO, error) {
attachmentDTO, err := impl.AttachmentService.Upload(ctx, file)
if err != nil {
return nil, err
}
pageEntity, err := convertToModel(pageParam)
if err != nil {
return xerr.BadParam.Wrap(err)
return nil, xerr.BadParam.Wrap(err)
}
pageEntity.Attachment = &attachmentDTO.ID
scrapPageDAL := dal.GetQueryByCtx(ctx).ScrapPage
err = scrapPageDAL.WithContext(ctx).Create(pageEntity)
if err != nil {
return WrapDBErr(err)
return nil, WrapDBErr(err)
}
return convertToDTO(pageEntity, false), nil
}
func (impl *scrapServiceImpl) Get(ctx context.Context, pageID int32) (*dto.ScrapPageDTO, error) {
scrapPageDAL := dal.GetQueryByCtx(ctx).ScrapPage
pageEntity, err := scrapPageDAL.WithContext(ctx).Where(scrapPageDAL.ID.Eq(pageID)).First()
if err != nil {
return nil, WrapDBErr(err)
}
return convertToDTO(pageEntity, true), nil
}
func (impl *scrapServiceImpl) Query(ctx context.Context, query *param.ScrapPageQuery) ([]*dto.ScrapPageDTO, int64, error) {
if query == nil || query.PageNum < 0 || query.PageSize <= 0 {
return nil, 0, xerr.BadParam.New("").WithStatus(xerr.StatusBadRequest).WithMsg("Paging parameter error")
}
scrapPageDAL := dal.GetQueryByCtx(ctx).ScrapPage
scrapDo := scrapPageDAL.WithContext(ctx)
if len(query.KeyWord) > 0 {
scrapDo = scrapDo.Where(scrapPageDAL.Title.Like(query.KeyWord))
}
result, total, err := scrapDo.FindByPage((query.PageNum-1)*query.PageSize, query.PageSize)
if err != nil {
return nil, 0, WrapDBErr(err)
}
dtoList := make([]*dto.ScrapPageDTO, len(result))
for k, v := range result {
dtoList[k] = convertToDTO(v, false)
}
return dtoList, total, nil
}
//func (impl *scrapServiceImpl) Update(ctx context.Context, pageId int32, pageParam *param.ScrapPage) error {
// scrapPageDAL := dal.GetQueryByCtx(ctx).ScrapPage
// scrapPageDAL.WithContext(ctx).Update
//}
return nil
func convertToDTO(pageEntity *entity.ScrapPage, withContent bool) *dto.ScrapPageDTO {
var content string
var summary string
if withContent && pageEntity.Content != nil {
content = *pageEntity.Content
}
if pageEntity.Summary != nil {
summary = *pageEntity.Summary
}
return &dto.ScrapPageDTO{
ID: pageEntity.ID,
Content: content,
Title: pageEntity.Title,
Summary: summary,
URL: pageEntity.URL,
}
}
func convertToModel(pageParam *param.ScrapPage) (*entity.ScrapPage, error) {
@ -53,15 +125,19 @@ func convertToModel(pageParam *param.ScrapPage) (*entity.ScrapPage, error) {
return nil, err
}
createTime := time.Now()
if pageParam.AddAt != nil {
createTime = time.Unix(*pageParam.AddAt, 0)
}
return &entity.ScrapPage{
ID: nil,
Title: pageParam.Title,
Md5: pageParam.Md5,
URL: pageParam.URL,
Content: pageParam.Content,
Summary: pageParam.Summary,
CreateAt: pageParam.AddAt,
Domain: pageURL.Hostname(),
OutLink: nil,
Title: pageParam.Title,
Md5: pageParam.Md5,
URL: pageParam.URL,
Content: pageParam.Content,
Summary: pageParam.Summary,
CreateTime: createTime,
Domain: pageURL.Hostname(),
Resource: pageParam.Resource,
}, nil
}

@ -2,11 +2,15 @@ package service
import (
"context"
"mime/multipart"
"github.com/go-sonic/sonic/model/dto"
"github.com/go-sonic/sonic/model/param"
)
type ScrapService interface {
QueryMd5List(ctx context.Context) ([]string, error)
Create(ctx context.Context, pageParam *param.ScrapPage) error
Create(ctx context.Context, pageParam *param.ScrapPage, file *multipart.FileHeader) (*dto.ScrapPageDTO, error)
Get(ctx context.Context, pageID int32) (*dto.ScrapPageDTO, error)
Query(ctx context.Context, query *param.ScrapPageQuery) ([]*dto.ScrapPageDTO, int64, error)
}

@ -94,6 +94,18 @@ func GetQueryBool(ctx *gin.Context, key string, defaultValue bool) (bool, error)
return value, nil
}
func GetQueryInt32(ctx *gin.Context, key string, defaultValue int32) (int32, error) {
str, ok := ctx.GetQuery(key)
if !ok {
return defaultValue, nil
}
value, err := strconv.ParseInt(str, 10, 32)
if err != nil {
return 0, xerr.WithStatus(err, xerr.StatusBadRequest).WithMsg(fmt.Sprintf("The parameter %s type is incorrect", key))
}
return int32(value), nil
}
func ParamString(ctx *gin.Context, key string) (string, error) {
str := ctx.Param(key)
if str == "" {

Loading…
Cancel
Save