125 lines
4.9 KiB
JavaScript
Raw Normal View History

2024-10-25 18:09:59 +08:00
/* eslint-disable no-param-reassign */
import { getCurrTime, promisify } from './utils';
const getFriendCloudStorage = promisify(wx.getFriendCloudStorage);
const getGroupCloudStorage = promisify(wx.getGroupCloudStorage);
const setUserCloudStorage = promisify(wx.setUserCloudStorage);
const getUserInfo = promisify(wx.getUserInfo);
/**
* 获取用户信息
* API文档可见https://developers.weixin.qq.com/minigame/dev/api/open-api/data/OpenDataContext-wx.getUserInfo.html
*/
export function getSelfData() {
return getUserInfo({
openIdList: ['selfOpenId'],
}).then((res) => res.data[0] || {});
}
let getSelfPromise;
/**
* UserGameData 数据反序列化
* @param { UserGameData } item
* https://developers.weixin.qq.com/minigame/dev/api/open-api/data/UserGameData.html
*/
function getWxGameData(item) {
let source;
try {
source = JSON.parse(item.KVDataList[0].value);
}
catch (e) {
source = {
wxgame: {
score: 0,
update_time: getCurrTime(),
},
};
}
return source.wxgame;
}
/**
* 处理 getFriendCloudStorage getGroupCloudStorage 返回的在玩好友数据
*/
function rankDataFilter(res, selfUserInfo = false) {
const data = (res.data || []).filter((item) => item.KVDataList && item.KVDataList.length);
return data
.map((item) => {
const { score, update_time: updateTime } = getWxGameData(item);
item.score = score;
item.update_time = updateTime;
/**
* 请注意这里判断是否为自己并不算特别严谨的做法
* 比较严谨的做法是从游戏域将openid传进来示例为了简化简单通过 avatarUrl 来判断
*/
if (selfUserInfo && selfUserInfo.avatarUrl === item.avatarUrl) {
item.isSelf = true;
}
return item;
})
// 升序排序
.sort((a, b) => b.score - a.score);
}
/**
* 获取好友排行榜列表
* API文档可见https://developers.weixin.qq.com/minigame/dev/api/open-api/data/wx.getFriendCloudStorage.html
*/
export function getFriendRankData(key, needMarkSelf = true) {
console.log('[WX OpenData] getFriendRankData with key: ', key);
return getFriendCloudStorage({
keyList: [key],
}).then((res) => {
console.log('[WX OpenData] getFriendRankData success: ', res);
if (needMarkSelf) {
getSelfPromise = getSelfPromise || getSelfData();
return getSelfPromise.then(userInfo => rankDataFilter(res, userInfo));
}
return rankDataFilter(res);
});
}
/**
* 获取群同玩成员的游戏数据小游戏通过群分享卡片打开的情况下才可以调用该接口需要用户授权且只在开放数据域下可用
* API文档可见: https://developers.weixin.qq.com/minigame/dev/api/open-api/data/wx.getGroupCloudStorage.html
*/
export function getGroupFriendsRankData(shareTicket, key, needMarkSelf = true) {
console.log('[WX OpenData] getGroupFriendsRankData with shareTicket and key: ', shareTicket, key);
return getGroupCloudStorage({
shareTicket,
keyList: [key],
}).then((res) => {
console.log('[WX OpenData] getGroupFriendsRankData success: ', res);
if (needMarkSelf) {
getSelfPromise = getSelfPromise || getSelfData();
return getSelfPromise.then(userInfo => rankDataFilter(res, userInfo));
}
return rankDataFilter(res);
});
}
/**
* 写入用户排行榜数据value 的值一般只需要为 Object 经过 JSON.stringify 的字符串即可
* 但排行榜支持展示在游戏中心因此这里统一用游戏中心需要的数据结构执行上报需要展示在游戏中心的数据可以经过以下操作
* mp.weixin.qq.com 的小游戏管理后台设置 - 游戏 - 排行榜设置下配置对应的 key 以及相关排行榜属性
* @param { String } key 排行榜对应的 key
* @param { Number } score 排行榜对应的分数
* @param { Object } extra 除了分数还需要写入的其他字段不需要不填即可
* @example
* setUserRecord('user_rank', 100, { type: 'coin' })
*/
export function setUserRecord(key, score = 0, extra = {}) {
console.log('[WX OpenData] setUserRecord: ', score);
return setUserCloudStorage({
KVDataList: [
{
key,
value: JSON.stringify({
wxgame: {
score,
// 时间单位:秒
update_time: getCurrTime(),
},
// wxgame下开发者不可自定义其他字段 wxgame同级开发者可自由定义比如定义一个detail 字段,用于存储取得该分数的中间状态。
...extra,
}),
},
],
}).then((res) => {
console.log('[WX OpenData] setUserRecord success: ', res);
});
}