完成首页推荐

dev
truthhun 1 year ago
parent c8ccd5a29c
commit 2902c561db

@ -5,6 +5,7 @@ import "gogoproto/gogo.proto";
// import "validate/validate.proto";
import "google/api/annotations.proto";
import "google/protobuf/empty.proto";
import "api/v1/attachment.proto";
package api.v1;
@ -42,6 +43,7 @@ message Document {
repeated int64 category_id = 26;
string deleted_username = 27;
string ext = 28;
Attachment attachment = 30;
}
message DeleteDocumentRequest { repeated int64 id = 1; }
@ -62,6 +64,7 @@ message ListDocumentRequest {
repeated int64 user_id = 7;
repeated int32 status = 8;
repeated bool is_recommend = 9;
int64 limit = 10;
}
message ListDocumentReply {

@ -249,14 +249,16 @@ func (s *AttachmentAPIService) ViewDocumentPages(ctx *gin.Context) {
func (s *AttachmentAPIService) ViewDocumentCover(ctx *gin.Context) {
hash := ctx.Param("hash")
file := fmt.Sprintf("documents/%s/%s/cover.png", strings.Join(strings.Split(hash, "")[:5], "/"), hash)
if len(hash) != 32 {
ctx.JSON(http.StatusNotFound, nil)
ctx.JSON(http.StatusNotFound, map[string]interface{}{"code": http.StatusNotFound, "message": "文件不存在"})
return
}
ctx.File(fmt.Sprintf("documents/%s/%s/cover.png", strings.Join(strings.Split(hash, "")[:5], "/"), hash))
ctx.File(file)
}
// UploadArticle 上传文章相关图片和视频。这里不验证文件格式。
// UploadArticle 上传文章相关图片和视频。这里不验证文件格式。
//
// 注意当前适配了wangeditor的接口规范如果需要适配其他编辑器需要修改此接口或者增加其他接口
func (s *AttachmentAPIService) UploadArticle(ctx *gin.Context) {
typ := ctx.Query("type")

@ -212,7 +212,7 @@ func (s *DocumentAPIService) GetDocument(ctx context.Context, req *pb.GetDocumen
// 2. 对于管理员,可以查询所有文档,可以根据关键字进行查询
func (s *DocumentAPIService) ListDocument(ctx context.Context, req *pb.ListDocumentRequest) (*pb.ListDocumentReply, error) {
opt := &model.OptionGetDocumentList{
WithCount: true,
WithCount: req.Limit <= 0,
Page: int(req.Page),
Size: int(req.Size_),
SelectFields: req.Field,
@ -253,6 +253,11 @@ func (s *DocumentAPIService) ListDocument(ctx context.Context, req *pb.ListDocum
}
}
if req.Limit > 0 {
opt.Size = int(req.Limit)
opt.Page = 1
}
s.logger.Debug("ListDocument", zap.Any("opt", opt))
return s.listDocument(opt)
}
@ -373,7 +378,9 @@ func (s *DocumentAPIService) listDocument(opt *model.OptionGetDocumentList) (*pb
docIndexMap[doc.Id] = i
userIndexesMap[doc.UserId] = append(userIndexesMap[doc.UserId], i)
docIds = append(docIds, doc.Id)
userIds = append(userIds, doc.UserId)
if doc.UserId > 0 {
userIds = append(userIds, doc.UserId)
}
if doc.DeletedUserId > 0 {
userIds = append(userIds, doc.DeletedUserId)
deletedUserIndexMap[doc.DeletedUserId] = append(deletedUserIndexMap[doc.DeletedUserId], i)
@ -396,6 +403,23 @@ func (s *DocumentAPIService) listDocument(opt *model.OptionGetDocumentList) (*pb
QueryIn: map[string][]interface{}{"id": util.Slice2Interface(userIds)},
})
// 查找文档相关联的附件。对于列表只返回hash和id不返回其他字段
attachments, _, _ := s.dbModel.GetAttachmentList(&model.OptionGetAttachmentList{
WithCount: false,
SelectFields: []string{"hash", "id", "type_id"},
QueryIn: map[string][]interface{}{
"type_id": util.Slice2Interface(docIds),
"type": {model.AttachmentTypeDocument},
},
})
for _, attachment := range attachments {
index := docIndexMap[attachment.TypeId]
pbDocs[index].Attachment = &pb.Attachment{
Hash: attachment.Hash,
}
}
for _, docUser := range docUsers {
indexes := userIndexesMap[docUser.Id]
for _, index := range indexes {

@ -17,8 +17,8 @@ func RegisterGinRouter(app *gin.Engine, dbModel *model.DBModel, logger *zap.Logg
app.GET("/helloworld", func(ctx *gin.Context) {
ctx.JSON(http.StatusOK, "hello world")
})
app.GET("/document/page/:hash/:page", attachmentAPIService.ViewDocumentPages)
app.GET("/document/cover/:hash", attachmentAPIService.ViewDocumentCover)
app.GET("/view/page/:hash/:page", attachmentAPIService.ViewDocumentPages)
app.GET("/view/cover/:hash", attachmentAPIService.ViewDocumentCover)
checkPermissionGroup := app.Group("/api/v1/upload")
checkPermissionGroup.Use(auth.AuthGin())

@ -70,6 +70,10 @@ export default {
target: 'http://127.0.0.1:8880', // 目标服务器
changeOrigin: true,
},
'/view': {
target: 'http://127.0.0.1:8880', // 目标服务器
changeOrigin: true,
},
'/uploads': {
target: 'http://127.0.0.1:8880', // 目标服务器
changeOrigin: true,

@ -117,15 +117,25 @@
<el-card shadow="never">
<div slot="header">最新推荐</div>
<el-row :gutter="20">
<el-col v-for="i in 12" :key="'i' + i" :span="4">
<nuxt-link to="/">
<img
src="https://static.sitestack.cn/projects/entgo-0.11-zh/uploads/202210/171f825ac77e9e82.png/cover"
alt=""
/>
<div class="el-link el-link--default">
Kong Gateway v3.0.x Documentation
</div>
<el-col
v-for="item in recommends"
:key="'recommend' + item.id"
:span="4"
>
<nuxt-link :to="`/document/${item.id}`">
<el-image
:src="
item.attachment && item.attachment.hash
? `/view/cover/${item.attachment.hash}`
: ''
"
:alt="item.title"
>
<div slot="error" class="image-slot">
<img src="/static/images/default-cover.png" />
</div>
</el-image>
<div class="el-link el-link--default">{{ item.title }}</div>
</nuxt-link>
</el-col>
</el-row>
@ -212,6 +222,7 @@
<script>
import { mapGetters } from 'vuex'
import { listBanner } from '~/api/banner'
import { listDocument } from '~/api/document'
export default {
name: 'IndexPage',
data() {
@ -221,6 +232,7 @@ export default {
password: '',
},
banners: [],
recommends: [],
search: {
wd: '',
},
@ -236,7 +248,7 @@ export default {
...mapGetters('category', ['categoryTrees']),
},
async created() {
await this.listBanner()
await Promise.all([this.getRecommendDocuments(), this.listBanner()])
},
methods: {
async listBanner() {
@ -258,6 +270,17 @@ export default {
this.$router.push({ path: '/search', query: { wd } })
}
},
async getRecommendDocuments() {
const res = await listDocument({
field: ['id', 'title'],
is_recommend: true,
order: 'recommend_at desc',
limit: 12,
})
if (res.status === 200) {
this.recommends = res.data.document || []
}
},
login() {
//
this.$router.push('/login')
@ -399,12 +422,20 @@ export default {
&:hover {
color: #409eff;
}
img {
width: 100%;
border: 1px solid #efefef;
.el-image {
border: 2px solid #efefef;
border-radius: 5px;
height: 160px;
img {
width: 100%;
transition: transform 0.3s ease 0s;
&:hover {
transform: scale(1.2);
}
}
}
div {
div.el-link {
height: 40px;
overflow: hidden;
margin-bottom: 0px;

Binary file not shown.

Before

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Loading…
Cancel
Save