lib/xapi/docs/amis.ex

defmodule Xmeta.Xapi.Docs.Amis do
  alias Xmeta.Xapi.Docs

  def amisJSON() do
    # docs_name = Mix.Project.config()[:name] || Mix.Project.config()[:app] |> Atom.to_string()
    host_info = Xmeta.Xapi.Docs.get_host_info()
    %{
      type: "app",
      title: "Xmeta Api",
      brandName: "Xmeta Api",
      header: %{
        type: "tpl",
        inline: false,
        className: "w-full",
        tpl: """
        <div class="flex justify-between"><div>接口文档</div><div>顶部区域右侧</div></div>
        """
      },
      # asideBefore: '<div class="p-2 text-center">菜单前面区域</div>',
      # asideAfter: '<div class="p-2 text-center">菜单后面区域</div>',
      footer: """
      <div class="flex justify-between"><div></div>Atuple Xmeta</div>
      """,
      pages: [
        %{
          label: "系统信息",
          children:
            [
              %{
                label: "应用信息",
                url: "/",
                schema: %{
                  type: "page",
                  body: [
                    %{
                      type: "markdown",
                      value: """
                      ## 系统信息
                        ```
                        名称:   #{host_info.name}
                        标识:   #{host_info.app}
                        版本:   #{host_info.verison}
                        类型:   #{host_info.type}
                        地址:   #{host_info.host}
                        环境:   #{host_info.env}
                        ```
                      """
                    }
                  ]
                }
              }
            ] ++ site_data()
        }
      ]
    }
    |> Jason.encode!()
  end

  defp get_view_module_url(view_module) do
    path = Enum.reduce(Module.split(view_module),"",fn x,acc ->
      if x == "Elixir" || x == "Xapi" do
        acc
      else
        {first,last} = String.next_grapheme(x)  
        acc <> "/" <> String.downcase(first) <> last  
      end
    end)
    "/api" <> path
  end

  def site_data() do
    site_module = Docs.get_site_module()
    site_module = site_module ++ Docs.get_xmeta_env_module(:site)
    site_module = Enum.uniq(site_module)
    for site <- site_module do
      %{
        label: site.config()[:title],
        url: "/#{site}",
        children: get_site_router(site)
      }
    end
  end

  def get_site_router(site_module) do
    router_modules = Docs.find_child_module(site_module)
    env_modules = Docs.filter_modules(site_module,Docs.get_xmeta_env_module(:router))
    router_modules = router_modules ++ env_modules
    router_modules = Enum.uniq(router_modules)
    site_module_name = to_string(site_module)
    for r <- router_modules do
      r_name = to_string(r)

      %{
        label: r.config()[:title],
        url: "/#{site_module_name}/#{r_name}",
        schemaApi: "/api/docs/router/#{r_name}/json"
      }
    end
  end

  def get_router_view(router_module) do
    view_modules = Docs.find_child_module(router_module)
    env_modules = Docs.filter_modules(router_module,Docs.get_xmeta_env_module(:api))
    view_modules = view_modules ++ env_modules
    view_modules = Enum.uniq(view_modules)
    # router_module_name = to_string(router_module)
    view_data =
      for view <- view_modules do
        %{
          title: view.config()[:title],
          url: get_view_module_url(view),
          view_name: "#{view}"
        }
      end

    %{
        type: "page",
        body: [
          %{
            type: "table",
            columns: [
              %{
                name: "title",
                label: "接口名",
                type: "text"
              },
              %{
                name: "url",
                label: "接口地址",
                type: "text"
              },
              %{
                name: "type",
                label: "复制",
                type: "button",
                size: "sm",
                level: "primary",
                actionType: "copy",
                copyFormat: "text/html",
                content: "${url}"
              }
            ],
            data: %{
              items: view_data
            },
            itemAction: %{
              type: "button",
              actionType: "dialog",
              dialog: %{
                title: "",
                size: "md",
                actions: [],
                closeOnEsc: true,
                body: %{
                  type: "service",
                  schemaApi: "/api/docs/view/${view_name}/json"
                }
              }
            }
          }
        ]
      }
  end

  def get_view(view_module) do
    view_module_name = view_module |> to_string |> String.replace("Elixir.","")
    %{
      type: "service",
      data: %{
        table: [
          %{table_name: "url:", table_value: get_view_module_url(view_module)},
          %{table_name: "节点名:", table_value: Node.self()},
          %{table_name: "模块名:", table_value: view_module_name},
        ],
        form: format_schema(view_module.config()[:schema])
        # %{table_name: "函数名:", table_value: "sdfsdf"},
      },
      body: [
        %{
          type: "page",
          body: [
            %{
              type: "grid",
              columns: [
                %{
                  md: 10,
                  body: view_module.config()[:title]
                },
                %{
                  md: 2,
                  body: [
                    %{
                      name: "type",
                      label: "复制",
                      type: "button",
                      size: "sm",
                      level: "primary",
                      actionType: "copy",
                      copyFormat: "text/html",
                      content: get_view_module_url(view_module)
                    }
                  ]
                }
              ]
            }
          ]
        },
        %{
          type: "table",
          source: "$table",
          columns: [
            %{
              name: "table_name",
            },
            %{
              name: "table_value",
            }
          ]
        },
        %{
          type: "markdown",
          value: """
          ```
          #{view_module.config()[:des] || ""}
          ```
          """
        },
        %{
          type: "table",
          source: "$form",
          title: "表单",
          columns: [
            %{
              name: "name",
              label: "名称"
            },
            %{
              name: "key",
              label: "键值"
            },
            %{
              name: "type",
              label: "类型"
            },
            %{
              name: "required",
              label: "必填"
            },
            %{
              name: "des",
              label: "说明"
            },
          ]
        },
      ]
    }
  end

  def format_schema(schema) when is_map(schema) do
    for x <- Map.to_list(schema) do
      {key, data} = x
      key = Atom.to_string(key)
      required = if String.contains?(key,"!"), do: true, else: false
      key = if String.contains?(key,"!") do
        String.replace(key,"!", "")
      else
        key
      end
      data = if is_atom(data), do: [field: data], else: data
      
      %{
        key: key,
        name: data[:name] || key,
        type: data[:field],
        required: required,
        des: data[:des]
      }
    end
  end

  def format_schema(schema) when is_nil(schema) do
    []
  end
end