scale_result.rb 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  1. # encoding:utf-8
  2. class ScaleResult < ActiveRecord::Base
  3. has_paper_trail
  4. self.table_name = "scale_result"
  5. belongs_to :wx_user
  6. belongs_to :scale_user, :foreign_key => :user_id
  7. def wx_user_contact
  8. return "-" if wx_user.blank?
  9. user = wx_user.user
  10. return "-" if user.blank?
  11. contact = user.tel
  12. contact = user.email if contact.blank?
  13. contact.blank? ? "-" : contact
  14. end
  15. # 从测量结果中获取时间戳
  16. def measurement_time
  17. return nil if result.blank?
  18. begin
  19. data = JSON.parse(result)
  20. timestamp = data['timestamp']
  21. return nil if timestamp.blank?
  22. Time.parse(timestamp)
  23. rescue => e
  24. nil
  25. end
  26. end
  27. # 格式化数值,保留2位小数
  28. def fmt(val)
  29. return '-' if val.nil?
  30. val.is_a?(Numeric) ? format('%.2f', val) : val.to_s
  31. end
  32. # 格式化显示测量结果(列表简要版)
  33. def result_summary
  34. return '-' if result.blank?
  35. begin
  36. d = JSON.parse(result)
  37. "体重:#{fmt(d['weight_kg'])}kg BMI:#{fmt(d['bmi'])} 体脂:#{fmt(d['bodyFatPercent'])}%"
  38. rescue
  39. '-'
  40. end
  41. end
  42. # 格式化显示测量结果(详情完整版)
  43. def result_formatted
  44. return '-' if result.blank?
  45. begin
  46. d = JSON.parse(result)
  47. userdata = d['userdata'] || {}
  48. html = '<table class="table table-striped table-condensed" style="font-size:13px;">'
  49. # 用户信息
  50. if userdata.present?
  51. html += '<tr><th colspan="4" style="background:#f5f5f5;">👤 用户信息</th></tr>'
  52. html += "<tr><td><b>昵称</b></td><td>#{userdata['nickName']}</td>"
  53. html += "<td><b>性别</b></td><td>#{userdata['sex'] == 0 ? '男' : '女'}</td></tr>"
  54. html += "<tr><td><b>年龄</b></td><td>#{userdata['age']}岁</td>"
  55. html += "<td><b>身高</b></td><td>#{userdata['height']}cm</td></tr>"
  56. end
  57. # 基础测量
  58. html += '<tr><th colspan="4" style="background:#f5f5f5;">📊 基础测量</th></tr>'
  59. html += "<tr><td><b>体重</b></td><td>#{fmt(d['weight_kg'])} kg</td>"
  60. html += "<td><b>BMI</b></td><td>#{fmt(d['bmi'])}</td></tr>"
  61. html += "<tr><td><b>身体评分</b></td><td>#{fmt(d['bodyScore'])} 分</td>"
  62. html += "<td><b>身体年龄</b></td><td>#{fmt(d['physicalAge'])} 岁</td></tr>"
  63. # 体成分
  64. html += '<tr><th colspan="4" style="background:#f5f5f5;">🏃 体成分分析</th></tr>'
  65. html += "<tr><td><b>体脂率</b></td><td>#{fmt(d['bodyFatPercent'])}%</td>"
  66. html += "<td><b>肌肉率</b></td><td>#{fmt(d['musclePercent'])}%</td></tr>"
  67. html += "<tr><td><b>内脏脂肪</b></td><td>#{fmt(d['visceralFat'])}</td>"
  68. html += "<td><b>皮下脂肪</b></td><td>#{fmt(d['subcutaneousFatPercent'])}%</td></tr>"
  69. html += "<tr><td><b>水分率</b></td><td>#{fmt(d['moisturePercent'])}%</td>"
  70. html += "<td><b>蛋白质</b></td><td>#{fmt(d['proteinPercent'])}%</td></tr>"
  71. html += "<tr><td><b>骨量</b></td><td>#{fmt(d['boneMass'])} kg</td>"
  72. html += "<td><b>基础代谢</b></td><td>#{fmt(d['bmr'])} kcal</td></tr>"
  73. html += "<tr><td><b>骨骼肌率</b></td><td>#{fmt(d['smPercent'])}%</td>"
  74. html += "<td><b>体型</b></td><td>#{d['bodyType']}</td></tr>"
  75. # 目标建议
  76. html += '<tr><th colspan="4" style="background:#f5f5f5;">🎯 目标建议</th></tr>'
  77. html += "<tr><td><b>目标体重</b></td><td>#{fmt(d['targetWeight'])} kg</td>"
  78. html += "<td><b>体重控制</b></td><td>#{fmt(d['weightControl'])} kg</td></tr>"
  79. html += "<tr><td><b>标准体重</b></td><td>#{fmt(d['weightStandard'])} kg</td>"
  80. html += "<td><b>标准BMI</b></td><td>#{fmt(d['bmiStandard'])}</td></tr>"
  81. # 设备信息
  82. html += '<tr><th colspan="4" style="background:#f5f5f5;">📱 设备信息</th></tr>'
  83. html += "<tr><td><b>MAC地址</b></td><td>#{d['mac']}</td>"
  84. html += "<td><b>测量时间</b></td><td>#{d['timestamp']}</td></tr>"
  85. html += '</table>'
  86. html.html_safe
  87. rescue => e
  88. "解析错误: #{e.message}"
  89. end
  90. end
  91. rails_admin do
  92. navigation_label '测量记录'
  93. parent ScaleDevice
  94. weight 2
  95. list do
  96. filters [:wx_user]
  97. field :id do
  98. label 'ID'
  99. end
  100. field :wx_user_id do
  101. label '微信用户ID'
  102. end
  103. field :wx_user do
  104. label '微信用户'
  105. pretty_value do
  106. bindings[:object].wx_user_contact
  107. end
  108. end
  109. field :user_id do
  110. label '称用户ID'
  111. end
  112. field :scale_user do
  113. label '称用户名'
  114. end
  115. field :result do
  116. label '测量结果'
  117. pretty_value do
  118. bindings[:object].result_summary
  119. end
  120. end
  121. field :measurement_time do
  122. label '测量时间'
  123. pretty_value do
  124. time = bindings[:object].measurement_time
  125. time.present? ? time.strftime('%Y-%m-%d %H:%M:%S') : '-'
  126. end
  127. sortable false
  128. end
  129. end
  130. show do
  131. field :id do
  132. label 'ID'
  133. end
  134. field :wx_user_id do
  135. label '微信用户ID'
  136. end
  137. field :wx_user do
  138. label '微信用户'
  139. pretty_value do
  140. bindings[:object].wx_user_contact
  141. end
  142. end
  143. field :user_id do
  144. label '称用户ID'
  145. end
  146. field :scale_user do
  147. label '称用户名'
  148. end
  149. field :result do
  150. label '测量结果'
  151. pretty_value do
  152. bindings[:object].result_formatted
  153. end
  154. end
  155. field :measurement_time do
  156. label '测量时间'
  157. pretty_value do
  158. time = bindings[:object].measurement_time
  159. time.present? ? time.strftime('%Y-%m-%d %H:%M:%S') : '-'
  160. end
  161. end
  162. end
  163. edit do
  164. field :wx_user do
  165. label '微信用户'
  166. end
  167. field :scale_user do
  168. label '称用户名'
  169. end
  170. field :result do
  171. label '测量结果'
  172. end
  173. end
  174. end
  175. end