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 52 additions and 26 deletions
Showing only changes of commit 6d49d28e1a - Show all commits
+17
View File
@@ -402,3 +402,20 @@ page{scrollbar-width:none;-ms-overflow-style:none}
/* 分享用微信原生 open-type=share,得抹掉 button 默认外观 */ /* 分享用微信原生 open-type=share,得抹掉 button 默认外观 */
.pa-share{background:transparent;border:none;padding:0;margin:0;line-height:inherit} .pa-share{background:transparent;border:none;padding:0;margin:0;line-height:inherit}
.pa-share::after{border:none} .pa-share::after{border:none}
/* ===== 设置项列表 =====
settings 和 mine 都在用。页面级 wxss 跨不了页,放在任一页里另一页就是裸的 */
.profile-list{background:#fff;border-radius:var(--r-lg);box-shadow:var(--sd-1);overflow:hidden;margin-bottom:var(--sp-4)}
.profile-row{
display:flex;align-items:center;gap:var(--sp-3);min-height:104rpx;padding:0 var(--sp-4);
border-bottom:1rpx solid var(--line);font-size:var(--fs-md);font-weight:var(--fw-b);
}
.profile-row:last-child{border-bottom:0}
.pr-ic{
width:56rpx;height:56rpx;border-radius:var(--r-xs);flex:none;
display:flex;align-items:center;justify-content:center;
background:var(--primary-soft);color:var(--primary-ink);
}
.pr-label{flex:1;min-width:0}
.pr-val{color:var(--muted);font-weight:var(--fw);font-size:var(--fs-sm)}
.pr-arrow{color:var(--muted2);display:flex;align-items:center;flex:none}
+3 -1
View File
@@ -11,12 +11,14 @@
background:#fff;border-radius:var(--r-lg);overflow:hidden; background:#fff;border-radius:var(--r-lg);overflow:hidden;
box-shadow:var(--sd-1);margin-bottom:var(--sp-5); box-shadow:var(--sd-1);margin-bottom:var(--sp-5);
} }
.pf-bg{height:220rpx;background:linear-gradient(135deg,var(--pf-a),var(--pf-b));position:relative} .pf-bg{height:180rpx;background:linear-gradient(135deg,var(--pf-a),var(--pf-b))}
.pf-bg-img{width:100%;height:100%;display:block} .pf-bg-img{width:100%;height:100%;display:block}
.pf-body{padding:0 var(--sp-5) var(--sp-5);text-align:center} .pf-body{padding:0 var(--sp-5) var(--sp-5);text-align:center}
/* 头像压在头图上,负 margin 提上去一半 */ /* 头像压在头图上,负 margin 提上去一半 */
.pf-av{ .pf-av{
/* 必须定位:头像要压在头图上面,靠 DOM 顺序不够——只要头图是定位元素就会反盖过来 */
position:relative;z-index:1;
width:144rpx;height:144rpx;margin:-72rpx auto var(--sp-3); width:144rpx;height:144rpx;margin:-72rpx auto var(--sp-3);
border-radius:50%;background:var(--pf-b);color:var(--pf-ink); border-radius:50%;background:var(--pf-b);color:var(--pf-ink);
display:flex;align-items:center;justify-content:center; display:flex;align-items:center;justify-content:center;
+8 -11
View File
@@ -8,27 +8,24 @@ const LIST = [
Component({ Component({
data: { selected: 0, hidden: false, list: LIST }, data: { selected: 0, hidden: false, list: LIST },
// 高亮由当前页面路径自己算出来。
// 原来每个 tab 页在 onShow 里硬写 selected: 0/1/2/3/4,调一次顺序就要同时改
// 五个文件,漏一个就高亮错位——这次把计划换成我的正好会踩到。
pageLifetimes: {
show() {
this.syncSelected();
},
},
lifetimes: { lifetimes: {
attached() { attached() {
this.syncSelected(); this.syncSelected();
}, },
}, },
methods: { methods: {
// 高亮由当前页面路径算出来,页面那边不写死 0/1/2/3/4,
// 调 tab 顺序只改上面的 LIST 就够了。
//
// 触发时机必须由页面 onShow 推(见 utils/tabbar.js):自定义 tabBar 不在
// 页面节点树里,组件自己的 pageLifetimes.show 拿不到可靠时机,实测切到
// 「我的」时高亮还留在「首页」。
syncSelected() { syncSelected() {
const pages = getCurrentPages(); const pages = getCurrentPages();
const cur = pages[pages.length - 1]; const cur = pages[pages.length - 1];
if (!cur) return; if (!cur) return;
const path = '/' + cur.route; const i = LIST.findIndex((t) => t.pagePath === '/' + cur.route);
const i = LIST.findIndex((t) => t.pagePath === path); if (i >= 0) this.setData({ selected: i });
if (i >= 0 && i !== this.data.selected) this.setData({ selected: i });
}, },
switchTab(e) { switchTab(e) {
wx.switchTab({ url: LIST[e.currentTarget.dataset.index].pagePath }); wx.switchTab({ url: LIST[e.currentTarget.dataset.index].pagePath });
+2
View File
@@ -1,6 +1,7 @@
const store = require('../../utils/store.js'); const store = require('../../utils/store.js');
const api = require('../../utils/api.js'); const api = require('../../utils/api.js');
const { toastErr } = require('../../utils/ui.js'); const { toastErr } = require('../../utils/ui.js');
const { syncTabBar } = require('../../utils/tabbar.js');
// 相对时间。社区里关心的是「多久以前发的」,精确到秒没意义 // 相对时间。社区里关心的是「多久以前发的」,精确到秒没意义
function fmtAgo(iso) { function fmtAgo(iso) {
@@ -61,6 +62,7 @@ Page({
if (this._unsub) this._unsub(); if (this._unsub) this._unsub();
}, },
onShow() { onShow() {
syncTabBar(this);
store store
.ready() .ready()
.then(() => { .then(() => {
+2
View File
@@ -1,6 +1,7 @@
const store = require('../../utils/store.js'); const store = require('../../utils/store.js');
const api = require('../../utils/api.js'); const api = require('../../utils/api.js');
const { toastErr } = require('../../utils/ui.js'); const { toastErr } = require('../../utils/ui.js');
const { syncTabBar } = require('../../utils/tabbar.js');
function todayStr() { function todayStr() {
const d = new Date(); const d = new Date();
@@ -111,6 +112,7 @@ Page({
if (this._unsub) this._unsub(); if (this._unsub) this._unsub();
}, },
onShow() { onShow() {
syncTabBar(this);
store store
.ready() .ready()
.then(() => { .then(() => {
+2
View File
@@ -1,6 +1,7 @@
const store = require('../../utils/store.js'); const store = require('../../utils/store.js');
const api = require('../../utils/api.js'); const api = require('../../utils/api.js');
const { toastErr } = require('../../utils/ui.js'); const { toastErr } = require('../../utils/ui.js');
const { syncTabBar } = require('../../utils/tabbar.js');
Page({ Page({
data: { user: {}, pets: [], card: null, sheetShow: false, sheetType: '' }, data: { user: {}, pets: [], card: null, sheetShow: false, sheetType: '' },
@@ -11,6 +12,7 @@ Page({
if (this._unsub) this._unsub(); if (this._unsub) this._unsub();
}, },
onShow() { onShow() {
syncTabBar(this);
store store
.ready() .ready()
.then(() => { .then(() => {
+2
View File
@@ -1,6 +1,7 @@
const store = require('../../utils/store.js'); const store = require('../../utils/store.js');
const api = require('../../utils/api.js'); const api = require('../../utils/api.js');
const { toastErr } = require('../../utils/ui.js'); const { toastErr } = require('../../utils/ui.js');
const { syncTabBar } = require('../../utils/tabbar.js');
function pad(n) { function pad(n) {
return n < 10 ? '0' + n : '' + n; return n < 10 ? '0' + n : '' + n;
@@ -131,6 +132,7 @@ Page({
if (this._unsub) this._unsub(); if (this._unsub) this._unsub();
}, },
onShow() { onShow() {
syncTabBar(this);
store store
.ready() .ready()
.then(() => { .then(() => {
+2
View File
@@ -1,5 +1,6 @@
const store = require('../../utils/store.js'); const store = require('../../utils/store.js');
const api = require('../../utils/api.js'); const api = require('../../utils/api.js');
const { syncTabBar } = require('../../utils/tabbar.js');
Page({ Page({
data: { data: {
@@ -22,6 +23,7 @@ Page({
if (this._unsub) this._unsub(); if (this._unsub) this._unsub();
}, },
onShow() { onShow() {
syncTabBar(this);
store store
.ready() .ready()
.then(() => { .then(() => {
-14
View File
@@ -9,17 +9,3 @@
.ph-name{font-size:var(--fs-2xl);font-weight:var(--fw-b)} .ph-name{font-size:var(--fs-2xl);font-weight:var(--fw-b)}
.ph-meta{font-size:var(--fs-sm);margin-top:var(--sp-1)} .ph-meta{font-size:var(--fs-sm);margin-top:var(--sp-1)}
.profile-list{background:#fff;border-radius:var(--r-lg);box-shadow:var(--sd-1);overflow:hidden;margin-bottom:var(--sp-4)}
.profile-row{
display:flex;align-items:center;gap:var(--sp-3);min-height:104rpx;padding:0 var(--sp-4);
border-bottom:1rpx solid var(--line);font-size:var(--fs-md);font-weight:var(--fw-b);
}
.profile-row:last-child{border-bottom:0}
.pr-ic{
width:56rpx;height:56rpx;border-radius:var(--r-xs);flex:none;
display:flex;align-items:center;justify-content:center;
background:var(--primary-soft);color:var(--primary-ink);
}
.pr-label{flex:1;min-width:0}
.pr-val{color:var(--muted);font-weight:var(--fw);font-size:var(--fs-sm)}
.pr-arrow{color:var(--muted2);display:flex;align-items:center;flex:none}
+14
View File
@@ -0,0 +1,14 @@
// tabBar 高亮同步。
//
// 本来想让 custom-tab-bar 自己在 pageLifetimes.show 里算,页面一行都不用写。
// 实测不行:自定义 tabBar 不在页面节点树里,pageLifetimes 拿不到可靠的时机,
// 结果是切到「我的」时高亮还留在「首页」。只能回到官方那套「页面 onShow 里推一把」。
//
// 但索引仍然由 tabBar 按当前路由自己算,页面这边不写死 0/1/2/3/4——
// 调 tab 顺序时改一个 LIST 就够了,五个页面一行都不用动。
function syncTabBar(page) {
const bar = page.getTabBar && page.getTabBar();
if (bar && bar.syncSelected) bar.syncSelected();
}
module.exports = { syncTabBar };