feat(auth): access token 缩到 2 小时 + refresh token 机制 #3

Merged
Blizzard merged 58 commits from feat/dev into main 2026-07-30 10:18:07 +00:00
10 changed files with 42 additions and 11 deletions
Showing only changes of commit 535ef08da7 - Show all commits
+3 -2
View File
@@ -113,7 +113,8 @@ func (h *Handler) ListComments(c *gin.Context) {
} }
type commentReq struct { type commentReq struct {
Content string `json:"content"` Content string `json:"content"`
Images []string `json:"images"`
} }
// CreateComment POST /api/posts/:id/comments // CreateComment POST /api/posts/:id/comments
@@ -127,7 +128,7 @@ func (h *Handler) CreateComment(c *gin.Context) {
response.FailParams(c, "评论内容不能为空") response.FailParams(c, "评论内容不能为空")
return return
} }
comment, err := h.svc.CreateComment(middleware.UserID(c), idParam(c, "id"), req.Content) comment, err := h.svc.CreateComment(middleware.UserID(c), idParam(c, "id"), req.Content, req.Images)
if err != nil { if err != nil {
respondErr(c, err) respondErr(c, err)
return return
+5 -1
View File
@@ -209,7 +209,7 @@ func (s *Service) ListComments(userID, postID string, offset, limit int) ([]mode
} }
// CreateComment 评论 // CreateComment 评论
func (s *Service) CreateComment(userID, postID string, content string) (*model.Comment, error) { func (s *Service) CreateComment(userID, postID string, content string, images []string) (*model.Comment, error) {
if _, err := s.GetPost(postID); err != nil { if _, err := s.GetPost(postID); err != nil {
return nil, err return nil, err
} }
@@ -219,6 +219,10 @@ func (s *Service) CreateComment(userID, postID string, content string) (*model.C
name = user.Nickname name = user.Nickname
} }
comment := model.Comment{PostID: postID, UserID: userID, AuthorName: name, Content: content, Status: "published"} comment := model.Comment{PostID: postID, UserID: userID, AuthorName: name, Content: content, Status: "published"}
// 配图存 JSON 数组。空数组也要显式写,否则前端拿到 null 还要额外判空
if b, err := json.Marshal(images); err == nil && len(images) > 0 {
comment.Images = b
}
if err := s.db.Transaction(func(tx *gorm.DB) error { if err := s.db.Transaction(func(tx *gorm.DB) error {
if err := tx.Create(&comment).Error; err != nil { if err := tx.Create(&comment).Error; err != nil {
return err return err
+14
View File
@@ -357,3 +357,17 @@ page{scrollbar-width:none;-ms-overflow-style:none}
} }
.no-pet-b{font-size:var(--fs-lg);font-weight:var(--fw-b)} .no-pet-b{font-size:var(--fs-lg);font-weight:var(--fw-b)}
.no-pet-p{color:var(--muted);font-size:var(--fs-sm);margin:var(--sp-2) 0 var(--sp-4);line-height:1.6} .no-pet-p{color:var(--muted);font-size:var(--fs-sm);margin:var(--sp-2) 0 var(--sp-4);line-height:1.6}
/* 宠物切换条固定在导航栏下方。它原本在 scroll-view 里,滚下去就找不到了,
而切宠物是随时要用的动作——尤其多宠用户,看着 A 的数据想切到 B
还得先滚回顶部。移出滚动区,四个主页面通用。 */
.pet-bar{
flex:none;
padding:var(--sp-2) var(--pad-x) 0;
background:rgba(250,247,242,.92);
backdrop-filter:blur(20rpx);
-webkit-backdrop-filter:blur(20rpx);
border-bottom:1rpx solid rgba(238,230,220,.7);
}
/* 条内的 pet-switch 自己带 padding-bottom,这里不再叠加 */
.pet-bar .pet-switch{padding-bottom:var(--sp-2)}
@@ -416,6 +416,7 @@ Component({
timeText: fmtAgo(c.created_at), timeText: fmtAgo(c.created_at),
// 没有头像字段,用昵称首字做个色块,比一律显示同一个 emoji 强 // 没有头像字段,用昵称首字做个色块,比一律显示同一个 emoji 强
initial: (c.author_name || '?').slice(0, 1), initial: (c.author_name || '?').slice(0, 1),
imgs: Array.isArray(c.images) ? c.images : [],
})), })),
}), }),
) )
@@ -954,6 +955,10 @@ Component({
wx.showToast({ title: (e && e.message) || '上传失败', icon: 'none' }); wx.showToast({ title: (e && e.message) || '上传失败', icon: 'none' });
}); });
}, },
onPreviewCommentImage(e) {
const { urls, cur } = e.currentTarget.dataset;
if (urls && urls.length) wx.previewImage({ urls, current: cur });
},
onRemoveCommentImage(e) { onRemoveCommentImage(e) {
const list = this.data.commentImages.slice(); const list = this.data.commentImages.slice();
list.splice(e.currentTarget.dataset.index, 1); list.splice(e.currentTarget.dataset.index, 1);
@@ -330,6 +330,11 @@ module.exports.sel = function (map, key, index, def) {
<text class="cm-time">{{item.timeText}}</text> <text class="cm-time">{{item.timeText}}</text>
</view> </view>
<view class="cm-text">{{item.content}}</view> <view class="cm-text">{{item.content}}</view>
<view wx:if="{{item.imgs.length}}" class="cm-imgs">
<image wx:for="{{item.imgs}}" wx:for-item="u" wx:key="*this" class="cm-img"
src="{{u}}" mode="aspectFill" catchtap="onPreviewCommentImage"
data-urls="{{item.imgs}}" data-cur="{{u}}"></image>
</view>
</view> </view>
</view> </view>
@@ -125,3 +125,5 @@
.cm-bar{display:flex;align-items:center;gap:var(--sp-3);margin-top:var(--sp-3)} .cm-bar{display:flex;align-items:center;gap:var(--sp-3);margin-top:var(--sp-3)}
.cm-pic{display:flex;align-items:center;gap:var(--sp-1);color:var(--muted);font-size:var(--fs-sm)} .cm-pic{display:flex;align-items:center;gap:var(--sp-1);color:var(--muted);font-size:var(--fs-sm)}
.cm-count{margin-left:auto;color:var(--muted2);font-size:var(--fs-cap)} .cm-count{margin-left:auto;color:var(--muted2);font-size:var(--fs-cap)}
.cm-imgs{display:flex;flex-wrap:wrap;gap:var(--sp-1);margin-top:var(--sp-2)}
.cm-img{width:150rpx;height:150rpx;border-radius:var(--r-sm)}
+2 -2
View File
@@ -1,5 +1,7 @@
<nav-bar title="肉垫计划"></nav-bar> <nav-bar title="肉垫计划"></nav-bar>
<view class="pet-bar"><pet-switch bind:add="onAddPet"></pet-switch></view>
<scroll-view class="page-scroll" scroll-y="{{true}}" enhanced="{{true}}" show-scrollbar="{{false}}"> <scroll-view class="page-scroll" scroll-y="{{true}}" enhanced="{{true}}" show-scrollbar="{{false}}">
<view class="page-body"> <view class="page-body">
<view class="top-row"> <view class="top-row">
@@ -13,8 +15,6 @@
</view> </view>
</view> </view>
<pet-switch bind:add="onAddPet"></pet-switch>
<!-- 门面:完成度环 + 当下状态。点进去编辑档案 --> <!-- 门面:完成度环 + 当下状态。点进去编辑档案 -->
<view class="card hero-card" bindtap="onHeroTap"> <view class="card hero-card" bindtap="onHeroTap">
<view class="hero-row"> <view class="hero-row">
+2 -2
View File
@@ -1,9 +1,9 @@
<nav-bar title="养宠计划"></nav-bar> <nav-bar title="养宠计划"></nav-bar>
<view class="pet-bar"><pet-switch bind:add="onAddPet"></pet-switch></view>
<scroll-view class="page-scroll" scroll-y="{{true}}" enhanced="{{true}}" show-scrollbar="{{false}}"> <scroll-view class="page-scroll" scroll-y="{{true}}" enhanced="{{true}}" show-scrollbar="{{false}}">
<view class="page-body"> <view class="page-body">
<pet-switch bind:add="onAddPet"></pet-switch>
<view wx:if="{{!pet.id}}" class="no-pet"> <view wx:if="{{!pet.id}}" class="no-pet">
<view class="no-pet-ic"><pt-icon name="community" size="{{52}}"></pt-icon></view> <view class="no-pet-ic"><pt-icon name="community" size="{{52}}"></pt-icon></view>
<view class="no-pet-b">还没有毛孩子的档案</view> <view class="no-pet-b">还没有毛孩子的档案</view>
+2 -2
View File
@@ -1,9 +1,9 @@
<nav-bar title="快速记录"></nav-bar> <nav-bar title="快速记录"></nav-bar>
<view class="pet-bar"><pet-switch bind:add="onAddPet"></pet-switch></view>
<scroll-view class="page-scroll" scroll-y="{{true}}" enhanced="{{true}}" show-scrollbar="{{false}}"> <scroll-view class="page-scroll" scroll-y="{{true}}" enhanced="{{true}}" show-scrollbar="{{false}}">
<view class="page-body"> <view class="page-body">
<pet-switch bind:add="onAddPet"></pet-switch>
<view wx:if="{{!pet.id}}" class="no-pet"> <view wx:if="{{!pet.id}}" class="no-pet">
<view class="no-pet-ic"><pt-icon name="community" size="{{52}}"></pt-icon></view> <view class="no-pet-ic"><pt-icon name="community" size="{{52}}"></pt-icon></view>
<view class="no-pet-b">还没有毛孩子的档案</view> <view class="no-pet-b">还没有毛孩子的档案</view>
+2 -2
View File
@@ -1,9 +1,9 @@
<nav-bar title="成长报告"></nav-bar> <nav-bar title="成长报告"></nav-bar>
<view class="pet-bar"><pet-switch bind:add="onAddPet"></pet-switch></view>
<scroll-view class="page-scroll" scroll-y="{{true}}" enhanced="{{true}}" show-scrollbar="{{false}}"> <scroll-view class="page-scroll" scroll-y="{{true}}" enhanced="{{true}}" show-scrollbar="{{false}}">
<view class="page-body"> <view class="page-body">
<pet-switch bind:add="onAddPet"></pet-switch>
<view wx:if="{{!pet.id}}" class="no-pet"> <view wx:if="{{!pet.id}}" class="no-pet">
<view class="no-pet-ic"><pt-icon name="community" size="{{52}}"></pt-icon></view> <view class="no-pet-ic"><pt-icon name="community" size="{{52}}"></pt-icon></view>
<view class="no-pet-b">还没有毛孩子的档案</view> <view class="no-pet-b">还没有毛孩子的档案</view>