# 外部集成

<cite>
**本文档中引用的文件**  
- [main.go](file://main.go)
- [config.go](file://utility/otel/config.go)
- [manager.go](file://utility/otel/manager.go)
- [utils.go](file://utility/otel/utils.go)
- [rbac_model.conf](file://resource/casbin/rbac_model.conf)
- [api.go](file://utility/integration/redeem/jd/api.go)
- [api.go](file://utility/integration/redeem/ctrip/api.go)
- [api.go](file://utility/integration/redeem/walmart/api.go)
- [api.go](file://utility/integration/tmall/api/api.go)
- [client.go](file://utility/integration/originalJd/client.go) - *新增京东订单创建及支付链接刷新功能*
- [model.go](file://utility/integration/originalJd/model.go) - *更新京东订单相关模型定义*
- [order.go](file://internal/logic/jd_cookie/order.go) - *实现订单复用逻辑*
</cite>

## 更新摘要
**变更内容**   

- 更新了京东集成部分，修复了订单ID字段类型问题，将OrderId类型从json.Number调整为string
- 修正了京东接口字段名，将card_pass字段名更改为card_pwd，保持与上游接口一致
- 修改了获取卡密接口的JSON字段名，并新增order_status字段
- 调整了京东订单字段命名，将AppleRechargeCardInfoReq中的OrderNo重命名为OrderId
- 更新了相关代码示例和架构图
- 新增了订单状态检查和复用逻辑的实现细节
- 更新了故障排除指南，增加了订单复用相关的常见问题

## 目录
1. [简介](#简介)
2. [电商平台API集成](#电商平台api集成)
3. [OpenTelemetry集成](#opentelemetry集成)
4. [Casbin权限系统集成](#casbin权限系统集成)
5. [故障排除指南](#故障排除指南)
6. [结论](#结论)

## 简介
本文档详细说明了kami_backend系统的外部集成机制，涵盖第三方电商平台API集成、OpenTelemetry可观测性系统集成以及Casbin权限控制系统的实现。文档旨在为开发人员提供全面的技术指导，包括集成架构、配置选项、使用模式和技术决策。

## 电商平台API集成

kami_backend通过`utility/integration`包实现了与多个电商平台的集成，包括京东、天猫、Ctrip和沃尔玛等。每个平台都有独立的子包，遵循统一的设计模式和接口规范。

### 京东集成
京东集成位于`utility/integration/redeem/jd`目录下，通过`Client`结构体封装API调用。该集成支持账户管理、订单提交和状态查询等核心功能。

**Section sources**
- [api.go](file://utility/integration/redeem/jd/api.go#L1-L5)

### Ctrip集成
Ctrip集成位于`utility/integration/redeem/ctrip`目录下，提供完整的API客户端实现。集成包括服务接口定义、数据模型和业务逻辑处理。

**Section sources**
- [api.go](file://utility/integration/redeem/ctrip/api.go#L1-L5)

### 沃尔玛集成
沃尔玛集成位于`utility/integration/redeem/walmart`目录下，通过`Client`结构体提供统一的访问接口。该集成支持多账户管理和订单生命周期跟踪。

**Section sources**
- [api.go](file://utility/integration/redeem/walmart/api.go#L1-L5)

### 天猫集成
天猫集成位于`utility/integration/tmall`目录下，采用单例模式通过`NewClient()`函数获取客户端实例。集成包含API调用、OAuth认证和定时任务同步功能。

```mermaid
classDiagram
class InnerClient {
+NewClient() *InnerClient
}
class api {
+NewClient()
}
class topsdk {
+topclient
+abilities
}
InnerClient --> api : "实现"
InnerClient --> topsdk : "依赖"
```

**Diagram sources**
- [api.go](file://utility/integration/tmall/api/api.go#L1-L20)

**Section sources**
- [api.go](file://utility/integration/tmall/api/api.go#L1-L20)

### 京东Cookie订单集成
京东Cookie订单集成位于`utility/integration/originalJd`目录下，提供了完整的京东订单管理功能，包括订单创建、支付链接刷新和支付状态检查。

#### 订单创建
通过`AppleRecharge`方法实现京东订单创建，接收订单面值、品类、订单号和Cookie等参数，返回京东订单号、支付ID和微信支付链接。

```go
func (c *Client) AppleRecharge(ctx context.Context, input *AppleRechargeReq) (*AppleRechargeResp, error) {
	var resp = &AppleRechargeResp{}
	glog.Info(ctx, "苹果权益充值", input)

	for range 3 {
		response, err := c.Client.ContentJson().Post(ctx, "http://jd_babel_channel:8289/jd/app/store", input)
		if err != nil {
			return resp, err
		}

		respData := response.ReadAllString()
		clientResp := AppleRechargeClientResp{}
		glog.Info(ctx, "获取信息", respData)
		err = json.Unmarshal([]byte(respData), &clientResp)
		if err != nil {
			glog.Error(ctx, "获取信息失败", err)
			return resp, err
		}
		resp = &AppleRechargeResp{
			Code:     clientResp.Code.JDOrderStatus(),
			Deeplink: clientResp.Data.Deeplink,
			OrderId:  clientResp.Data.OrderId,
			PayId:    clientResp.Data.PayId,
			Msg:      clientResp.Data.Remark,
		}
		if clientResp.Code == RiskError {
			continue
		}
		if clientResp.Code != Success {
			return resp, gerror.New("苹果权益充值失败，" + clientResp.Data.Remark)
		}
		break
	}
	if resp == nil {
		return resp, gerror.New("苹果权益充值失败")
	}
	return resp, nil
}
```

#### 支付链接刷新
通过`RefreshPayment`方法实现支付链接刷新功能，当原有支付链接过期时，可以重新获取新的支付链接。

```go
func (c *Client) RefreshPayment(ctx context.Context, input *RefreshPaymentReq) (*RefreshPaymentRes, error) {
	resp := &RefreshPaymentRes{}
	glog.Info(ctx, "刷新收银台参数", input)
	response, err := c.Client.ContentJson().Post(ctx, "http://jd_babel_channel:8289/api/v1/jd/wx/refresh-payment", input)
	if err != nil {
		return resp, err
	}
	clientResp := &AppleRechargeClientResp{}
	err = json.Unmarshal(response.ReadAll(), clientResp)
	glog.Info(ctx, "刷新收银台返回值", clientResp)
	if err != nil {
		return resp, err
	}
	resp = &RefreshPaymentRes{
		Code:     clientResp.Code.JDOrderStatus(),
		Deeplink: clientResp.Data.Deeplink,
		OrderId:  clientResp.Data.OrderId,
		PayId:    clientResp.Data.PayId,
		Msg:      clientResp.Data.Remark,
	}
	if clientResp.Code != Success {
		return resp, gerror.New("苹果权益充值失败")
	}
	return resp, nil
}
```

#### 支付状态检查
通过`CheckOrderPayment`方法检查京东订单的支付状态，返回支付状态、订单状态和是否可复用等信息。

```go
func (c *Client) CheckOrderPayment(ctx context.Context, input *CheckOrderPaymentReq) (*CheckOrderPaymentResp, error) {
	resp := &CheckOrderPaymentResp{}
	glog.Info(ctx, "检查京东订单支付状态", input)

	response, err := c.Client.ContentJson().Post(ctx, "http://jd_babel_channel:8289/api/jd/query/order/payment", input)
	if err != nil {
		return resp, err
	}

	clientResp := &CheckOrderPaymentClientResp{}
	err = json.Unmarshal(response.ReadAll(), clientResp)
	glog.Info(ctx, "检查京东订单支付状态响应", response.ReadAllString())
	if err != nil {
		return resp, err
	}

	resp = &CheckOrderPaymentResp{
		PaymentStatus: clientResp.Data.PaymentStatus,
		OrderStatus:   clientResp.Data.OrderStatus,
		CanReuse:      clientResp.Data.CanReuse,
		IsPaid:        clientResp.Data.PaymentStatus == 2, // 2表示已支付
	}

	if clientResp.Code != Success {
		return resp, gerror.New("检查京东订单支付状态失败: " + clientResp.Msg)
	}

	return resp, nil
}
```

#### 获取卡密信息

通过`GetCardInfo`方法获取京东订单的卡号和卡密，修正了接口字段名，将card_pass字段名更改为card_pwd，并新增order_status字段。

```go
func (c *Client) GetCardInfo(ctx context.Context, input *AppleRechargeCardInfoReq) (resp *AppleRechargeCardInfoResp, err error) {
	response, err := c.Client.ContentJson().Post(ctx, "http://jd_babel_channel:8289/jd/query/card", input)
	if err != nil {
		return
	}
	clientResp := struct {
		Code int    `json:"code"`
		Msg  string `json:"msg"`
		Data struct {
			Remark      string `json:"remark"`
			CardPwd     string `json:"card_pwd"`
			CardNo      string `json:"card_num"`
			OrderStatus string `json:"order_status"`
		} `json:"data,omitempty"`
	}{}
	err = json.Unmarshal(response.ReadAll(), &clientResp)
	glog.Info(ctx, "获取京东订单的卡号和卡密", clientResp, err)
	if err != nil {
		return
	}
	resp = &AppleRechargeCardInfoResp{
		OrderStatus:  clientResp.Data.OrderStatus,
		Remark:       clientResp.Data.Remark,
		CardNo:       clientResp.Data.CardNo,
		IsCkFailed:   clientResp.Code == int(CkError),
		CardPassword: clientResp.Data.CardPwd,
	}
	if clientResp.Code != int(Success) || clientResp.Data.CardNo == "" {
		return resp, gerror.New("状态不正确")
	}
	return
}
```

**Section sources**
- [client.go](file://utility/integration/originalJd/client.go#L11-L123)
- [model.go](file://utility/integration/originalJd/model.go#L1-L144)

## OpenTelemetry集成

OpenTelemetry集成在`utility/otel`包中实现，提供统一的可观测性解决方案，包括链路追踪、指标收集和日志导出。

### 配置结构
`Config`结构体定义了OpenTelemetry的配置参数，包括服务名称、收集器URL、安全设置和采样率等。默认配置通过`DefaultConfig()`函数提供。

```mermaid
classDiagram
class Config {
+ServiceName string
+CollectorURL string
+Insecure bool
+Compressor string
+Headers map[string]string
+Timeout time.Duration
+SampleRate float64
+Enable bool
+ResourceAttrs []attribute.KeyValue
+Validate() error
+Clone() *Config
}
class Manager {
+NewOTelManager(config *Config) (*Manager, error)
+Shutdown(ctx context.Context) error
+GetConfig() *Config
+GetResource() *resource.Resource
+IsTracingEnabled() bool
+IsLoggingEnabled() bool
+CreateTracer(name string) oteltrace.Tracer
+CreateLogger(name string) otellog.Logger
}
Config --> Manager : "配置"
```

**Diagram sources**
- [config.go](file://utility/otel/config.go#L1-L68)
- [manager.go](file://utility/otel/manager.go#L1-L258)

**Section sources**
- [config.go](file://utility/otel/config.go#L1-L68)
- [manager.go](file://utility/otel/manager.go#L1-L258)

### 初始化流程
系统启动时在`main.go`中调用`otel.InitWithConfig()`函数初始化OpenTelemetry。该函数创建`Manager`实例并配置追踪、日志和指标组件。

```mermaid
sequenceDiagram
participant Main as main.go
participant Otel as otel/utils.go
participant Manager as otel/manager.go
Main->>Otel : InitWithConfig(config)
Otel->>Manager : NewOTelManager(config)
Manager->>Manager : Validate配置
Manager->>Manager : 创建资源
Manager->>Manager : initTracing()
Manager->>Manager : initLogging()
Manager-->>Otel : 返回Manager
Otel-->>Main : nil
```

**Diagram sources**
- [main.go](file://main.go#L1-L50)
- [utils.go](file://utility/otel/utils.go#L22-L33)
- [manager.go](file://utility/otel/manager.go#L35-L86)

**Section sources**
- [main.go](file://main.go#L1-L50)
- [utils.go](file://utility/otel/utils.go#L1-L50)

## Casbin权限系统集成

Casbin权限系统基于RBAC模型实现，配置文件位于`resource/casbin/rbac_model.conf`。系统通过`g`规则定义角色继承关系，实现灵活的权限控制。

### RBAC模型配置
模型定义了请求、策略、角色和匹配器四个核心部分。请求定义为`sub, obj, act`三元组，策略定义了具体的权限规则，角色定义支持层级继承。

```mermaid
erDiagram
USER ||--o{ ROLE : "拥有"
ROLE ||--o{ POLICY : "关联"
USER {
string username
string role
}
ROLE {
string name
string parent
}
POLICY {
string subject
string object
string action
string effect
}
```

**Diagram sources**
- [rbac_model.conf](file://resource/casbin/rbac_model.conf#L1-L14)

**Section sources**
- [rbac_model.conf](file://resource/casbin/rbac_model.conf#L1-L14)

## 故障排除指南

### OpenTelemetry初始化失败
当OpenTelemetry初始化失败时，检查配置参数是否正确，特别是`ServiceName`和`CollectorURL`不能为空。确保网络连接正常，收集器服务可访问。

**Section sources**
- [config.go](file://utility/otel/config.go#L40-L52)
- [manager.go](file://utility/otel/manager.go#L50-L55)

### 电商平台API调用失败
检查API客户端配置是否正确，验证认证信息和端点URL。查看日志中的详细错误信息，确认网络连接和防火墙设置。

**Section sources**
- [api.go](file://utility/integration/redeem/jd/api.go#L1-L5)
- [api.go](file://utility/integration/tmall/api/api.go#L1-L20)

### 权限验证失败
确认用户角色分配正确，检查`sys_casbin_rule`表中的策略规则。验证请求的`sub, obj, act`三元组是否与策略匹配。

**Section sources**
- [rbac_model.conf](file://resource/casbin/rbac_model.conf#L1-L14)

### 京东订单复用问题
当京东订单无法复用时，检查以下条件：
1. 订单金额和商品品类是否匹配
2. 京东订单状态是否为待支付
3. 订单是否已超过复用超时时间（15分钟）
4. 京东订单是否已关联其他订单

**Section sources**
- [order.go](file://internal/logic/jd_cookie/order.go#L500-L550)
- [consts.go](file://internal/consts/jd_cookie.go#L150-L160)

## 结论
kami_backend的外部集成设计遵循模块化和可扩展原则，通过清晰的包结构和接口定义实现了与多个第三方服务的无缝集成。OpenTelemetry提供了全面的可观测性支持，Casbin实现了灵活的权限控制，为系统的稳定运行和安全管理提供了坚实基础。新增的京东订单复用功能优化了订单创建流程，提高了系统资源利用率。