lib/xadmin/view.ex

defmodule Xmeta.Xadmin.View do
  defmacro __using__(opts) do
    unless opts[:title], do: raise("plaease set :title in  Module: #{__MODULE__}")

    quote bind_quoted: [opts: opts] do
      Xmeta.Amis.Env.put_module(__MODULE__, :xadmin_api)

      if opts[:schema] do
        use Params.Schema, Xmeta.Xadmin.View.make_schema(opts[:schema])
      end

      @config opts
      
      def schema(ctx, params) do
        %{}
      end

      def call(conn, params) do
        ctx = %{conn: conn}
        schema(ctx, params)
      end

      def config, do: @config
      defp get_schema, do: @config[:schema]

      def get_middleware() do
        config = config()
        middleware = config[:middleware]
        if middleware, do: middleware, else: []
      end

      defoverridable schema: 2, call: 2, valid_schema: 2,get_middleware: 0
    end
  end

  def make_schema(schema) do
    Enum.reduce(Map.to_list(schema), %{}, fn(x,acc) -> 
      {key,data} = x
      if is_atom(data) do
        put_in(acc,[key],data)
      else
        data = for x <- data, check_key?(x), do: x
        put_in(acc,[key],data)
      end
    end)
  end

  defp check_key?(c) do
    {key,_} = c
    if key in [:name,:des] do
      false
    else
      true
    end
  end

  def check_middleware(ctx, params, module) do
    mids = get_module_middleware(module)
    Enum.reduce(mids,%{status: 0, data: [], msg: ""}, fn(m,acc) -> 
      if acc[:status] != 0 do
        acc
      else
        m.call(ctx,params)
      end
    end)
  end

  defp get_module_middleware(module) do
    slist = Module.split(module)
    site_mod = get_module_root(slist,1)
    router_mod = get_module_root(slist,2)
    site_mod.get_middleware() ++ router_mod.get_middleware() ++ module.get_middleware()
  end

  defp get_module_root(slist, num) do
    new_slist = for x <- 0..num do
      Enum.at(slist,x)
    end
    Module.concat(new_slist)
  end
end