121 lines
2.9 KiB
Go
Executable File
121 lines
2.9 KiB
Go
Executable File
// Package upstream 上游对接方管理:多商户(易支付 pid+key)独立加密存储
|
|
//
|
|
// UpstreamPool 是各模块获取上游数据的唯一入口:
|
|
// - epay 协议层(main.go 验签):按 pid 查对应密钥
|
|
// - order.Service:下单记录 pid/upstream_name;回调签名按订单 pid 取密钥
|
|
// - Admin API:增删改查后同步到 pool
|
|
//
|
|
// 设计约束:
|
|
// - 不直接访问 upstreams.db(仅 Admin API 有权限)
|
|
// - 所有密钥在内存中解密,不落盘
|
|
package upstream
|
|
|
|
import (
|
|
"sync"
|
|
)
|
|
|
|
// UpstreamPool 内存上游池(线程安全)
|
|
// 负责:pid → Upstream 索引(验签/签名路由)
|
|
type UpstreamPool struct {
|
|
mu sync.RWMutex
|
|
byID map[int64]*Upstream // id → Upstream
|
|
byPid map[string]*Upstream // pid → Upstream(易支付验签/签名路由)
|
|
}
|
|
|
|
// NewPool 创建空上游池
|
|
func NewPool() *UpstreamPool {
|
|
return &UpstreamPool{
|
|
byID: make(map[int64]*Upstream),
|
|
byPid: make(map[string]*Upstream),
|
|
}
|
|
}
|
|
|
|
// ---------- 管理接口(仅 Admin API 调用)----------
|
|
|
|
// Add 添加上游到池中(Admin API 解密后调用)
|
|
func (p *UpstreamPool) Add(u *Upstream) {
|
|
p.mu.Lock()
|
|
defer p.mu.Unlock()
|
|
p.byID[u.ID] = u
|
|
if u.Pid != "" {
|
|
p.byPid[u.Pid] = u
|
|
}
|
|
}
|
|
|
|
// Update 更新池中上游(pid 变更时重建索引)
|
|
func (p *UpstreamPool) Update(u *Upstream) {
|
|
p.mu.Lock()
|
|
defer p.mu.Unlock()
|
|
if old, ok := p.byID[u.ID]; ok {
|
|
if old.Pid != "" && old.Pid != u.Pid {
|
|
delete(p.byPid, old.Pid)
|
|
}
|
|
}
|
|
p.byID[u.ID] = u
|
|
if u.Pid != "" {
|
|
p.byPid[u.Pid] = u
|
|
}
|
|
}
|
|
|
|
// Remove 从池中移除上游
|
|
func (p *UpstreamPool) Remove(id int64) {
|
|
p.mu.Lock()
|
|
defer p.mu.Unlock()
|
|
if old, ok := p.byID[id]; ok {
|
|
if old.Pid != "" {
|
|
delete(p.byPid, old.Pid)
|
|
}
|
|
delete(p.byID, id)
|
|
}
|
|
}
|
|
|
|
// SetStatus 设置上游状态
|
|
func (p *UpstreamPool) SetStatus(id int64, status UpstreamStatus) {
|
|
p.mu.Lock()
|
|
defer p.mu.Unlock()
|
|
if u, ok := p.byID[id]; ok {
|
|
u.Status = status
|
|
}
|
|
}
|
|
|
|
// ---------- 查询接口(业务模块使用)----------
|
|
|
|
// ByPid 按易支付商户ID查找上游(验签/签名路由)
|
|
// 返回 nil 表示该 pid 未登记
|
|
func (p *UpstreamPool) ByPid(pid string) *Upstream {
|
|
p.mu.RLock()
|
|
defer p.mu.RUnlock()
|
|
return p.byPid[pid]
|
|
}
|
|
|
|
// ByID 按 ID 查找上游
|
|
func (p *UpstreamPool) ByID(id int64) *Upstream {
|
|
p.mu.RLock()
|
|
defer p.mu.RUnlock()
|
|
return p.byID[id]
|
|
}
|
|
|
|
// All 返回全部上游(按 ID 排序,Admin 列表用)
|
|
func (p *UpstreamPool) All() []*Upstream {
|
|
p.mu.RLock()
|
|
defer p.mu.RUnlock()
|
|
out := make([]*Upstream, 0, len(p.byID))
|
|
for _, u := range p.byID {
|
|
out = append(out, u)
|
|
}
|
|
// 按 ID 升序
|
|
for i := 1; i < len(out); i++ {
|
|
for j := i; j > 0 && out[j].ID < out[j-1].ID; j-- {
|
|
out[j], out[j-1] = out[j-1], out[j]
|
|
}
|
|
}
|
|
return out
|
|
}
|
|
|
|
// Count 上游总数
|
|
func (p *UpstreamPool) Count() int {
|
|
p.mu.RLock()
|
|
defer p.mu.RUnlock()
|
|
return len(p.byID)
|
|
}
|