server/laf-cloud/functions/wucaiTransfer.ts

186 lines
5.6 KiB
TypeScript

import cloud from "@lafjs/cloud";
import Utils from "@/Utils";
import {
WUCAI_TYPE_AUTO_MIGRATED,
WUCAI_TYPE_CHOSE_CURRENT,
WUCAI_TYPE_CHOSE_WUCAI,
WUCAI_TYPE_PENDING_CHOICE,
addWucaiReward,
fetchWucaiUser,
isValidWucaiType,
normalizeWucaiUser,
} from "./wucaiMigration";
const db = cloud.database();
export default async function wucaiTransfer(ctx: FunctionContext) {
const body = ctx.body || {};
const uid = body.uid;
const action = String(body.action || "");
if (body.gameName === "iaa") {
return fail("WUCAI_UNSUPPORTED_GAME", "五彩账号迁移仅支持主用户库");
}
if (!uid) {
return fail("WUCAI_UID_REQUIRED", "未获取到uid");
}
if (!isSupportedAction(action)) {
return fail("WUCAI_INVALID_ACTION", "无效的五彩迁移动作");
}
const userResult = await db.collection("users").where({ _id: uid }).getOne();
const user = userResult.data;
if (!user) {
return fail("WUCAI_USER_NOT_FOUND", "未获取到玩家信息");
}
if (!user.token || !body.token || !Utils.checkToken(body.token, user.token)) {
return fail("TOKEN_INVALID", "token校验失败");
}
if (!isValidWucaiType(user.wucai_type)) {
return fail("WUCAI_INVALID_STATE", "五彩迁移状态异常");
}
const expectedType = action === "claim_reward"
? WUCAI_TYPE_AUTO_MIGRATED
: WUCAI_TYPE_PENDING_CHOICE;
const nextType = action === "choose_current"
? WUCAI_TYPE_CHOSE_CURRENT
: WUCAI_TYPE_CHOSE_WUCAI;
const currentType = Number(user.wucai_type);
if (action === "ack_reward_popup") {
return acknowledgeRewardPopup(uid, currentType, user);
}
if (currentType === nextType) {
return success(
nextType,
user.wucai_reward_popup_pending === true,
action === "claim_reward" ? user : null,
);
}
if (currentType !== expectedType) {
return fail("WUCAI_INVALID_STATE", "当前状态不能执行该迁移动作", { wucai_type: currentType });
}
let update: any;
if (action === "choose_wucai") {
const source = await fetchWucaiUser(user.unionid);
if (!source) {
return fail("WUCAI_SOURCE_UNAVAILABLE", "五彩数据获取失败,请重新进入游戏后重试");
}
const migratedUser = normalizeWucaiUser(source);
update = {
...migratedUser,
...addWucaiReward(migratedUser),
wucai_type: nextType,
wucai_reward_popup_pending: true,
forcedUpdate: true,
};
} else {
update = {
...addWucaiReward(user),
wucai_type: nextType,
wucai_reward_popup_pending: action === "choose_current",
forcedUpdate: true,
};
}
const updateResult = await db.collection("users").where({
_id: uid,
wucai_type: expectedType,
}).update(update);
if (isUpdateFailed(updateResult)) {
const latestResult = await db.collection("users").where({ _id: uid }).getOne();
const latestType = Number(latestResult.data?.wucai_type);
if (latestType === nextType) {
return success(
nextType,
latestResult.data?.wucai_reward_popup_pending === true,
action === "claim_reward" ? latestResult.data : null,
);
}
return fail("WUCAI_STATE_CHANGED", "迁移状态已经变化,请重新登录", { wucai_type: latestType });
}
return success(
nextType,
action !== "claim_reward",
action === "claim_reward" ? update : null,
);
}
function isSupportedAction(action: string): boolean {
return action === "claim_reward"
|| action === "choose_wucai"
|| action === "choose_current"
|| action === "ack_reward_popup";
}
function isUpdateFailed(result: any): boolean {
return Boolean(result && (result.ok === false || result.updated === 0));
}
async function acknowledgeRewardPopup(uid: any, currentType: number, user: any) {
if (currentType !== WUCAI_TYPE_CHOSE_WUCAI && currentType !== WUCAI_TYPE_CHOSE_CURRENT) {
return fail("WUCAI_INVALID_STATE", "当前状态不能确认迁移奖励弹窗", { wucai_type: currentType });
}
if (user.wucai_reward_popup_pending !== true) {
return popupAcknowledged(currentType);
}
const updateResult = await db.collection("users").where({
_id: uid,
wucai_type: currentType,
wucai_reward_popup_pending: true,
}).update({ wucai_reward_popup_pending: false });
if (isUpdateFailed(updateResult)) {
const latestResult = await db.collection("users").where({ _id: uid }).getOne();
const latestType = Number(latestResult.data?.wucai_type);
if ((latestType === WUCAI_TYPE_CHOSE_WUCAI || latestType === WUCAI_TYPE_CHOSE_CURRENT)
&& latestResult.data?.wucai_reward_popup_pending !== true) {
return popupAcknowledged(latestType);
}
return fail("WUCAI_STATE_CHANGED", "迁移奖励弹窗状态已经变化,请重新登录", {
wucai_type: latestType,
});
}
return popupAcknowledged(currentType);
}
function success(wucaiType: number, rewardPopupPending: boolean, rewardUser: any = null) {
const rewardData = rewardUser
? {
coinAmount: Number(rewardUser.coinAmount),
freezeAmount: Number(rewardUser.freezeAmount),
hammerAmount: Number(rewardUser.hammerAmount),
magicAmount: Number(rewardUser.magicAmount),
}
: {};
return {
code: 1,
data: {
wucai_type: wucaiType,
wucai_reward_popup_pending: rewardPopupPending,
forcedUpdate: true,
...rewardData,
},
msg: "五彩账号迁移处理成功",
};
}
function popupAcknowledged(wucaiType: number) {
return {
code: 1,
data: {
wucai_type: wucaiType,
wucai_reward_popup_pending: false,
},
msg: "迁移奖励弹窗已确认",
};
}
function fail(errorCode: string, msg: string, data: any = null) {
return { code: 0, errorCode, data, msg };
}