ZhileTime.QiaoFang 1.2.1

dotnet add package ZhileTime.QiaoFang --version 1.2.1
                    
NuGet\Install-Package ZhileTime.QiaoFang -Version 1.2.1
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="ZhileTime.QiaoFang" Version="1.2.1" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="ZhileTime.QiaoFang" Version="1.2.1" />
                    
Directory.Packages.props
<PackageReference Include="ZhileTime.QiaoFang" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add ZhileTime.QiaoFang --version 1.2.1
                    
#r "nuget: ZhileTime.QiaoFang, 1.2.1"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package ZhileTime.QiaoFang@1.2.1
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=ZhileTime.QiaoFang&version=1.2.1
                    
Install as a Cake Addin
#tool nuget:?package=ZhileTime.QiaoFang&version=1.2.1
                    
Install as a Cake Tool

ZhileTime.QiaoFang

一个面向「巧房 OpenPlatform」的 .NET 客户端库(独立于 ZhileTime.Hope.Yop)。

运行环境

  • 目标框架:net10.0
  • 推荐:使用与你项目一致的 .NET SDK

安装

dotnet add package ZhileTime.QiaoFang

快速开始(DI)

services.AddQiaoFang(options =>
{
    options.Host = "https://example.com";
    options.AppId = "...";
    options.AppSecret = "...";
    options.CompanyUuid = "...";
    // 可选:用于区分不同环境/项目的 key 前缀
    // options.CachePrefix = "myapp:prod";
});

var client = serviceProvider.GetRequiredService<IQiaoFangClient>();

// 可选:使用封装好的 Services 层
var service = serviceProvider.GetRequiredService<IQiaoFangService>();

也支持从配置文件绑定:

// appsettings.json: "QiaoFang": { "Host": "...", "AppId": "...", ... }
services.AddQiaoFang(configuration);

Options Resolver(可选)

当你希望在运行时动态提供/覆盖 Host/AppId/AppSecret/CompanyUuid 时,可以实现 IQiaoFangOptionsResolver。

注册方式 1:通过 DI(推荐:resolver 需要依赖注入/需要复用)

services.AddSingleton<IQiaoFangOptionsResolver, MyQiaoFangOptionsResolver>();
services.AddQiaoFang(configuration);

注:为了支持 resolver 使用 Scoped/Transient 生命周期且避免在 Options 构建期实例化 resolver,推荐使用下方的注册方式(方式 1.1)。

注册方式 1.1:通过常规 DI 注册(推荐:支持 scoped/transient)

services.AddScoped<IQiaoFangOptionsResolver, MyQiaoFangOptionsResolver>();
// 注意:推荐在 AddQiaoFang(...) 之前注册 resolver,便于 SDK 自动捕获其类型并参与解析。
services.AddQiaoFang(configuration);

如果你必须在调用 AddQiaoFang(...) 之后才注册 resolver,则需要额外把 resolver 类型加入:

services.AddScoped<IQiaoFangOptionsResolver, MyQiaoFangOptionsResolver>();
services.Configure<ZhileTime.QiaoFang.Client.QiaoFangClientOptions>(o =>
{
    o.Resolvers.Add<MyQiaoFangOptionsResolver>();
});

注册方式 2:通过 QiaoFangClientOptions.Resolvers 追加 resolver 类型

services.AddQiaoFang(o =>
{
    o.Resolvers.Add<MyQiaoFangOptionsResolver>();
});

解析顺序:

  1. Request 的 per-call 覆盖字段
  2. Resolvers(按顺序遍历,命中第一个非 null 即停止;DI 注册的 resolver 会被自动加入到 QiaoFangClientOptions.Resolvers 的前部)
  3. 全局 QiaoFangClientOptions

注:QiaoFangClientOptions.Resolvers 默认为空;当集合为空时 SDK 不会调用解析器链路。

如需通过 Options 显式控制解析器链路,可在 AddQiaoFang 的配置中追加:

services.AddQiaoFang(o =>
{
    // 例:显式追加一个 resolver
    o.Resolvers.Add<MyQiaoFangOptionsResolver>();
});

多租户/ABP 集成建议

本包提供:

  • IQiaoFangClient(底层 SDK)
  • IQiaoFangService 及各子域 Service(可选的业务封装层)

当你在 ABP 中希望“按租户标识自动获取 AppId/AppSecret/Host 等配置”时,建议使用独立的集成包:

  • ZhileTime.Hope.QiaoFang

SDK 侧的合并优先级为:

  1. Request 上的 per-call 覆盖字段
  2. 租户解析器返回的租户配置
  3. 全局 QiaoFangClientOptions

默认行为:当 Request 已提供 Host/AppId/AppSecret/CompanyUuid 全部字段时,不会额外调用解析器。

如需每次请求都尝试解析(例如租户配置可能被动态更新),可开启:

services.AddQiaoFang(o =>
{
    o.ForceResolveOptions = true;
});

ABP 快速示例

// 注册:会启用租户级解析器,并默认允许全局 Options 留空
services.AddHopeQiaoFang(configuration);

// 可选:多实例共享 AccessToken(显式启用)
services.UseQiaoFangCsRedisCache(configuration);

// 使用:在 CurrentTenant 上下文中直接调用(AppId/AppSecret/Host 由 Setting 提供)
using (CurrentTenant.Change(tenantId))
{
    var svc = serviceProvider.GetRequiredService<IQiaoFangService>();
    // svc.Department / svc.UserCenter ...

    var client = serviceProvider.GetRequiredService<IQiaoFangClient>();

    // 示例 1:直接使用 Client(GET,无请求体)
    var departments = await client.SendAsync(new ZhileTime.QiaoFang.Requests.Organization.Department.GetAllDepartmentRequest());
}

AccessToken Redis 缓存(可选)

QiaoFangClient 支持跨实例共享 AccessToken。

本库不使用 IDistributedCache,如需跨实例共享 token,请启用 CSRedis。

方案:巧房专用 CSRedis

services.AddQiaoFang(configuration);

services.UseQiaoFangCsRedisCache(o =>
{
    o.ConnectionString = "127.0.0.1:6379,password=xxx,defaultDatabase=0";
});

也可以用配置文件绑定:

services.AddQiaoFang(configuration);
services.UseQiaoFangCsRedisCache(configuration);

对应配置示例(默认节名为 Redis:QiaoFang):

{
    "Redis": {
        "QiaoFang": {
            "ConnectionString": "127.0.0.1:6379,password=xxx,defaultDatabase=0"
        }
    }
}

Polly 重试(可选)

DI 已内置 Polly 重试策略(默认关闭),通过配置开启。

注意:默认对 POST 等非幂等请求也开启重试,但仅当服务端返回可重试的 HTTP 状态码(由 RetryOnStatusCodes 配置)时才会重试;不会因网络异常/超时而重试,以降低重复提交风险。

补充:由于 SDK 内部使用 CancellationTokenSource.CancelAfter 实现单次请求超时,超时会表现为取消异常;因此对 GET 等幂等请求的“超时重试”由客户端层补充实现,而不是依赖 Polly。

{
    "QiaoFang": {
        "Host": "https://example.com",
        "AppId": "...",
        "AppSecret": "...",
        "CompanyUuid": "...",
        "Retry": {
            "Enabled": true,
            "RetryNonIdempotentMethods": false,
            "MaxRetries": 3,
            "BaseDelayMs": 200,
            "MaxDelayMs": 2000,
            "RetryOnStatusCodes": [ 429, 500, 502, 503, 504 ]
        }
    }
}

通用营销(Marketing OpenApi)示例

通用营销接口通常要求在请求头中携带 appId,本 SDK 会在对应 Request 实现标记接口后自动处理。

时间字符串建议使用格式:yyyy-MM-dd HH:mm:ss。

var svc = serviceProvider.GetRequiredService<IQiaoFangService>();

// 1) 资源滚动拉取 uuid
var scroll = await svc.MarketingOpenApi.PullResourceUuidListAsync(
    new ZhileTime.QiaoFang.Requests.Marketing.Company.PullResourceUuidListRequest
    {
        ResourceType = "PROPERTY_BASE",
        Dto = new ZhileTime.QiaoFang.Requests.Marketing.Company.PullResourceUuidListRequest.PullResourceUuidListScrollDto
        {
            WindowSize = 200,
            UseAsc = true,
            StartUpdatedTime = "2026-02-01 00:00:00",
            EndUpdatedTime = "2026-02-05 00:00:00",
        },
    });

// 2) 搜索房源
var result = await svc.MarketingOpenApi.SearchPropertyAsync(
    new ZhileTime.QiaoFang.Requests.Marketing.CommonHouse.SearchPropertyRequest
    {
        PageDTO = new ZhileTime.QiaoFang.Requests.QiaoFangPageArgs { PageNum = 1, PageSize = 50 },
        SearchPropertyDTO = new ZhileTime.QiaoFang.Requests.Marketing.CommonHouse.SearchPropertyRequest.SearchPropertyParam
        {
            ExternalCompanyUuid = "company-uuid",
            TradeType = "SELL",
            StartUpdateTime = "2026-02-01 00:00:00",
            EndUpdateTime = "2026-02-05 00:00:00",
        },
    });

房源/楼盘接口示例

建议优先使用 IQiaoFangService 的子域服务:

var svc = serviceProvider.GetRequiredService<IQiaoFangService>();

// 房源:查询跟进
var follows = await svc.Property.SearchPropertyFollowAsync(
    new ZhileTime.QiaoFang.Requests.Property.CommonHouse.SearchPropertyFollowRequest
    {
        Page = new ZhileTime.QiaoFang.Requests.QiaoFangPageArgs
        {
            PageNum = 1,
            PageSize = 50,
        },
        Param = new ZhileTime.QiaoFang.Requests.Property.CommonHouse.SearchPropertyFollowRequest.SearchPropertyFollowParam
        {
            PropertyUuids = new List<string> { "property-uuid-1" },
        },
    });

// 楼盘:按时间范围查询(Unix 时间戳:毫秒/秒以接口实际约定为准)
var estates = await svc.Estate.SearchEstateAsync(
    new ZhileTime.QiaoFang.Requests.Estate.SearchEstateRequest
    {
        Page = new ZhileTime.QiaoFang.Requests.QiaoFangPageArgs
        {
            PageNum = 1,
            PageSize = 50,
        },
        Param = new ZhileTime.QiaoFang.Requests.Estate.SearchEstateRequest.SearchEstateParam
        {
            StartTime = 1735689600000,
            EndTime = 1735776000000,
        },
    });

更多 API 请参考 IQiaoFangClient / IQiaoFangService 及 ZhileTime.QiaoFang.Requests.*。

Product Compatible and additional computed target framework versions.
.NET net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (1)

Showing the top 1 NuGet packages that depend on ZhileTime.QiaoFang:

Package Downloads
ZhileTime.Hope.QiaoFang

HOPE modular application framework package: ZhileTime.Hope.QiaoFang.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.2.1 143 2/5/2026
1.2.0 306 2/5/2026

变更记录请参考包内 CHANGELOG.md。