topfans/frontend/utils/likeHelper.js
2026-05-22 18:06:33 +08:00

128 lines
3.8 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// 双击点赞工具函数
import { likeAssetApi } from './api.js';
// 存储已点赞的作品
// - 带 exhibitionId 时key = "${assetId}_${exhibitionId}",支持每次展示点赞一次
// - 不带 exhibitionId 时key = "asset_${assetId}",兼容旧行为(每天每个作品只能点赞一次)
const LIKE_STORAGE_KEY = 'liked_assets_exhibition';
/**
* 获取存储键
* @param {string|number} assetId
* @param {string|number} exhibitionId
*/
function getStorageKey(assetId, exhibitionId) {
if (exhibitionId) {
return `${assetId}_${exhibitionId}`;
}
return `asset_${assetId}`;
}
/**
* 双击点赞处理
* - 有 exhibitionId 时:每个展品每次展示只能点赞一次
* - 无 exhibitionId 时:每个藏品每天只能点赞一次(兼容旧逻辑)
* @param {string|number} assetId - 藏品ID
* @param {string|number} [exhibitionId] - 展品展示ID每次展示唯一可选
* @param {Function} [callback] - 回调函数,参数为是否成功
*/
export function doubleTapLike(assetId, exhibitionId, callback) {
if (!assetId) {
console.error('doubleTapLike: assetId 是必需的');
if (callback) callback(false);
return;
}
// 如果第二个参数是函数,说明调用者传的是 callbackexhibitionId 未提供
let actualCallback = callback;
let actualExhibitionId = exhibitionId;
if (typeof exhibitionId === 'function') {
actualCallback = exhibitionId;
actualExhibitionId = null;
}
const key = getStorageKey(assetId, actualExhibitionId);
// 不再做本地缓存检查,统一由后端判断唯一性
// 这样可以避免:用户清缓存后、后端已重置、但本地存储还有旧数据 导致的问题
// if (storage[key]) {
// const msg = actualExhibitionId ? '本次展示已点赞' : '今日已点赞';
// uni.showToast({ title: msg, icon: 'none' });
// if (actualCallback) actualCallback(false);
// return;
// }
likeAssetApi(assetId).then(res => {
console.log('点赞成功', res);
// 记录点赞
try {
const storage = uni.getStorageSync(LIKE_STORAGE_KEY) || {};
storage[key] = Date.now();
uni.setStorageSync(LIKE_STORAGE_KEY, storage);
} catch (e) {
console.error('存储点赞记录失败:', e);
}
// 触发全局点赞成功事件
uni.$emit('assetLiked', {
asset_id: assetId,
exhibition_id: actualExhibitionId,
data: res.data
});
if (actualCallback) actualCallback(true, res.data);
}).catch(err => {
console.error('点赞失败:', err);
const errMsg = err?.message || '';
const errData = err?.data?.message || '';
const showMsg = errData || errMsg || '点赞失败';
uni.showToast({ title: showMsg, icon: 'none' });
if (actualCallback) actualCallback(false);
});
}
/**
* 检查藏品在当前展示中是否已点赞
* @param {string|number} assetId - 藏品ID
* @param {string|number} [exhibitionId] - 展品展示ID
*/
export function hasLikedExhibition(assetId, exhibitionId) {
if (!assetId) return false;
const key = getStorageKey(assetId, exhibitionId);
try {
const storage = uni.getStorageSync(LIKE_STORAGE_KEY) || {};
return !!storage[key];
} catch (e) {
return false;
}
}
/**
* 清除指定展览的点赞记录(用于展品下架时)
* @param {string|number} exhibitionId - 展品展示ID
*/
export function clearLikeByExhibition(exhibitionId) {
if (!exhibitionId) return;
try {
const storage = uni.getStorageSync(LIKE_STORAGE_KEY) || {};
const keys = Object.keys(storage);
keys.forEach(key => {
if (key.endsWith(`_${exhibitionId}`)) {
delete storage[key];
}
});
uni.setStorageSync(LIKE_STORAGE_KEY, storage);
} catch (e) {
console.error('清除点赞记录失败:', e);
}
}
/**
* 清除所有点赞记录
*/
export function clearAllLikes() {
try {
uni.removeStorageSync(LIKE_STORAGE_KEY);
} catch (e) {
console.error('清除所有点赞记录失败:', e);
}
}