" module BaseModelConcern\n extend ActiveSupport::Concern\n\n def self.get_model(model_name)\n ActiveSupport::Dependencies.constantize(model_name.classify)\n end\n\n def self.params_blank?(params)\n !params.select {|_k, v| v.blank?}.empty?\n end\n\n module ClassMethods\n def get_model(model_name)\n ActiveSupport::Dependencies.constantize(model_name.classify)\n end\n\n def permit_params\n name = self.model_name.singular\n p = \"(\"\n self.columns.each {|c|\n if (c.name != 'id')\n p += \":\#{'\#{c.name}'},\"\n end}\n p += \")\"\n puts p\n return \"ok\"\n end\n\n def api_params\n name = self.model_name.singular\n self.columns.each {|c| puts \"param :\#{'\#{' \"' + name + '[' + c.name + ']\" ' }'},String,desc: '\#{'\#{c.comment}'}' \"}\n return \"ok\"\n end\n\n # \u83B7\u53D6\u5B57\u6BB5\u7684\u5907\u6CE8\u4FE1\u606F\n # \u4F7F\u7528 User.column_comments => hash\n def column_comments\n column_comments = self.connection.retrieve_column_comments(self.table_name)\n column_comments\n end\n\n # \u4F7F\u7528 User.column_comment('username') => '\u7528\u6237\u540D'\n def column_comment(column_name)\n column_name = column_name.to_s\n return '' unless self.column_names.include?(column_name)\n\n column_comments = self.connection.retrieve_column_comments(self.table_name)\n comment = column_comments[column_name.to_sym]\n comment\n end\n\n # \u8F85\u52A9\u65B9\u6CD5 \u5C06\u4F20\u9012\u8FDB\u6765\u7684true false \u8F6C\u6362\u4E3A \u662F \u5426\n def true_change(value = '')\n temp_value = value\n case value\n when true, 'true'\n temp_value = '\u662F'\n when false, 'false'\n temp_value = '\u5426'\n when 'un_pass'\n temp_value = '\u4E0D\u901A\u8FC7'\n when 'pass'\n temp_value = '\u901A\u8FC7'\n when 'success'\n temp_value = '\u6210\u529F'\n when 'fail'\n temp_value = '\u5931\u8D25'\n when 'change'\n temp_value = '\u8BFE\u7A0B\u786E\u8BA4'\n when 'modify'\n temp_value = '\u672A\u901A\u8FC7'\n when 'file'\n temp_value = '\u5931\u8D25\uFF0C\u9700\u8865\u6750\u6599'\n when 'internet'\n temp_value = '\u5728\u7EBF\u7533\u8BF7'\n when 'paper'\n temp_value = '\u90AE\u4EF6\u7533\u8BF7'\n when 'other'\n temp_value = '\u7EBF\u4E0B\u652F\u4ED8'\n when 'liuyangbao'\n temp_value = '\u7559\u6D0B\u5B9D\u652F\u4ED8'\n when 'provide_credit_card'\n temp_value = '\u63D0\u4F9B\u4FE1\u7528\u5361\u4FE1\u606F'\n when 'provided', 'provided_cer'\n temp_value = '\u5DF2\u63D0\u4F9B'\n when 'un_provided'\n temp_value = '\u672A\u63D0\u4F9B'\n when '\u662F'\n temp_value = true\n when '\u5426'\n temp_value = false\n when 'institutional_feedback'\n temp_value = '\u9662\u6821\u53CD\u9988'\n when 'refusal'\n temp_value = '\u9662\u6821\u62D2\u5F55\u53D6'\n when 'offer'\n temp_value = '\u6210\u529F'\n when 'success_enter'\n temp_value = '\u4ED8\u8D39\u6CE8\u518C\u65E0\u6761\u4EF6'\n when 'fail_enter'\n temp_value = '\u4ED8\u8D39\u6CE8\u518C\u6709\u6761\u4EF6'\n end\n\n temp_value\n end\n\n # \u83B7\u53D6\u4E03\u725B\u4E0A\u4F20\u6587\u4EF6\u7684\u51ED\u8BC1\n def get_upload_token\n put_policy = Qiniu::Auth::PutPolicy.new(\n CarrierwaveSetting.qiniu.bucket, # \u5B58\u50A8\u7A7A\u95F4\n nil, # \u6700\u7EC8\u8D44\u6E90\u540D\uFF0C\u53EF\u7701\u7565\uFF0C\u5373\u7F3A\u7701\u4E3A\u201C\u521B\u5EFA\u201D\u8BED\u4E49\n 1800, # \u76F8\u5BF9\u6709\u6548\u671F\uFF0C\u53EF\u7701\u7565\uFF0C\u7F3A\u7701\u4E3A3600\u79D2\u540E uptoken \u8FC7\u671F\n (Time.now + 30.minutes).to_i # \u7EDD\u5BF9\u6709\u6548\u671F\uFF0C\u53EF\u7701\u7565\uFF0C\u6307\u660E uptoken \u8FC7\u671F\u671F\u9650\uFF08\u7EDD\u5BF9\u503C\uFF09\uFF0C\u901A\u5E38\u7528\u4E8E\u8C03\u8BD5\uFF0C\u8FD9\u91CC\u8868\u793A\u534A\u5C0F\u65F6\n )\n\n uptoken = Qiniu::Auth.generate_uptoken(put_policy) #\u751F\u6210\u51ED\u8BC1\n bucket_domain = CarrierwaveSetting.qiniu.bucket_domain #\u5B58\u50A8\u7A7A\u95F4\u540D\n\n return uptoken, bucket_domain\n end\n\n def es_find_by_id(id)\n $elasticsearch_client.perform_request('GET', \"\#{'\#{self.name.underscore.pluralize}/\#{self.name}/\#{id}'}\")\n end\n\n\n def search_by_params(options = {})\n result = self.all\n if options.present?\n keys = options.keys\n keys.delete(:page)\n keys.delete(:per)\n keys.each do |key|\n value = options[key]\n next unless value.present? || !value.to_s.empty?\n if key == :order || key == 'order'\n if value.is_a?(Array)\n value.each do |v|\n orders = v.split(' ')\n result = if orders.length == 2\n result.order(\"\#{'\#{orders[0]}'} \#{'\#{orders[1].upcase}'}\")\n else\n result.order(value)\n end\n end\n else\n orders = value.split(' ')\n result = if orders.length == 2\n result.order(\"\#{'\#{orders[0]}'} \#{'\#{orders[1].upcase}'}\")\n else\n result.order(value)\n end\n end\n elsif key.to_s.include?('like_')\n query = ''\n query_value = {}\n attr_key = key.to_s.gsub('like_', '')\n if attr_key.include?('.')\n ref_table = attr_key.split('.')[0]\n ref_key = attr_key.split('.')[1]\n\n if value.is_a?(Array)\n value.each_with_index do |v, i|\n query += \"upper(\#{'\#{attr_key}'}) like :value\#{'\#{i}'} \"\n query += 'or ' if i != value.length - 1\n query_value.merge!({\"value\#{'\#{i}'}\": \"%\#{'\#{v.upcase}'}%\"})\n end\n result = result.where(query, query_value)\n else\n result = result.where(\"upper(\#{'\#{attr_key}'}) like ?\", \"%\#{'\#{value.upcase}'}%\")\n end\n else\n\n if value.is_a?(Array)\n value.each_with_index do |v, i|\n query += \"\#{'\#{self.name.tableize}'}.\#{'\#{attr_key}'} like :value\#{'\#{i}'} \"\n query += 'or ' if i != value.length - 1\n query_value.merge!({\"value\#{'\#{i}'}\": \"%\#{'\#{v.upcase}'}%\"})\n end\n result = result.where(query, query_value)\n else\n result = result.where(\"upper(\#{'\#{self.name.tableize}'}.\#{'\#{attr_key}'}) like ?\", \"%\#{'\#{value.upcase}'}%\") if self.attribute_names.include?(attr_key)\n end\n end\n\n # or || \u517C\u5BB9 'students.creator_id'\u7684\u60C5\u51B5\u53D1\u751F \u53EF\u80FD\u4F20\u9012\u591A\u4E2A\uFF0C\u8D85\u8FC7\u4E24\u4E2A\n elsif key.to_s =~ /^or_/\n attr_key = key.to_s.gsub('or_', '')\n values = value.split(' ')\n\n if attr_key.include?('.')\n search_key = \"\#{'\#{attr_key}'}\" if value.present?\n else\n search_key = \"\#{'\#{self.name.tableize}'}.\#{'\#{attr_key}'}\" if self.attribute_names.include?(attr_key) && value.present?\n end\n\n query_string = ''\n values.each_with_index do |v, i|\n query_string += \"\#{'\#{search_key}'} = '\#{'\#{values[i]}'}' or \"\n end\n query_string.chomp!(' or ')\n\n result = result.where(query_string)\n\n # or\u4E00\u4E2Avalue\u540C\u65F6\u641C\u591A\u4E2A\u53C2\u6570\n elsif key.to_s.include?('&or&')\n # \u8FD9\u8FB9\u7684\u9700\u6C42\u662F\u641C\u7D22\u5B66\u6821\u3001\u4EE3\u7406\u3001\u5B66\u751F\u7B49\u7684\u62FC\u97F3\u540D \u6240\u4EE5\u9700\u8981\u540C\u65F6\u641Cname\u548Cname_pinyin \u6682\u65F6\u9ED8\u8BA4\u662F\u76F4\u63A5\u9700\u8981like\u7684\n # \u683C\u5F0F: 'schools.name&or&schools.full_name'\n attr_keys = key.to_s.split('&or&')\n if value.present?\n # query_string = ''\n query_hash = {value: \"%\#{'\#{value.upcase}'}%\"}\n query_string = attr_keys.map.with_index do |attr_key, i|\n convert_key = if attr_key.include?('.')\n attr_key\n else\n \"\#{'\#{self.name.tableize}'}.\#{'\#{attr_key}'}\" if self.attribute_names.include?(attr_key)\n end\n convert_key_arr = convert_key.split('.')\n # \u7528self\u7684\u8BDD\u4F1A\u6709\u95EE\u9898\n key_type = convert_key_arr.first.classify.constantize.type_for_attribute(convert_key_arr.last).type.to_s.classify\n key_type == String.name ? \"upper(\#{'\#{convert_key}'}) like :value or \" : \"\#{'\#{convert_key}'} = :value or \"\n end.flatten.join[0..-5]\n result = result.where(query_string, query_hash)\n end\n elsif key.to_s =~ /^compare_/\n attr_key = key.to_s.gsub(/^compare_/, '')\n if value.present?\n query_hash = {}\n query_string = \"\"\n if attr_key =~ /^lt_/\n attr_key.gsub!(/^lt_/, '')\n convert_key = if attr_key.include?('.')\n attr_key\n else\n \"\#{'\#{self.name.tableize}'}.\#{'\#{attr_key}'}\" if self.attribute_names.include?(attr_key)\n end\n query_hash = {value: \"\#{'\#{value.to_d}'}\"}\n query_string = \"\#{'\#{convert_key}'} <= :value \"\n elsif attr_key =~ /^bt_/\n attr_key.gsub!(/^bt_/, '')\n convert_key = if attr_key.include?('.')\n attr_key\n else\n \"\#{'\#{self.name.tableize}'}.\#{'\#{attr_key}'}\" if self.attribute_names.include?(attr_key)\n end\n query_hash = {min: \"\#{'\#{value.split(' ')[0]}'}\", max: \"\#{'\#{value.split(' ')[1]}'}\"}\n query_string = \"\#{'\#{convert_key}'} >= :min and \#{'\#{convert_key}'} <= :max \"\n elsif attr_key =~ /^gt_/\n attr_key.gsub!(/^gt_/, '')\n convert_key = if attr_key.include?('.')\n attr_key\n else\n \"\#{'\#{self.name.tableize}'}.\#{'\#{attr_key}'}\" if self.attribute_names.include?(attr_key)\n end\n query_hash = {value: \"\#{'\#{value.to_d}'}\"}\n query_string = \"\#{'\#{convert_key}'} >= :value \"\n end\n result = result.where(query_string, query_hash)\n end\n #between\n elsif key.to_s.include?('between_')\n attr_key = key.to_s.gsub('between_', '')\n front, back = value.split(',')\n if attr_key.include?('.')\n result = result.between_fields(\"\#{'\#{attr_key}'}\", front, back) if value.present? && value.split(',').length == 2\n else\n puts \"betewwen \#{'\#{front}'} \#{'\#{back}'}\"\n result = result.between_fields(\"\#{'\#{self.name.tableize}'}.\#{'\#{attr_key}'}\", front, back) if self.attribute_names.include?(attr_key) && value.present? && value.split(',').length == 2\n end\n elsif key.to_s.include?('array_column_')\n attr_key = key.to_s.gsub('array_column_', '')\n result = result.where(\"\#{'\#{attr_key}'} && ARRAY[?]::varchar[]\", value)\n elsif key.to_s.include?('not_')\n attr_key = key.to_s.gsub('not_', '')\n result = result.where.not(\"\#{'\#{attr_key}'} = ?\", \"\#{'\#{value}'}\")\n else\n key = key.to_s.remove('between_').remove('like_').remove('not_')\n if key.include?('.')\n result = result.where(key.to_sym => value)\n else\n result = result.where(\"\#{'\#{self.name.tableize}'}.\#{'\#{key}'}\".to_sym => value) if self.attribute_names.include?(key)\n end\n end\n end\n end\n result\n end\n\n def resources_search_by_params(resources, options = {})\n result = resources\n if options.present?\n keys = options.keys\n keys.delete(:page)\n keys.delete(:per)\n keys.each do |key|\n value = options[key]\n next unless value.present? || !value.to_s.empty?\n if key == :order || key == 'order'\n orders = value.split(' ')\n\n result = if orders.length == 2\n result.order(orders[0].to_sym => orders[1].to_sym)\n else\n result.order(value)\n end\n else\n result = result.where(key.to_sym => value) if result.model.instance_methods.include?(key) || result.model.attribute_names.include?(key.to_s)\n if key.to_s.include?('like_')\n attr_key = key.to_s.gsub('like_', '')\n if attr_key.include?('.')\n result = result.where(\"\#{'\#{attr_key}'} like ?\", \"%\#{'\#{value}'}%\")\n else\n result = result.where(\"\#{'\#{result.model.name.tableize}'}.\#{'\#{attr_key}'} like ?\", \"%\#{'\#{value}'}%\") if result.model.attribute_names.include?(attr_key)\n end\n end\n end\n end\n end\n result\n end\n\n def search_by_hash(args, result_objects = nil)\n result = result_objects.present? ? result_objects : self.all\n\n if args.present?\n args.each_key do |key|\n value = args[key]\n\n next unless value.present? || !value.to_s.empty?\n\n result = result.where(\"\#{'\#{self.name.tableize}'}.\#{'\#{key}'} like ?\", \"%\#{'\#{args[key]}'}%\") if self.attribute_names.include?(key)\n end\n end\n\n result\n end\n\n def validate_present?(params)\n params.select(&:present?).empty?\n end\n\n def validate_blank?(params)\n return true if params.blank?\n !params.select(&:blank?).empty?\n end\n\n def validate_all_present?(*args)\n args.select(&:blank?).empty?\n end\n\n def validate_all_blank?(*args)\n return true if args.blank?\n args.select(&:present?).empty?\n end\n\n def exist_resource(resource_id)\n return nil if resource_id.blank?\n\n self.find_by_id(resource_id)\n end\n\n # \u4E3A\u7B80\u5355\u7684\u5BF9\u8C61\u4FDD\u5B58\u8BB0\u5F55\n # \u4F5C\u8005 liangyuzhe 20161225\n def save_values_for_object(options)\n record = nil\n response = Response.rescue do |_res|\n column_sym = (self.columns.map(&:name) - %w(id deleted_at created_at updated_at)).map(&:to_sym)\n hash = {}\n column_sym.each do |c|\n hash.merge!(c => options[c])\n end\n record = self.create!(hash)\n end\n [response, record]\n end\n\n # postgresql\u67E5\u8BE2jsonb\u6570\u636E\u65B9\u6CD5\n # params white_list String Array\n # params params ActionController::Parameters\n # params jsonb_column_name string\n # \u4F5C\u8005 liangyuzhe 20170108\n #\n def search_by_action_controller_params_for_jsonb(params, white_list, column_name)\n if white_list.present?\n if white_list.is_a? String\n permitted = params.permit(white_list)\n elsif white_list.is_a? Array\n permitted = {}\n white_list.each {|w| permitted.merge!(params.permit(w)) if w.is_a? String}\n end\n end\n if permitted.present?\n find_result(permitted.to_json, column_name)\n else\n self.all\n end\n rescue => e\n yloge e, '\u4F20\u5165\u7684\u6570\u636E\u6709\u95EE\u9898'\n end\n\n # \u5F97\u5230\u6570\u636E\u65B9\u6CD5\n def find_result(permitted, column_name)\n query = nil\n self.columns.map(&:name).each do |c|\n if column_name == c\n query = self.where(\"\#{'\#{column_name}'} @> :permitted\", permitted: permitted)\n end\n end\n query\n rescue => e\n yloge e, '\u4F20\u5165\u7684\u6570\u636E\u6709\u95EE\u9898'\n end\n\n\n def hash_keys_to_symbol(hash)\n {}.tap do |h|\n hash.each {|key, value| h[key.to_sym] = map_value(value)}\n end\n end\n end\n\n # \u4E3A\u7B80\u5355\u7684\u5BF9\u8C61\u66F4\u65B0\u8BB0\u5F55\n # \u4F5C\u8005 liangyuzhe 20161225\n def update_values_for_object(options)\n record = nil\n response = Response.rescue do |_res|\n column_sym = (self.class.columns.map(&:name) - %w(id deleted_at created_at updated_at)).map(&:to_sym)\n hash = {}\n column_sym.each do |c|\n hash.merge!(c => options[c]) if options[c].present?\n end\n record = self.update!(hash)\n end\n [response, record]\n end\n\n #\u6784\u9020\u67E5\u8BE2\u6761\u4EF6\n def self.build_search(options = {})\n if options.present?\n search_string = \"where \"\n keys = options.keys\n keys.each do |key|\n value = options[key]\n Rails.logger.info \">>>> build_search key: \#{'\#{key.to_s}'}\"\n Rails.logger.info \">>>> build_search value: \#{'\#{value.to_s}'}\"\n\n next unless (value.present? || !value.to_s.empty?) and value != \"''\" and !value.blank?\n #\u6A21\u7CCA\u67E5\u8BE2\n if key.to_s.include?('like_')\n attr_key = key.to_s.gsub('like_', '')\n str = \"\#{'\#{attr_key}'} like '%\#{'\#{value}'}%'\"\n\n #\u5426\u5B9A\u67E5\u8BE2\n elsif key.to_s.include?('no_')\n attr_key = key.to_s.gsub('no_', '')\n if attr_key == 'academic_category'\n str = \"\#{'\#{attr_key}'} != '\#{'\#{value.upcase}'}'\"\n else\n str = \"\#{'\#{attr_key}'} not like '%\#{'\#{value}'}%'\"\n end\n\n #\u6309\u65E5\u671F\u533A\u95F4\u67E5\u8BE2\n elsif key.to_s.include?('between_')\n attr_key = key.to_s.gsub('between_', '')\n date_array = value.split(',').collect {|item| item.tr('/', '-')}\n str = ''\n if date_array.size > 1\n str = \"\#{'\#{attr_key}'} between '\#{'\#{date_array[0]}'}' and '\#{'\#{date_array[1]}'}'\"\n elsif value[0].blank?\n str = \"\#{'\#{attr_key}'} <= '\#{'\#{date_array[0]}'}'\"\n elsif value[-1].blank?\n str = \"\#{'\#{attr_key}'} >= '\#{'\#{date_array[0]}'}'\"\n end\n\n # #\u7531\u4E8E\u6570\u636E\u5B58\u5728\u5F02\u5E38 \u7528\u4E8E\u7279\u5B9A\u7684\u6309\u6708\u67E5\u8BE2\n # elsif key.to_s.include?('special_')\n # attr_key = key.to_s.gsub('special_', '')\n # begin_month = value.split(' ')[0]\n # end_month = value.split(' ')[1]\n # str = \"(\#{'\#{attr_key}'} between '\#{'\#{begin_month}'}' and '\#{'\#{end_month}'}' or in_account_time_month between '\#{'\#{begin_month}'}' and '\#{'\#{end_month}'}')\"\n\n #\u7531\u4E8E\u6570\u636E\u5B58\u5728\u5F02\u5E38 \u7528\u4E8E\u7279\u5B9A\u7684\u6309\u6708\u67E5\u8BE2\n elsif key.to_s.include?('special_')\n attr_key = key.to_s.gsub('special_', '')\n date_array = value.split.collect {|item| item.tr('/', '-')}\n str = ''\n if date_array.size > 1\n str = \"(\#{'\#{attr_key}'} between '\#{'\#{date_array[0]}'}' and '\#{'\#{date_array[1]}'}' or in_account_time_month between '\#{'\#{date_array[0]}'}' and '\#{'\#{date_array[1]}'}')\"\n elsif value[0].blank?\n str = \"(\#{'\#{attr_key}'} <= '\#{'\#{date_array[0]}'}' or in_account_time_month <= '\#{'\#{date_array[0]}'}')\"\n elsif value[-1].blank?\n str = \"(\#{'\#{attr_key}'} >= '\#{'\#{date_array[0]}'}' or in_account_time_month >= '\#{'\#{date_array[0]}'}')\"\n end\n\n elsif key.to_s.end_with?('_id')\n str = ''\n if value.size > 0\n tmp = value.map {|item| item.to_i}.to_s\n tmp.tr!('[', '(')\n tmp.tr!(']', ')')\n str = \"\#{'\#{key}'} in \#{'\#{tmp}'}\"\n end\n\n #\u591A\u9009\u6A21\u7CCA\u67E5\u8BE2\n elsif key.to_s.include?('multi_')\n str = \"\"\n attr_key = key.to_s.gsub('multi_', '')\n value.each do |a|\n next unless a.present?\n tmp = \"\#{'\#{attr_key}'} like '%\#{'\#{a}'}%'\"\n if a != value.first and str != \"\"\n tmp = \" or \" + tmp\n end\n str += tmp\n end\n str = \"(\#{'\#{str}'})\"\n else\n if key == 'academic_category'\n str = \"\#{'\#{key}'} = '\#{'\#{value.upcase}'}'\"\n else\n str = \"\#{'\#{key.to_s}'}='\#{'\#{value}'}'\"\n end\n end\n if key != options.keys.first and search_string != \"where \"\n str = \" and \" + str\n end\n\n search_string += str\n end\n if search_string == \"where \"\n search_string = \"\"\n end\n # log(search_string)\n return search_string\n end\n end\n\n module AttributeType\n DECIMAL = 'decimal'\n STRING = 'string'\n DATE = 'date'\n end\n\n def generate_pinyin_when_create\n if self.deleted_at.blank?\n self.class.attribute_names.each do |attribute|\n self[attribute.intern] = PinYin.of_string(self[attribute.remove('_pinyin').intern]).join if attribute.include?('_pinyin')\n end\n end\n end\n\nend\n\n"
"# encoding: UTF-8\n# frozen_string_literal: true\n\nmodule ApplicationHelper\n #\n # \u6E32\u67D3json\u8FD4\u56DE\u5C5E\u6027\n #\n # @param json [Unknown] json\u5BF9\u8C61\n # @param obj [ActiveRecord] \u6570\u636E\u5E93\u8868\u7684\u5BF9\u8C61\n # @param attrs [Array] \u9700\u8981\u6E32\u67D3\u7684\u8868\u5C5E\u6027\u7B26\u53F7\u6570\u7EC4\n #\n def render_json_attrs(json, obj, attrs = nil)\n # Rails.logger.info \"obj=>\#{'\#{obj}'}\"\n if attrs.blank?\nattrs = obj.class.columns.map(&:name)\n end\n attrs.each do |column|\nnext unless column != 'deleted_at'\nkey = column.to_sym\ncolumn_type = obj.class.columns.select { |c| c.name == column.to_s }.first.type\nvalue = obj.__send__(column.to_sym)\nif value.present?\n value = value.to_time&.strftime('%F') if key.to_s == 'date' || key.to_s.include?('_date')\n # \u517C\u5BB9\u4EE3\u7801\n value = value.to_time&.strftime('%F %H:%M') if key.to_s =~ /_at$/ || key.to_s =~ /_time$/\n\n # if (/^([a-zA-Z]+_)*id$/ =~ key).present? || key.to_s == 'whodunnit'\n # if value.class == Array\n # value = value.map { |v| v }\n # else\n # value = value\n # end\n # end\nelse\n value = ''\n value = false if value != true && column_type == :boolean\nend\njson.__send__(key, value)\n end\n end\n\n def render_json_attrs_except(json, object, attrs = nil)\n attrs = object.class.columns.map(&:name) - (attrs.map { |x| x.to_s }) if attrs.present?\n\n render_json_attrs(json, object, attrs)\n end\n\n def render_json_array_partial(obj, array, particle, as)\n obj.__send__('array!', array, partial: particle, as: as)\n end\n\n #\n # \u5C06\u51C6\u786E\u65F6\u95F4\u8F6C\u6362\u6210\u76F8\u5BF9\u4E8E\u5F53\u524D\u7684\u65F6\u95F4\n #\n def timeago(time)\n return '' if time.blank?\n\n if time.is_a?(String)\ntime = begin\n Time.parse(time)\nrescue\n ''\nend\n elsif time.is_a?(Time)\ntime = time\n end\n\n return '' if time.blank?\n\n time_now = Time.now\n\n interval = (time_now - time).to_i\n\n case interval\n when 0 .. 3600\nminutes = interval / 60\n\ntime = I18n.t('timeago.minutes', minutes: minutes)\n\n when 3601 .. 86_400\nhours = interval / 3600\n\ntime = I18n.t('timeago.hours', hours: hours)\n\n when 86_401 .. 2_592_000\ndays = interval / 86_400\n\ntime = I18n.t('timeago.days', days: days)\n\n else\ntime = time.strftime('%F %H:%M')\n end\n\n time\n end\n\n def get_model(model_name)\n ActiveSupport::Dependencies.constantize(model_name.classify)\n end\n\n\nend\n"