product.rb 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441
  1. class Product < ActiveRecord::Base
  2. # Performance: list scope skips large TEXT columns (detail/detail_en/detail_ru/detail_tw)
  3. LIGHT_COLUMNS = %i[id name product_no category_id sale_zone price user_sale_price count recommend status virtual_sold_count purchase_limit_count share_img seckill_price size_id color_id relate_product_id show_flag allow_app sale_nums single_purch_limit package pv out_nums key_words created_at updated_at].freeze
  4. scope :light, -> { select(LIGHT_COLUMNS) }
  5. has_paper_trail
  6. self.table_name = 'products'
  7. #Thread.current[:current_user] = @current_user
  8. scope :active, -> { where(ptype: "cent_sale") }
  9. scope :inactive, -> { where(ptype: "direct_sale") }
  10. belongs_to :product_cat, :foreign_key => :category_id
  11. belongs_to :product_sale_type, :foreign_key => :sale_zone
  12. belongs_to :merchant, :foreign_key => :merchant_id
  13. has_and_belongs_to_many :depart_record
  14. validates :product_no,:name,:buy_price,:price,:category_id,:count,:robo_balance_price,:relate_product_id, presence: true
  15. validate :product_validation
  16. validates :id, presence: true, uniqueness: true
  17. validates_numericality_of :pv ,:only_integer => true,:greater_than_or_equal_to => 0, :less_than => 100
  18. def product_validation
  19. if self.relate_product_id <= 0
  20. #主商品默认关联商品
  21. if self.show_flag
  22. self.relate_product_id = self.id
  23. end
  24. prd = Product.where("id = ?", self.relate_product_id).first
  25. if prd.blank?
  26. self.relate_product_id = self.id
  27. end
  28. self.save
  29. end
  30. end
  31. attr_accessor :v_share_img,:get_size_enum,:get_color_enum,:gross_interest_rate
  32. # after_find :get_size_enum
  33. after_create :after_create
  34. before_save :before_save
  35. after_destroy :del_picture
  36. after_commit :clear_product_cache_after_commit
  37. def after_create
  38. #主商品默认关联商品
  39. if self.show_flag
  40. self.relate_product_id = self.id
  41. self.save
  42. end
  43. end
  44. def before_save
  45. #主商品默认关联商品
  46. if self.show_flag
  47. self.relate_product_id = self.id
  48. end
  49. if self.size_id.nil?
  50. self.size_id = 0
  51. end
  52. if self.color_id.nil?
  53. self.color_id = 0
  54. end
  55. end
  56. def del_picture
  57. # 删除商品图片
  58. pictures = ProductPicture.find_by_sql("select * from product_pictures where pic_type=0 and product_id = #{self.id}")
  59. # 创建商品图片
  60. pictures.each do |u|
  61. u.delete
  62. end
  63. end
  64. def self.notify_product_cache(product_id)
  65. return if product_id.blank?
  66. #清空商品缓存
  67. url = "#{CONFIG_FILE["api_host"]}/railsadmin/clean_cache/product/#{product_id}"
  68. p url
  69. open(url)
  70. end
  71. def clear_product_cache
  72. Product.notify_product_cache(self.id)
  73. end
  74. def clear_product_cache_after_commit
  75. clear_product_cache
  76. end
  77. TYPE_ENUM = [["直营","direct_sale"],["店铺专区","shop_sale"],["积分专区","cent_sale"]]
  78. SIZE_ENUM = []
  79. COLOR_ENUM = []
  80. def get_size_enum
  81. SIZE_ENUM.clear
  82. if SIZE_ENUM.length ==0 && !self.id.nil?
  83. linkSize = ProductAttrConfig.where("product_id=? and size_type='size'",self.relate_product_id).first
  84. if !linkSize.blank?
  85. productAttrs = ProductAttr.where("attr_key_id=? and status=1 ",linkSize.attr_key_id).order("recommend desc")
  86. productAttrs.each do |attr|
  87. a=[attr.name,attr.id]
  88. SIZE_ENUM.push(a)
  89. end
  90. end
  91. end
  92. return SIZE_ENUM
  93. end
  94. def get_color_enum
  95. COLOR_ENUM.clear
  96. if COLOR_ENUM.length==0 && !self.id.nil?
  97. linkColor = ProductAttrConfig.where("product_id=? and size_type='color'",self.relate_product_id).first
  98. if !linkColor.blank?
  99. productColorAttrs = ProductAttr.where("attr_key_id=? and status=1",linkColor.attr_key_id).order("recommend desc")
  100. productColorAttrs.each do |color_attr|
  101. b=[color_attr.name,color_attr.id]
  102. COLOR_ENUM.push(b)
  103. end
  104. end
  105. end
  106. return COLOR_ENUM
  107. end
  108. IMG_STORE_PATH = "product"
  109. def size_name
  110. linkSize = ProductAttr.where("id = ?", self.size_id).first
  111. if !linkSize.blank?
  112. return linkSize.name
  113. else
  114. return "-"
  115. end
  116. end
  117. def color_name
  118. linkColor = ProductAttr.where("id = ?", self.color_id).first
  119. if !linkColor.blank?
  120. return linkColor.name
  121. else
  122. return "-"
  123. end
  124. end
  125. def v_share_img=file
  126. unless file.blank?
  127. file_name = "#{UUID.new.generate[0...8].downcase}.jpg"
  128. file_path = "#{IMG_STORE_PATH}/product/share/#{file_name}"
  129. Ali::Oss.store(Ali::Oss::BUCKET_NAME_PUBLIC_READ, file_path, file.read)
  130. self.share_img = file_path
  131. self.save
  132. end
  133. end
  134. def clean_share_img
  135. file_path = "#{self.share_img}"
  136. Ali::Oss.delete_object(Ali::Oss::BUCKET_NAME_PUBLIC_READ, file_path)
  137. end
  138. def get_share_img
  139. url = "http://#{Ali::Oss::CDN_URL_FOR_HOST}/#{self.share_img}"
  140. return url
  141. end
  142. def after_destroy
  143. clean_share_img
  144. end
  145. def gross_interest_rate
  146. rate = 0
  147. if self.buy_price != 0 && self.price != 0
  148. rate = (( self.price.to_f - self.buy_price.to_f )/self.buy_price.to_f)*100
  149. end
  150. return rate
  151. end
  152. rails_admin do
  153. navigation_label '商品管理'
  154. weight -240
  155. list do
  156. scopes [nil, :light] # Performance: nil=All, :light=skip TEXT columns
  157. filters [:id,:status,:name]
  158. field :id
  159. #field :merchant_id
  160. #field :merchant
  161. field :name do
  162. filterable true
  163. end
  164. # field :ptype, :enum do
  165. # enum do
  166. # TYPE_ENUM
  167. # end
  168. # end
  169. field :product_no
  170. #field :category_id
  171. field :product_cat
  172. field :product_sale_type
  173. # field :detail # Removed: large TEXT column slows list
  174. field :price do
  175. label "现金价格(元)"
  176. formatted_value do # used in form views
  177. value.to_f / 100
  178. end
  179. end
  180. #field :robo_balance_price
  181. field :user_sale_price do
  182. label "零售价(元)"
  183. formatted_value do
  184. value.to_f / 100
  185. end
  186. end
  187. # field :buy_price
  188. #field :gross_interest_rate
  189. field :count
  190. field :recommend
  191. field :status
  192. #field :is_support_poor
  193. field :virtual_sold_count
  194. field :purchase_limit_count
  195. field :share_img do
  196. visible false
  197. formatted_value do
  198. bindings[:view].tag(:img,{:src => bindings[:object].get_share_img,
  199. :style => 'width: 100px;height: 100px;cursor: pointer;display: block;max-width: 100px;',
  200. :onClick => "javascript:window.open('#{bindings[:object].get_share_img}')"})
  201. end
  202. end
  203. field :seckill_price do
  204. label "秒杀显示原价(元)"
  205. formatted_value do # used in form views
  206. value.to_f / 100
  207. end
  208. end
  209. #field :is_only_new
  210. #ield :video_state
  211. # field :size_name # Removed: causes N+1 query per row
  212. # field :color_name # Removed: causes N+1 query per row
  213. field :relate_product_id
  214. field :show_flag
  215. # field :live
  216. field :allow_app
  217. # field :product_cycle
  218. # field :stock_cycle
  219. # field :min_purchase
  220. field :sale_nums
  221. field :single_purch_limit
  222. field :package
  223. field :pv do
  224. label "pv%"
  225. formatted_value do # used in form views
  226. "#{value}%"
  227. end
  228. end
  229. field :out_nums
  230. field :key_words
  231. field :depart_record
  232. field :created_at
  233. field :updated_at
  234. end
  235. show do
  236. field :id
  237. field :merchant_id
  238. field :merchant
  239. field :name
  240. field :name_en
  241. field :name_ru
  242. field :name_tw
  243. # field :ptype, :enum do
  244. # enum do
  245. # TYPE_ENUM
  246. # end
  247. # end
  248. field :product_no
  249. #field :category_id
  250. field :product_cat
  251. field :product_sale_type
  252. field :detail
  253. field :detail_en
  254. field :detail_ru
  255. field :detail_tw
  256. field :price do
  257. label "现金价格(元)"
  258. formatted_value do # used in form views
  259. value.to_f / 100
  260. end
  261. end
  262. field :robo_balance_price
  263. field :buy_price
  264. field :user_sale_price do
  265. label "零售价(元)"
  266. formatted_value do
  267. value.to_f / 100
  268. end
  269. end
  270. field :count
  271. field :recommend
  272. field :status
  273. #field :is_support_poor
  274. field :virtual_sold_count
  275. field :purchase_limit_count
  276. field :share_content
  277. # field :share_img do
  278. # formatted_value do
  279. # bindings[:view].tag(:img,{:src => bindings[:object].get_share_img,
  280. # :style => 'width: 100px;height: 100px;cursor: pointer;display: block;max-width: 100px;',
  281. # :onClick => "javascript:window.open('#{bindings[:object].get_share_img}')"})
  282. # end
  283. # end
  284. field :seckill_start
  285. field :seckill_end
  286. field :seckill_price do
  287. label "秒杀显示原价(元)"
  288. formatted_value do # used in form views
  289. value.to_f / 100
  290. end
  291. end
  292. field :deliver_stop_at
  293. field :deliver_start_at
  294. field :is_only_new
  295. field :specification
  296. field :no_delivery_area
  297. field :only_delivery_area
  298. field :video_state
  299. field :video_url
  300. field :size_name
  301. field :color_name
  302. field :relate_product_id
  303. field :show_flag
  304. # field :live
  305. field :allow_app
  306. field :single_purch_limit
  307. field :package
  308. # field :product_cycle
  309. # field :stock_cycle
  310. # field :min_purchase
  311. field :pv do
  312. label "pv%"
  313. formatted_value do # used in form views
  314. "#{value}%"
  315. end
  316. end
  317. field :out_nums
  318. field :silver
  319. field :use_quan
  320. field :key_words
  321. field :depart_record
  322. field :created_at
  323. field :updated_at
  324. end
  325. edit do
  326. field :id do
  327. read_only do
  328. bindings[:object].id
  329. end
  330. end
  331. field :name
  332. field :name_en
  333. field :name_ru
  334. field :name_tw
  335. # field :ptype, :enum do
  336. # enum do
  337. # TYPE_ENUM
  338. # end
  339. # end
  340. field :product_no
  341. #field :category_id
  342. field :merchant_id
  343. field :product_cat
  344. field :product_sale_type
  345. field :detail, :ck_editor
  346. field :detail_en, :ck_editor
  347. field :detail_ru, :ck_editor
  348. field :detail_tw, :ck_editor
  349. field :price
  350. field :robo_balance_price
  351. field :buy_price
  352. field :user_sale_price
  353. field :count
  354. field :recommend
  355. field :status
  356. #field :is_support_poor
  357. field :virtual_sold_count
  358. field :purchase_limit_count
  359. field :share_content
  360. =begin
  361. field :v_share_img, :file_upload do
  362. pretty_value do
  363. bindings[:view].tag(:img, {:src => bindings[:object].get_share_img, :class => 'preview'})
  364. end
  365. end
  366. =end
  367. field :seckill_start
  368. field :seckill_end
  369. field :seckill_price
  370. field :deliver_stop_at
  371. field :deliver_start_at
  372. field :is_only_new
  373. field :specification
  374. field :no_delivery_area
  375. field :only_delivery_area
  376. field :video_state
  377. field :video_url
  378. field :size_id, :enum do
  379. enum do
  380. bindings[:object].get_size_enum
  381. end
  382. end
  383. field :color_id, :enum do
  384. enum do
  385. bindings[:object].get_color_enum
  386. end
  387. end
  388. field :relate_product_id
  389. field :show_flag
  390. # field :live
  391. field :allow_app
  392. field :single_purch_limit
  393. field :package
  394. # field :product_cycle
  395. # field :stock_cycle
  396. # field :min_purchase
  397. field :pv do
  398. label "pv%"
  399. end
  400. field :out_nums
  401. field :key_words
  402. field :silver
  403. field :use_quan
  404. field :depart_record
  405. end
  406. end
  407. end