125 lines
4.9 KiB
JavaScript
125 lines
4.9 KiB
JavaScript
/* 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);
|
||
});
|
||
}
|