Class: JPSClient::ModularClient

Inherits:
Object
  • Object
show all
Defined in:
lib/jpsclient/api/modular_client.rb

Overview

模块化Client - 支持按需加载指定的API模块组

Constant Summary collapse

MODULE_GROUPS =

模块分组定义

{
  # 核心模块 - 项目和文件管理
  core: %w[project project_package file cert],

  # 应用管理相关
  application: %w[application application_category application_version application_design
                  application_income application_sales],

  # 资源管理相关
  resource: %w[app_resource app_resource_version app_level assets_category
               resource_category collection],

  # Bug和工作流
  workflow: %w[bug workflow commit_log],

  # 用户和权限
  user: %w[user role login],

  # Lark集成
  lark: %w[lark_task lark_task_list lark_task_section lark_user
           lark_wiki_node lark_wiki_space lark_chat_group lark_comment lark_bitable],

  # 创意和设计
  creative: %w[creative idea sketch sketch_category experience experience_category],

  # 发布商相关
  publisher: %w[publisher publisher_category publisher_group publisher_group_category],

  # 需求和调研
  requirements: %w[requirements requirements_category survey survey_category],

  # 工具和实用
  utility: %w[tool tool_category util simple_search menu tag],

  # 统计和分析
  analytics: %w[statistics trending sov],

  # 媒体相关
  media: %w[video_cover icon_and_snapshot m3u8 document_text],

  # 其他
  misc: %w[store webhook healthy custom_application custom_application_web
           apple_account ud_id jssdk fgui_export game_assets collect]
}.freeze

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(config_file:, load_groups: [:core]) ⇒ ModularClient

Returns a new instance of ModularClient.



63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
# File 'lib/jpsclient/api/modular_client.rb', line 63

def initialize(config_file:, load_groups: [:core])
  begin
    @config_file = config_file
    @loaded_groups = []
    @loaded_modules = []

    raise ExceptionError, "必须提供配置文件路径" unless @config_file
    raise ExceptionError, "配置文件不存在: #{@config_file}" unless File.exist?(@config_file)

    @config_json = JSON.parse(File.read(@config_file))
    @baseurl = @config_json["pgyerapps_base_url"]
    @request_config = @config_json["api_path_config"]

    # 初始化API配置管理器
    @api_config = ApiConfig.new(@config_json)

    # 从 auth_config 获取配置
    auth_config = @config_json["auth_config"]
    @pgyer_aes_key = auth_config["aes_key"]

    # 加载 JPS 登录配置
    @jps_config = LoginConfig.from_json(auth_config)

    # 初始化 token 管理器
    @token_manager = Token.new(@jps_config)

    # 尝试加载已保存的 token
    if @token_manager.load && @token_manager.loaded?
      @token = @token_manager.to_h
    end

    # 初始化共享的 HTTP 客户端
    @http_client = HttpClient.new(base_url: @baseurl)
    @http_client.update_token(@token["token"]) if @token && @token["token"]

    # 加载指定的模块组
    Array(load_groups).each { |group| load_group(group) }

  rescue JSON::ParserError => error
    raise ExceptionError.new("配置文件格式错误 (#{@config_file}): #{error.message}")
  rescue ExceptionError
    raise  # 重新抛出 JPS 异常
  rescue => error
    raise ExceptionError.new("加载配置文件失败 (#{@config_file}): #{error.message}")
  end
end

Instance Attribute Details

#api_configObject

Returns the value of attribute api_config.



60
61
62
# File 'lib/jpsclient/api/modular_client.rb', line 60

def api_config
  @api_config
end

#baseurlObject

Returns the value of attribute baseurl.



60
61
62
# File 'lib/jpsclient/api/modular_client.rb', line 60

def baseurl
  @baseurl
end

#config_fileObject (readonly)

Returns the value of attribute config_file.



61
62
63
# File 'lib/jpsclient/api/modular_client.rb', line 61

def config_file
  @config_file
end

#config_jsonObject (readonly)

Returns the value of attribute config_json.



61
62
63
# File 'lib/jpsclient/api/modular_client.rb', line 61

def config_json
  @config_json
end

#http_clientObject

Returns the value of attribute http_client.



60
61
62
# File 'lib/jpsclient/api/modular_client.rb', line 60

def http_client
  @http_client
end

#loaded_groupsObject (readonly)

Returns the value of attribute loaded_groups.



61
62
63
# File 'lib/jpsclient/api/modular_client.rb', line 61

def loaded_groups
  @loaded_groups
end

#loaded_modulesObject (readonly)

Returns the value of attribute loaded_modules.



61
62
63
# File 'lib/jpsclient/api/modular_client.rb', line 61

def loaded_modules
  @loaded_modules
end

#request_configObject

Returns the value of attribute request_config.



60
61
62
# File 'lib/jpsclient/api/modular_client.rb', line 60

def request_config
  @request_config
end

#tokenObject

Returns the value of attribute token.



60
61
62
# File 'lib/jpsclient/api/modular_client.rb', line 60

def token
  @token
end

Instance Method Details

#do_login(force_login: false) ⇒ Object

核心登录功能token 有效性由服务端 401 响应判断,本地不做过期检查



175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
# File 'lib/jpsclient/api/modular_client.rb', line 175

def (force_login: false)
  if 
    @token_manager.clear
  else
    # 本地存在 token,直接使用
    if @token_manager.load && @token_manager.loaded?
      update_token_everywhere
      return true
    end
  end

  # 需要重新登录
  auth = Auth.new(@jps_config)
  result = auth.

  if result == :user_cancelled
    Logger.instance.fancyinfo_error("用户取消了登录操作")
    return false
  elsif result == true
    unless @token_manager.save(auth.get_token_data)
      Logger.instance.fancyinfo_error("Token 保存失败,下次启动需要重新登录")
    end
    update_token_everywhere
    return true
  else
    Logger.instance.fancyinfo_error("登录失败,未能获取有效token")
    return false
  end
end

#load_group(group_name) ⇒ Object

加载指定的模块组



111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
# File 'lib/jpsclient/api/modular_client.rb', line 111

def load_group(group_name)
  group_name = group_name.to_sym
  return if @loaded_groups.include?(group_name)

  modules = MODULE_GROUPS[group_name]
  unless modules
    puts "警告: 未知的模块组 '#{group_name}'"
    puts "可用的模块组: #{MODULE_GROUPS.keys.join(', ')}"
    return
  end

  modules.each do |module_name|
    load_module(module_name)
  end

  @loaded_groups << group_name
  puts "已加载模块组: #{group_name} (#{modules.size}个模块)"
end

#load_module(module_name) ⇒ Object

加载单个模块



131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
# File 'lib/jpsclient/api/modular_client.rb', line 131

def load_module(module_name)
  return if @loaded_modules.include?(module_name)

  begin
    require "jpsclient/api/#{module_name}"

    # 将模块名转换为类名
    class_name = module_name.split('_').map(&:capitalize).join

    # Include模块
    if API.const_defined?(class_name)
      self.class.send(:include, API.const_get(class_name))
      @loaded_modules << module_name
    end
  rescue LoadError => e
    puts "警告: 无法加载模块 #{module_name}: #{e.message}"
  end
end

打印加载状态



156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
# File 'lib/jpsclient/api/modular_client.rb', line 156

def print_status
  puts "=" * 60
  puts "ModularClient 加载状态"
  puts "=" * 60
  puts "已加载的模块组: #{@loaded_groups.join(', ')}"
  puts "已加载的模块数: #{@loaded_modules.size}"
  puts "可用的方法示例:"

  # 显示一些可用的方法
  sample_methods = self.methods(false).select { |m|
    m.to_s.start_with?('get_', 'create_', 'update_', 'delete_')
  }.first(10)

  sample_methods.each { |m| puts "  - #{m}" }
  puts "  ..." if self.methods(false).size > 10
end

#request_with_auth(method, path, **opts) ⇒ Object

带 401 重试的统一请求方法



206
207
208
209
210
211
212
213
214
215
216
217
218
# File 'lib/jpsclient/api/modular_client.rb', line 206

def request_with_auth(method, path, **opts)
  response = @http_client.send(method, path, **opts)
  result = JPSClient::Response.new(response)

  if result.need_login?
    if (force_login: true)
      response = @http_client.send(method, path, **opts)
      result = JPSClient::Response.new(response)
    end
  end

  result.to_h
end

#shared_http_clientObject

提供共享的HTTP客户端给其他模块



151
152
153
# File 'lib/jpsclient/api/modular_client.rb', line 151

def shared_http_client
  @http_client
end