fix(admin): decode recharge order enum cells
This commit is contained in:
@@ -725,7 +725,7 @@ fn parse_admin_database_table_rows_sql_response(
|
||||
.ok_or_else(|| "SQL rows 字段格式非法".to_string())?;
|
||||
let rows = row_values
|
||||
.iter()
|
||||
.map(|row| build_admin_database_table_row(row, &columns))
|
||||
.map(|row| build_admin_database_table_row_for_table(table_name, row, &columns))
|
||||
.collect::<Vec<_>>();
|
||||
Ok(AdminDatabaseTableRowsResponse {
|
||||
table_name: table_name.to_string(),
|
||||
@@ -769,7 +769,15 @@ fn extract_sql_statement_columns(statement: &Value) -> Vec<String> {
|
||||
}
|
||||
|
||||
fn build_admin_database_table_row(row: &Value, columns: &[String]) -> AdminDatabaseTableRowPayload {
|
||||
let raw = normalize_admin_database_value(row);
|
||||
build_admin_database_table_row_for_table("", row, columns)
|
||||
}
|
||||
|
||||
fn build_admin_database_table_row_for_table(
|
||||
table_name: &str,
|
||||
row: &Value,
|
||||
columns: &[String],
|
||||
) -> AdminDatabaseTableRowPayload {
|
||||
let raw = normalize_admin_database_table_row_raw(table_name, row, columns);
|
||||
let mut cells = Map::new();
|
||||
if let Some(values) = row.as_array() {
|
||||
for (index, value) in values.iter().enumerate() {
|
||||
@@ -777,11 +785,17 @@ fn build_admin_database_table_row(row: &Value, columns: &[String]) -> AdminDatab
|
||||
.get(index)
|
||||
.cloned()
|
||||
.unwrap_or_else(|| format!("col_{}", index + 1));
|
||||
cells.insert(key, normalize_admin_database_value(value));
|
||||
cells.insert(
|
||||
key.clone(),
|
||||
normalize_admin_database_table_cell(table_name, &key, value),
|
||||
);
|
||||
}
|
||||
} else if let Some(object) = row.as_object() {
|
||||
for (key, value) in object {
|
||||
cells.insert(key.clone(), normalize_admin_database_value(value));
|
||||
cells.insert(
|
||||
key.clone(),
|
||||
normalize_admin_database_table_cell(table_name, key, value),
|
||||
);
|
||||
}
|
||||
}
|
||||
AdminDatabaseTableRowPayload {
|
||||
@@ -790,6 +804,85 @@ fn build_admin_database_table_row(row: &Value, columns: &[String]) -> AdminDatab
|
||||
}
|
||||
}
|
||||
|
||||
fn normalize_admin_database_table_row_raw(
|
||||
table_name: &str,
|
||||
row: &Value,
|
||||
columns: &[String],
|
||||
) -> Value {
|
||||
if let Some(values) = row.as_array() {
|
||||
return Value::Array(
|
||||
values
|
||||
.iter()
|
||||
.enumerate()
|
||||
.map(|(index, value)| {
|
||||
let key = columns.get(index).map(String::as_str).unwrap_or_default();
|
||||
normalize_admin_database_table_cell(table_name, key, value)
|
||||
})
|
||||
.collect(),
|
||||
);
|
||||
}
|
||||
|
||||
if let Some(object) = row.as_object() {
|
||||
return Value::Object(
|
||||
object
|
||||
.iter()
|
||||
.map(|(key, value)| {
|
||||
(
|
||||
key.clone(),
|
||||
normalize_admin_database_table_cell(table_name, key, value),
|
||||
)
|
||||
})
|
||||
.collect(),
|
||||
);
|
||||
}
|
||||
|
||||
normalize_admin_database_value(row)
|
||||
}
|
||||
|
||||
fn normalize_admin_database_table_cell(
|
||||
table_name: &str,
|
||||
column_name: &str,
|
||||
value: &Value,
|
||||
) -> Value {
|
||||
if let Some(enum_value) = normalize_admin_database_known_enum(table_name, column_name, value) {
|
||||
return enum_value;
|
||||
}
|
||||
normalize_admin_database_value(value)
|
||||
}
|
||||
|
||||
fn normalize_admin_database_known_enum(
|
||||
table_name: &str,
|
||||
column_name: &str,
|
||||
value: &Value,
|
||||
) -> Option<Value> {
|
||||
let variant_index = extract_sats_enum_variant_index(value)?;
|
||||
let label = match (table_name, column_name) {
|
||||
("profile_recharge_order", "kind") => match variant_index {
|
||||
0 => "points",
|
||||
1 => "membership",
|
||||
_ => return None,
|
||||
},
|
||||
("profile_recharge_order", "status") => match variant_index {
|
||||
0 => "pending",
|
||||
1 => "paid",
|
||||
2 => "failed",
|
||||
3 => "closed",
|
||||
4 => "refunded",
|
||||
_ => return None,
|
||||
},
|
||||
_ => return None,
|
||||
};
|
||||
Some(Value::String(label.to_string()))
|
||||
}
|
||||
|
||||
fn extract_sats_enum_variant_index(value: &Value) -> Option<u64> {
|
||||
let items = value.as_array()?;
|
||||
if items.len() != 2 {
|
||||
return None;
|
||||
}
|
||||
items.first()?.as_u64()
|
||||
}
|
||||
|
||||
fn normalize_admin_database_value(value: &Value) -> Value {
|
||||
match value {
|
||||
Value::Array(items) if items.len() == 1 => normalize_admin_database_value(&items[0]),
|
||||
@@ -1526,6 +1619,46 @@ mod tests {
|
||||
assert_eq!(response.rows[0].cells["points"], json!(12));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn parse_admin_database_table_rows_sql_response_maps_recharge_order_enum_cells() {
|
||||
let payload = json!([
|
||||
{
|
||||
"schema": {
|
||||
"elements": [
|
||||
{"name": {"some": "order_id"}},
|
||||
{"name": {"some": "kind"}},
|
||||
{"name": {"some": "status"}},
|
||||
{"name": {"some": "paid_at"}}
|
||||
]
|
||||
},
|
||||
"rows": [[
|
||||
"recharge:user_00000001:1778757456811099:points_60",
|
||||
[0, []],
|
||||
[0, []],
|
||||
[1, []]
|
||||
]]
|
||||
}
|
||||
]);
|
||||
|
||||
let response =
|
||||
parse_admin_database_table_rows_sql_response("profile_recharge_order", 100, payload)
|
||||
.expect("recharge order rows should parse");
|
||||
|
||||
let cells = &response.rows[0].cells;
|
||||
assert_eq!(cells["kind"], json!("points"));
|
||||
assert_eq!(cells["status"], json!("pending"));
|
||||
assert_eq!(cells["paid_at"], json!(null));
|
||||
assert_eq!(
|
||||
response.rows[0].raw,
|
||||
json!([
|
||||
"recharge:user_00000001:1778757456811099:points_60",
|
||||
"points",
|
||||
"pending",
|
||||
null
|
||||
])
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn build_admin_database_table_row_normalizes_optional_sats_values() {
|
||||
let row = build_admin_database_table_row(
|
||||
|
||||
Reference in New Issue
Block a user