Merge remote-tracking branch 'origin/master'
Some checks failed
CI / verify (push) Has been cancelled

This commit is contained in:
2026-05-12 13:59:28 +08:00
119 changed files with 10021 additions and 2230 deletions

View File

@@ -192,7 +192,6 @@ pub struct ProfileInviteCode {
pub(crate) starts_at: Option<Timestamp>,
#[default(None::<Timestamp>)]
pub(crate) expires_at: Option<Timestamp>,
pub(crate) granted_user_tags: Vec<String>,
}
#[spacetimedb::table(
@@ -2201,7 +2200,8 @@ fn redeem_profile_referral_invite_code_record(
if inviter_code.user_id == invitee_user_id {
return Err("不能填写自己的邀请码".to_string());
}
let granted_user_tags = inviter_code.granted_user_tags.clone();
let invite_metadata_user_tags =
profile_invite_code_metadata_user_tags(&inviter_code.metadata_json)?;
let invitee_balance_after = apply_profile_wallet_delta(
ctx,
@@ -2248,7 +2248,7 @@ fn redeem_profile_referral_invite_code_record(
invitee_reward_granted: true,
bound_at,
});
merge_user_account_tags(ctx, &invitee_user_id, granted_user_tags)?;
merge_user_account_tags(ctx, &invitee_user_id, invite_metadata_user_tags)?;
Ok(RuntimeReferralRedeemSnapshot {
center: build_profile_referral_invite_center_snapshot(ctx, &invitee_user_id),
@@ -2422,7 +2422,6 @@ fn admin_upsert_profile_invite_code_record(
input.admin_user_id,
input.invite_code,
input.metadata_json,
input.granted_user_tags,
input.starts_at_micros,
input.expires_at_micros,
input.updated_at_micros,
@@ -2459,7 +2458,6 @@ fn admin_upsert_profile_invite_code_record(
expires_at: validated_input
.expires_at_micros
.map(Timestamp::from_micros_since_unix_epoch),
granted_user_tags: validated_input.granted_user_tags,
});
return Ok(build_profile_invite_code_snapshot_from_row(&inserted));
}
@@ -2476,7 +2474,6 @@ fn admin_upsert_profile_invite_code_record(
expires_at: validated_input
.expires_at_micros
.map(Timestamp::from_micros_since_unix_epoch),
granted_user_tags: validated_input.granted_user_tags,
});
Ok(build_profile_invite_code_snapshot_from_row(&inserted))
}
@@ -2603,7 +2600,6 @@ fn ensure_profile_invite_code(ctx: &ReducerContext, user_id: &str) -> ProfileInv
updated_at: ctx.timestamp,
starts_at: None,
expires_at: None,
granted_user_tags: Vec::new(),
})
}
@@ -2622,14 +2618,33 @@ fn merge_user_account_tags(
return Err("用户不存在".to_string());
};
account.user_tags.extend(granted_tags);
let mut next_tags = account.user_tags.take().unwrap_or_default();
next_tags.extend(granted_tags);
account.user_tags =
normalize_profile_user_tags(account.user_tags).map_err(|error| error.to_string())?;
Some(normalize_profile_user_tags(next_tags).map_err(|error| error.to_string())?);
ctx.db.user_account().user_id().delete(&account.user_id);
ctx.db.user_account().insert(account);
Ok(())
}
fn profile_invite_code_metadata_user_tags(metadata_json: &str) -> Result<Vec<String>, String> {
let metadata = serde_json::from_str::<JsonValue>(metadata_json)
.map_err(|_| RuntimeProfileFieldError::InvalidInviteCodeMetadata.to_string())?;
let tags = metadata
.get("userTags")
.or_else(|| metadata.get("user_tags"))
.and_then(JsonValue::as_array)
.map(|items| {
items
.iter()
.filter_map(JsonValue::as_str)
.map(str::to_string)
.collect::<Vec<_>>()
})
.unwrap_or_default();
normalize_profile_user_tags(tags).map_err(|error| error.to_string())
}
fn validate_profile_invite_code_redeem_time(
invite_code: &ProfileInviteCode,
now_micros: i64,
@@ -3654,7 +3669,6 @@ fn build_profile_invite_code_snapshot_from_row(
user_id: row.user_id.clone(),
invite_code: row.invite_code.clone(),
metadata_json: row.metadata_json.clone(),
granted_user_tags: row.granted_user_tags.clone(),
starts_at_micros: row
.starts_at
.map(|value| value.to_micros_since_unix_epoch()),