element.vue 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220
  1. <template>
  2. <view class="element">
  3. <view class="element-header">
  4. <view class="element-title">{{ title }}</view>
  5. <view class="element-status" v-if="!sensorList">
  6. 2024-01-25 16:05:05
  7. <u-icon name="reload" color="#14A478" style="margin-left: 20rpx" />
  8. </view>
  9. </view>
  10. <view class="element-body">
  11. <view class="element-group" v-for="(group, gIndex) in groups" :key="gIndex">
  12. <!-- 组名:接口 sensor_list 节点 display_name(对应 PC 屏的 1组/2组 徽标) -->
  13. <view class="element-group-name" v-if="group.name">{{ group.name }}</view>
  14. <view class="element-grid">
  15. <view class="element-row" v-for="(item, index) in group.sensors" :key="index">
  16. <image :src="item.url" class="element-col-icon" />
  17. <view class="element-col">
  18. <view class="element-col-title"
  19. >{{ item.content }}
  20. <text class="unit">{{ item.unit }}</text>
  21. </view>
  22. <view class="element-col-content">{{ item.title }}</view>
  23. </view>
  24. </view>
  25. </view>
  26. </view>
  27. </view>
  28. </view>
  29. </template>
  30. <script>
  31. export default {
  32. name: 'Element',
  33. props: {
  34. // status 接口返回的 sensor_list(节点嵌套:display_name + children),为空时展示内置示例
  35. sensorList: {
  36. type: Array,
  37. default: null,
  38. },
  39. title: {
  40. type: String,
  41. default: '1号环控',
  42. },
  43. },
  44. computed: {
  45. // sensor_list 节点 → 分组:组名取节点 display_name,子传感器值取 SensorDevXX:FieldName 遥测 key
  46. groups() {
  47. if (!this.sensorList || !this.sensorList.length) {
  48. return this.demoGroups;
  49. }
  50. return this.sensorList
  51. .map((node) => ({
  52. name: node.display_name || '',
  53. sensors: (node.children || []).map((item) => {
  54. const key = Object.keys(item).find((k) =>
  55. /^SensorDev\d+:\w+$/.test(k)
  56. );
  57. const val = key ? item[key] : null;
  58. return {
  59. title: item.display_name || '',
  60. unit: item.unit || '',
  61. content: val == null ? '--' : val,
  62. url: this.iconByName(item.display_name),
  63. };
  64. }),
  65. }))
  66. .filter((group) => group.sensors.length);
  67. },
  68. },
  69. data() {
  70. return {
  71. demoGroups: [
  72. {
  73. name: '1组',
  74. sensors: [
  75. {
  76. url: 'https://s3.hnyfwlw.com/webstaticimg/bigdata_app/greenHouseIcon/sensor_temp.png',
  77. title: '空气温度',
  78. unit: '℃',
  79. content: '12',
  80. },
  81. {
  82. url: 'https://s3.hnyfwlw.com/webstaticimg/bigdata_app/greenHouseIcon/sensor_humidity.png',
  83. title: '空气湿度',
  84. unit: '%',
  85. content: '80',
  86. },
  87. {
  88. url: 'https://s3.hnyfwlw.com/webstaticimg/bigdata_app/greenHouseIcon/sensor_soil_temp.png',
  89. title: '土壤温度',
  90. unit: '℃',
  91. content: '80',
  92. },
  93. {
  94. url: 'https://s3.hnyfwlw.com/webstaticimg/bigdata_app/greenHouseIcon/sensor_soil_humidity.png',
  95. title: '土壤湿度',
  96. unit: '%',
  97. content: '80',
  98. },
  99. {
  100. url: 'https://s3.hnyfwlw.com/webstaticimg/bigdata_app/greenHouseIcon/sensor_co2.png',
  101. title: '二氧化碳',
  102. unit: 'ppm',
  103. content: '80',
  104. },
  105. {
  106. url: 'https://s3.hnyfwlw.com/webstaticimg/bigdata_app/greenHouseIcon/sensor_sun.png',
  107. title: '光照',
  108. unit: 'LUX',
  109. content: '80',
  110. },
  111. {
  112. url: 'https://s3.hnyfwlw.com/webstaticimg/bigdata_app/greenHouseIcon/sensor_ph.png',
  113. title: '土壤PH值',
  114. unit: '',
  115. content: '80',
  116. },
  117. ],
  118. },
  119. ],
  120. };
  121. },
  122. methods: {
  123. // 按传感器名称匹配图标
  124. iconByName(name) {
  125. const n = String(name || '');
  126. if (n.includes('土壤') && n.includes('湿')) {
  127. return 'https://s3.hnyfwlw.com/webstaticimg/bigdata_app/greenHouseIcon/sensor_soil_humidity.png';
  128. }
  129. if (n.includes('土壤')) {
  130. return 'https://s3.hnyfwlw.com/webstaticimg/bigdata_app/greenHouseIcon/sensor_soil_temp.png';
  131. }
  132. if (n.includes('湿')) {
  133. return 'https://s3.hnyfwlw.com/webstaticimg/bigdata_app/greenHouseIcon/sensor_humidity.png';
  134. }
  135. if (n.includes('二氧化碳')) {
  136. return 'https://s3.hnyfwlw.com/webstaticimg/bigdata_app/greenHouseIcon/sensor_co2.png';
  137. }
  138. if (n.includes('光照') || n.includes('亮度')) {
  139. return 'https://s3.hnyfwlw.com/webstaticimg/bigdata_app/greenHouseIcon/sensor_sun.png';
  140. }
  141. if (n.toLowerCase().includes('ph')) {
  142. return 'https://s3.hnyfwlw.com/webstaticimg/bigdata_app/greenHouseIcon/sensor_ph.png';
  143. }
  144. return 'https://s3.hnyfwlw.com/webstaticimg/bigdata_app/greenHouseIcon/sensor_temp.png';
  145. },
  146. },
  147. };
  148. </script>
  149. <style lang="less" scoped>
  150. .element {
  151. .element-header {
  152. display: flex;
  153. justify-content: space-between;
  154. align-items: center;
  155. margin-bottom: 20rpx;
  156. color: #042118;
  157. font-family: 'Source Han Sans CN VF';
  158. font-size: 28rpx;
  159. font-weight: 700;
  160. .element-status {
  161. color: #687a74;
  162. text-align: center;
  163. font-family: 'Source Han Sans CN VF';
  164. font-size: 28rpx;
  165. font-weight: 400;
  166. }
  167. }
  168. .element-body {
  169. padding: 20rpx;
  170. .element-group {
  171. & + .element-group {
  172. margin-top: 32rpx;
  173. }
  174. }
  175. // 组名徽标:浅绿底绿字(对应 PC 深色屏的 1组/2组 方块)
  176. .element-group-name {
  177. display: inline-block;
  178. padding: 6rpx 24rpx;
  179. margin-bottom: 20rpx;
  180. background: #e6f7ee;
  181. border-radius: 8rpx;
  182. color: #0bbc58;
  183. font-family: 'Source Han Sans CN VF';
  184. font-size: 24rpx;
  185. font-weight: 600;
  186. }
  187. .element-grid {
  188. display: grid;
  189. grid-template-columns: repeat(2, 1fr);
  190. grid-gap: 20rpx;
  191. .element-row {
  192. display: flex;
  193. margin-bottom: 20rpx;
  194. .element-col-icon {
  195. width: 80rpx;
  196. height: 80rpx;
  197. margin-right: 10rpx;
  198. }
  199. .element-col {
  200. margin-left: 10rpx;
  201. .element-col-title {
  202. font-size: 28rpx;
  203. color: #042118;
  204. font-weight: 700;
  205. .unit {
  206. font-size: 24rpx;
  207. color: #999;
  208. }
  209. }
  210. .element-col-content {
  211. font-size: 24rpx;
  212. color: #666;
  213. }
  214. }
  215. }
  216. }
  217. }
  218. }
  219. </style>