Support personal records and persistent smoking visibility. Add upload quota preflight, file cleanup, privacy entry, image caching and revision-based page refresh across the backend, admin and mini program.
138 lines
5.9 KiB
JavaScript
138 lines
5.9 KiB
JavaScript
const { tryLoginRenewal } = require('../../utils/subscribe');
|
|
const { itemsOf, startList, applyList, failList, finishList, withListPagination } = require('../../utils/list-pagination');
|
|
const { withDataCache } = require('../../utils/page-cache');
|
|
const { getLayout } = require('../../utils/layout');
|
|
// pages/punch/punch.js - 情侣打卡
|
|
const { api, getImageUrl } = require('../../utils/request');
|
|
Page(withDataCache(withListPagination({
|
|
onLoginSubscribeTap: function() { return tryLoginRenewal(); },
|
|
onResize: function() { this.setData(getLayout()); },
|
|
data: { loadError: false,
|
|
checkins: [], smokingVisible: false, smokingKnown: false, smokingSaving: false, smokingError: false,
|
|
coupleInfo: null,
|
|
myAvatar: '', partnerAvatar: '',
|
|
myName: '我', partnerName: 'TA',
|
|
weekBoth: 0, weekMy: 0, weekPartner: 0,
|
|
todayMy: 0, todayPartner: 0,
|
|
loading: true
|
|
},
|
|
|
|
onLoad: function() {
|
|
this.setData(getLayout());
|
|
this.loadCoupleInfo();
|
|
this.loadData();
|
|
},
|
|
onShow: function() { this.loadSmokingPreference(); this.loadCoupleInfo(); this.loadData(); },
|
|
|
|
loadSmokingPreference: async function() {
|
|
try { const auth=await api.checkAuth(); this.setData({smokingVisible:Number(auth.user.smoking_card_visible)!==0, smokingKnown:true, smokingError:false}); }
|
|
catch(e) { this.setData({smokingError:true}); }
|
|
},
|
|
toggleSmoking: async function(e) {
|
|
if (this.data.smokingSaving || !this.data.smokingKnown) return;
|
|
const previous=this.data.smokingVisible;
|
|
this.setData({smokingSaving:true});
|
|
try { const result=await api.smokingCardVisible({visible:e.detail.value?1:0}); this.setData({smokingVisible:Number(result.card_visible)===1}); }
|
|
catch(error) { this.setData({smokingVisible:previous}); wx.showToast({title:error.error||'保存失败,请重试',icon:'none'}); }
|
|
finally { this.setData({smokingSaving:false}); }
|
|
},
|
|
onSmokingUpdated: function() { this.loadData(); },
|
|
|
|
onPullDownRefresh: async function() {
|
|
const smoking = this.selectComponent && this.selectComponent("#smoking");
|
|
if (smoking) await smoking.load(true);
|
|
await this.loadCoupleInfo();
|
|
await this.loadData();
|
|
wx.stopPullDownRefresh();
|
|
},
|
|
|
|
// 从接口加载情侣头像和名称
|
|
loadCoupleInfo: function() {
|
|
var self = this;
|
|
return api.coupleInfo().then(function(info) {
|
|
self._applyCoupleInfo(info);
|
|
}).catch(function(e) { console.error(e); });
|
|
},
|
|
|
|
_applyCoupleInfo: function(info) {
|
|
if (!info) return;
|
|
var myUid = wx.getStorageSync('userId');
|
|
var p1 = info.partner1 || {}, p2 = info.partner2 || {};
|
|
var me = (p1.id == myUid) ? p1 : p2;
|
|
var partner = (p1.id == myUid) ? p2 : p1;
|
|
this.setData({
|
|
coupleInfo: info,
|
|
myAvatar: getImageUrl(me.avatar || ''),
|
|
partnerAvatar: getImageUrl(partner.avatar || ''),
|
|
myName: me.nickname || '我',
|
|
partnerName: partner.nickname || 'TA'
|
|
});
|
|
},
|
|
|
|
loadData: async function(page) {
|
|
const ticket = startList(this, page);
|
|
if (!ticket) return;
|
|
try {
|
|
const [res, stats] = await Promise.all([
|
|
api.checkinList({page:ticket.page,page_size:20}),
|
|
api.checkinStats().catch(() => ({}))
|
|
]);
|
|
const list = itemsOf(res).map(function(item) {
|
|
item.type = item.type || 'both';
|
|
var typeLabels = { both: '双方', first: '第一视角', her: '她打卡' };
|
|
item.type_label = typeLabels[item.type] || '双方';
|
|
item.frequency = item.frequency || 'daily';
|
|
var freqLabels = { daily: '每天', weekly: '每周', monthly: '每月', once: '一次', unlimited: '不限' };
|
|
item.freq_label = freqLabels[item.frequency] || '每天';
|
|
var periodLabels = { daily: '今日', weekly: '本周', monthly: '本月', once: '本次', unlimited: '' };
|
|
item.period_label = periodLabels[item.frequency] || '今日';
|
|
item.my_photo_url = item.my_photo ? getImageUrl(item.my_photo) : '';
|
|
item.partner_photo_url = item.partner_photo ? getImageUrl(item.partner_photo) : '';
|
|
// 打卡人头像
|
|
item.creator_avatar_url = item.creator_avatar ? getImageUrl(item.creator_avatar) : '';
|
|
item.my_checkin_avatar_url = item.my_checkin_avatar ? getImageUrl(item.my_checkin_avatar) : '';
|
|
item.partner_checkin_avatar_url = item.partner_checkin_avatar ? getImageUrl(item.partner_checkin_avatar) : '';
|
|
return item;
|
|
});
|
|
var data = {
|
|
checkins: list,
|
|
weekBoth: stats.week_both_count || 0,
|
|
weekMy: stats.week_my_count || 0,
|
|
weekPartner: stats.week_partner_count || 0,
|
|
todayMy: stats.today_my_count || 0,
|
|
todayPartner: stats.today_partner_count || 0,
|
|
loading: false
|
|
};
|
|
delete data.checkins;
|
|
applyList(this, ticket, res, list, 'checkins', data);
|
|
} catch(e) {
|
|
failList(this,ticket); console.error(e); this.setData({ loading: false }); }
|
|
finally { finishList(this,ticket); }
|
|
},
|
|
|
|
// ===== 点击卡片 → 详情弹窗 =====
|
|
openDetail: function(e) {
|
|
var idx = e.currentTarget.dataset.index;
|
|
var item = this.data.checkins[idx];
|
|
wx.navigateTo({ url: '/pages/checkin-detail/checkin-detail?id=' + item.id });
|
|
},
|
|
|
|
// ===== 跳转发布页 =====
|
|
showAddModal: function() { wx.navigateTo({ url: '/pages/publish/publish?type=checkin' }); },
|
|
|
|
// ===== 删除 =====
|
|
deleteCheckin: function(e) {
|
|
var id = e.currentTarget.dataset.id;
|
|
wx.showModal({
|
|
title: '确认删除', content: '确定要删除这个打卡项吗?',
|
|
success: async (res) => {
|
|
if (res.confirm) { try { await api.checkinDelete({ id: id }); wx.showToast({ title: '已删除', icon: 'success' }); this.loadData(); } catch(err) {} }
|
|
}
|
|
});
|
|
},
|
|
|
|
goBack: function() { wx.navigateBack(); },
|
|
goHome: function() { wx.switchTab({ url: '/pages/index/index' }); },
|
|
goProfile: function() { wx.switchTab({ url: '/pages/profile/profile' }); }
|
|
}, 'loadData'), {"loadData": ["checkinList", "checkinStats", "coupleInfo"], "loadSmokingPreference":["checkAuth"], "loadCoupleInfo":["coupleInfo"]}));
|