42 lines
1.8 KiB
C#
42 lines
1.8 KiB
C#
namespace WxAgent.Core;
|
|
|
|
public sealed record WechatDatabaseContact(string Username, string? NickName, string? Remark, string? AvatarUrl)
|
|
{
|
|
public string DisplayName => !string.IsNullOrWhiteSpace(Remark) ? Remark :
|
|
!string.IsNullOrWhiteSpace(NickName) ? NickName : Username;
|
|
}
|
|
|
|
public sealed record WechatContactPage(IReadOnlyList<WechatDatabaseContact> Contacts, int? NextOffset)
|
|
{
|
|
public bool HasMore => NextOffset is not null;
|
|
}
|
|
|
|
public static class WechatContactQuery
|
|
{
|
|
// Stable IDs, not display names, define ordering and identity. No UI fallback.
|
|
public const string Sql = """
|
|
SELECT username, nick_name, remark, small_head_url FROM contact
|
|
WHERE ($contains IS NULL OR instr(username, $contains) > 0
|
|
OR instr(nick_name, $contains) > 0 OR instr(remark, $contains) > 0)
|
|
AND ($groups IS NULL OR (substr(username, -9) = '@chatroom') = $groups)
|
|
ORDER BY username COLLATE BINARY LIMIT $limit OFFSET $offset;
|
|
""";
|
|
|
|
public static IReadOnlyList<KeyValuePair<string, object?>> Parameters(int limit, int offset, string? contains, bool? groupsOnly)
|
|
{
|
|
if (limit is < 1 or > 10000 || offset < 0 || offset > int.MaxValue - limit)
|
|
throw new WxAgentException(WxAgentErrorCode.InvalidArgument, "Contact limit must be 1-10000 and offset must leave room for the next page.");
|
|
return new KeyValuePair<string, object?>[]
|
|
{
|
|
new("$limit", limit + 1), new("$offset", offset), new("$contains", contains),
|
|
new("$groups", groupsOnly is null ? null : groupsOnly.Value ? 1 : 0)
|
|
};
|
|
}
|
|
|
|
public static WechatContactPage Page(IReadOnlyList<WechatDatabaseContact> rows, int limit, int offset)
|
|
{
|
|
_ = Parameters(limit, offset, null, null);
|
|
return new(rows.Take(limit).ToArray(), rows.Count > limit ? offset + limit : null);
|
|
}
|
|
}
|