177 lines
5.9 KiB
TypeScript
177 lines
5.9 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,
|
|
hasWucaiRewardGranted,
|
|
isValidWucaiType,
|
|
normalizeWucaiUser,
|
|
wucaiMatch,
|
|
wucaiState,
|
|
} 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 rewardGranted = hasWucaiRewardGranted(user);
|
|
// A delayed claim response must not finish or reward a later selection round.
|
|
if (action === "claim_reward" && rewardGranted) {
|
|
return success(user, true);
|
|
}
|
|
if ((body.wucai_entry_id || "") !== (user.wucai_entry_id || "")) {
|
|
return fail("WUCAI_STATE_CHANGED", "迁移轮次已经变化,请重新登录", wucaiState(user));
|
|
}
|
|
|
|
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(user, action === "claim_reward");
|
|
}
|
|
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,
|
|
monthCardReward: Math.max(migratedUser.monthCardReward, Number(user.monthCardReward) || 0),
|
|
...(!rewardGranted ? addWucaiReward(migratedUser) : {}),
|
|
};
|
|
} else {
|
|
update = !rewardGranted ? addWucaiReward(user) : {};
|
|
}
|
|
Object.assign(update, {
|
|
wucai_type: nextType,
|
|
wucai_reward_granted: true,
|
|
wucai_reward_popup_pending: user.wucai_reward_popup_pending === true
|
|
|| (!rewardGranted && action !== "claim_reward"),
|
|
forcedUpdate: true,
|
|
});
|
|
|
|
const updateResult = await (cloud.mongo.db as any).collection("users").updateOne(
|
|
wucaiMatch(user, Object.keys(update)), { $set: update },
|
|
);
|
|
if (!updateResult.matchedCount) {
|
|
const latestResult = await db.collection("users").where({ _id: uid }).getOne();
|
|
const latestType = Number(latestResult.data?.wucai_type);
|
|
if (latestResult.data && (latestResult.data.wucai_entry_id || "") === (user.wucai_entry_id || "")
|
|
&& latestType === nextType) {
|
|
return success(latestResult.data, action === "claim_reward");
|
|
}
|
|
return fail("WUCAI_STATE_CHANGED", "迁移状态已经变化,请重新登录", { wucai_type: latestType });
|
|
}
|
|
|
|
return success({ ...user, ...update }, action === "claim_reward");
|
|
}
|
|
|
|
function isSupportedAction(action: string): boolean {
|
|
return action === "claim_reward"
|
|
|| action === "choose_wucai"
|
|
|| action === "choose_current"
|
|
|| action === "ack_reward_popup";
|
|
}
|
|
|
|
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(user);
|
|
}
|
|
|
|
const updateResult = await (cloud.mongo.db as any).collection("users").updateOne(
|
|
wucaiMatch(user), { $set: { wucai_reward_popup_pending: false } },
|
|
);
|
|
if (!updateResult.matchedCount) {
|
|
const latestResult = await db.collection("users").where({ _id: uid }).getOne();
|
|
const latestType = Number(latestResult.data?.wucai_type);
|
|
if (latestResult.data && (latestResult.data.wucai_entry_id || "") === (user.wucai_entry_id || "")
|
|
&& (latestType === WUCAI_TYPE_CHOSE_WUCAI || latestType === WUCAI_TYPE_CHOSE_CURRENT)
|
|
&& latestResult.data?.wucai_reward_popup_pending !== true) {
|
|
return popupAcknowledged(latestResult.data);
|
|
}
|
|
return fail("WUCAI_STATE_CHANGED", "迁移奖励弹窗状态已经变化,请重新登录", {
|
|
wucai_type: latestType,
|
|
});
|
|
}
|
|
return popupAcknowledged({ ...user, wucai_reward_popup_pending: false });
|
|
}
|
|
|
|
function success(user: any, includeResources = false) {
|
|
const rewardData = includeResources
|
|
? {
|
|
coinAmount: Number(user.coinAmount),
|
|
freezeAmount: Number(user.freezeAmount),
|
|
hammerAmount: Number(user.hammerAmount),
|
|
magicAmount: Number(user.magicAmount),
|
|
}
|
|
: {};
|
|
return {
|
|
code: 1,
|
|
data: {
|
|
...wucaiState(user),
|
|
forcedUpdate: true,
|
|
...rewardData,
|
|
},
|
|
msg: "五彩账号迁移处理成功",
|
|
};
|
|
}
|
|
|
|
function popupAcknowledged(user: any) {
|
|
return {
|
|
code: 1,
|
|
data: wucaiState(user),
|
|
msg: "迁移奖励弹窗已确认",
|
|
};
|
|
}
|
|
|
|
function fail(errorCode: string, msg: string, data: any = null) {
|
|
return { code: 0, errorCode, data, msg };
|
|
}
|