package upstreamimpl import ( "context" "fmt" "git.5iot.com/iotlcm-public/iotlcm-upstream-proxy/internal/model" "git.5iot.com/iotlcm-public/iotlcm-upstream-proxy/internal/service" "sync/atomic" "time" "github.com/gogf/gf/v2/errors/gerror" "github.com/gogf/gf/v2/frame/g" "github.com/gogf/gf/v2/net/gsvc" "golang.org/x/sync/singleflight" ) const ( gUrlBase = "https://api.iot.10086.cn/v5/" ) type sSimYD struct { channelConfig *model.SimChannelConfigItemCache seqId atomic.Int64 tokenFlight singleflight.Group } func NewSimYD() *sSimYD { return &sSimYD{} } func init() { s := NewSimYD() service.UpstreamAPI().RegisterTemp("sim_yd_v5", s) service.UpstreamAPI().RegisterTemp("sim_yd_mock_v5", s) // These channel implementations live in the upstream gateway. The proxy // forwards their API calls through the same generic gateway route, so any // template registered in iotlcm-upstream-chan must be registered here too: // channel refresh fails with "channel template not registered" otherwise. // sSimYD has no template-specific logic, so an alias per template suffices. service.UpstreamAPI().RegisterTemp("sim_sdtywl_v1", s) service.UpstreamAPI().RegisterTemp("sim_onelink_tengyu_v1", s) service.UpstreamAPI().RegisterTemp("sim_onelink_xuzhou_mobile_v1", s) service.UpstreamAPI().RegisterTemp("sim_onelink_lelian_v1", s) service.UpstreamAPI().RegisterTemp("sim_onelink_qianxun_v1", s) service.UpstreamAPI().RegisterTemp("sim_onelink_henan_xinjing_v1", s) service.UpstreamAPI().RegisterTemp("sim_henan_xinjing_direct_v1", s) service.UpstreamAPI().RegisterTemp("sim_onelink_zibo_v1", s) service.UpstreamAPI().RegisterTemp("sim_tibiot_v1", s) service.UpstreamAPI().RegisterTemp("sim_qianxun_v3", s) service.UpstreamAPI().RegisterTemp("sim_yunda_v1", s) service.UpstreamAPI().RegisterTemp("sim_mingqian_v3", s) service.UpstreamAPI().RegisterTemp("sim_daihe_v1", s) service.UpstreamAPI().RegisterTemp("sim_onelink_daihe_v1", s) service.UpstreamAPI().RegisterTemp("sim_onelink_daliuliang_v1", s) service.UpstreamAPI().RegisterTemp("sim__daliuliang_v1", s) service.UpstreamAPI().RegisterTemp("sim_onelink_mobile_public_v1", s) service.UpstreamAPI().RegisterTemp("sim_onelink_kedang_v1", s) service.UpstreamAPI().RegisterTemp("lanshang_8003", s) service.UpstreamAPI().RegisterTemp("lanshang_8000", s) service.UpstreamAPI().RegisterTemp("sim_onelink_yunze_v1", s) // 江苏倍信(jsbxkj)共享 Token。协议实现在 chan 的 beixin_token_provider.go; // proxy 只负责把业务 API 转发到 gateway,与腾宇/澜数同一形态。 service.UpstreamAPI().RegisterTemp("sim_onelink_beixin_v1", s) service.UpstreamAPI().RegisterTemp("sim_onelink_lanshu_v1", s) service.RegisterSimYD(s) } func (s *sSimYD) NewTemp(ctx context.Context, channelConfig *model.SimChannelConfigItemCache) model.SimCardChannelI { return &sSimYD{ channelConfig: channelConfig, } } func (s *sSimYD) getUpstreamUrl(ctx context.Context, serviceUrl string) string { address, _ := g.Cfg().Get(ctx, "gateway.address") return fmt.Sprintf("http://%s%s", address, serviceUrl) // return fmt.Sprintf("http://%s%s", "127.0.0.1:8110", serviceUrl) } func (s *sSimYD) getUpstreamTimeout(ctx context.Context) time.Duration { timeout, _ := g.Cfg().Get(ctx, "gateway.timeout") if timeout == nil { return 10 * time.Second } if d := timeout.Duration(); d > 0 { return d } if seconds := timeout.Int(); seconds > 0 { return time.Duration(seconds) * time.Second } return 10 * time.Second } func (s *sSimYD) SimBase(ctx context.Context, input *model.SimBaseReqJson) (model.SimBaseResJson, error) { r := g.RequestFromCtx(ctx) if r.Method != "POST" { g.Log().Errorf(ctx, "SimYD.SimBase, method not allowed, method %s, input %+v", r.Method, input) return nil, gerror.New("方法调用错误") } path := r.URL.Path if path == "" { g.Log().Errorf(ctx, "SimYD.SimBase, path is required, input %+v", input) return nil, gerror.New("路径不能为空") } url := s.getUpstreamUrl(ctx, path) g.Log().Debugf(ctx, "SimYD.SimBase, url %s", url) client := g.Client() client.SetDiscovery(gsvc.GetRegistry()) client.SetTimeout(s.getUpstreamTimeout(ctx) * time.Duration(len(input.SimKeys))) resp, err := client.Post(ctx, url, input) if err != nil { g.Log().Errorf(ctx, "SimYD.SimBase, post error %+v,url %s, params %+v, ", err, url, input) return nil, gerror.New("请求失败") } return readGatewayResponse(resp) }