index.vue 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292
  1. <template>
  2. <div class="base-container no-events">
  3. <fnHeader></fnHeader>
  4. <div class="content">
  5. <!-- <div class="top"></div> -->
  6. <div class="left yes-events">
  7. <tool-list
  8. direction="left"
  9. :list="leftToolList"
  10. @handleActive="handleActiveLeft"
  11. ></tool-list>
  12. <component :is="components[currentComponent]" />
  13. </div>
  14. <div class="home-bottom">
  15. <div class="log-box yes-events">
  16. <chart-box name="果园日志"></chart-box>
  17. </div>
  18. <div class="file-box yes-events">
  19. <chart-box name="果园档案">
  20. <template #title-right>
  21. <el-icon class="arrow-icon cursor-pointer" color="#141414"
  22. ><DArrowLeft
  23. /></el-icon>
  24. <div class="edit-btn cursor-pointer">编辑</div>
  25. </template>
  26. <div class="file-chart">
  27. <div
  28. v-for="(item, index) in fileData"
  29. :key="index"
  30. class="item-container"
  31. >
  32. <div class="file-label">{{ item.name }}</div>
  33. <div class="file-bar">
  34. <div
  35. v-for="(value, subIndex) in item.data"
  36. :key="subIndex"
  37. class="bar-block"
  38. :class="'bg-'+value.level"
  39. :style="{ width: computedWidths[index][subIndex] + 'px' }"
  40. >
  41. <el-tooltip
  42. class="tooltip-item"
  43. effect="light"
  44. :content="value.tag"
  45. placement="top"
  46. >
  47. <div class="cursor-pointer">{{ value.tag }}</div>
  48. </el-tooltip>
  49. </div>
  50. </div>
  51. </div>
  52. </div>
  53. </chart-box>
  54. </div>
  55. </div>
  56. <div class="right yes-events">
  57. <div class="list">
  58. <chart-box name="农事列表" arrow="arrow-left"></chart-box>
  59. </div>
  60. <tool-list direction="right" :list="rightToolList"></tool-list>
  61. </div>
  62. </div>
  63. </div>
  64. <div ref="mapRef" class="bottom-map"></div>
  65. </template>
  66. <script setup>
  67. import { onMounted, ref, computed } from "vue";
  68. import fnHeader from "@/components/fnHeader.vue";
  69. import chartBox from "@/components/chartBox.vue";
  70. import toolList from "@/components/toolList.vue";
  71. import HomeMap from "./homeMap";
  72. import homePage from "./components/homePage.vue";
  73. import weatherPage from "./components/weatherPage.vue";
  74. import phenologyPage from "./components/phenologyPage.vue";
  75. const components = {
  76. homePage,
  77. weatherPage,
  78. phenologyPage,
  79. };
  80. let homeMap = new HomeMap();
  81. const mapRef = ref();
  82. onMounted(() => {
  83. let location = "POINT (113.78049350268851 23.419886891845312)";
  84. homeMap.initMap(location, mapRef.value);
  85. });
  86. const currentComponent = ref("homePage");
  87. const handleActiveLeft = (e) => {
  88. currentComponent.value = e.componentName;
  89. };
  90. const leftToolList = [
  91. {
  92. title: "首页",
  93. name: "home",
  94. componentName: "homePage",
  95. },
  96. {
  97. title: "气象预警",
  98. componentName: "weatherPage",
  99. },
  100. {
  101. title: "物候调节",
  102. componentName: "phenologyPage",
  103. },
  104. {
  105. title: "病虫测报",
  106. },
  107. {
  108. title: "营养评估",
  109. },
  110. ];
  111. const rightToolList = [
  112. {
  113. title: "农事列表",
  114. },
  115. {
  116. title: "新增农事",
  117. },
  118. {
  119. title: "复核对比",
  120. },
  121. ];
  122. const fileData = ref([
  123. { name: '高产级', data: [
  124. { value: 325, level: 4, tag: '325棵' },
  125. { value: 325, level: 3, tag: '325棵' },
  126. { value: 325, level: 2, tag: '325棵' },
  127. { value: 325, level: 1, tag: '325棵' },
  128. ]},
  129. { name: '稳产级', data: [
  130. { value: 160, level: 4, tag: '160棵' },
  131. { value: 170, level: 3, tag: '170棵' },
  132. { value: 170, level: 2, tag: '170棵' },
  133. { value: 170, level: 1, tag: '170棵' },
  134. ]},
  135. { name: '休养-幼树', data: [
  136. { value: 380, level: 0, tag: '新嫁接1年 380棵' },
  137. { value: 330, level: 0, tag: '2年 330棵' },
  138. { value: 200, level: 0, tag: '3年 200棵' },
  139. ]},
  140. { name: '休养-病虫', data: [
  141. { value: 350, level: 3, tag: '蒂蛀虫 350棵' },
  142. { value: 350, level: 1, tag: '其他病 350棵' },
  143. ]},
  144. { name: '休养-生长', data: [
  145. { value: 300, level: 2, tag: '花芽 300棵' },
  146. { value: 280, level: 2, tag: '花穗 280棵' },
  147. { value: 320, level: 2, tag: '小果 320棵' },
  148. ]},
  149. ]);
  150. // 计算所有 data 中 value 属性的总和最大值
  151. const maxSum = computed(() => {
  152. return Math.max(...fileData.value.map(item => item.data.reduce((sum, dataPoint) => sum + dataPoint.value, 0)));
  153. });
  154. // 计算每个 dataPoint 的值在所有 data 中 value 总和最大值中所占的百分比
  155. const computedWidths = computed(() => {
  156. const max = maxSum.value;
  157. return fileData.value.map(item => {
  158. // 258是右侧容器总宽度
  159. return item.data.map(dataPoint => ((dataPoint.value / max) * 258).toFixed(0)); // 保留两位小数
  160. });
  161. });
  162. </script>
  163. <style lang="scss" scoped>
  164. .base-container {
  165. width: 100%;
  166. height: 100vh;
  167. color: #fff;
  168. position: absolute;
  169. box-sizing: border-box;
  170. z-index: 1;
  171. .content {
  172. width: 100%;
  173. height: calc(100% - 74px - 48px);
  174. display: flex;
  175. justify-content: space-between;
  176. box-sizing: border-box;
  177. .left,
  178. .right {
  179. width: calc(376px + 54px);
  180. height: 100%;
  181. padding-top: 10px;
  182. box-sizing: border-box;
  183. display: flex;
  184. }
  185. .right {
  186. .list {
  187. width: 100%;
  188. height: 100%;
  189. }
  190. }
  191. .home-bottom {
  192. display: flex;
  193. align-items: flex-end;
  194. width: calc(100% - 430px - 430px - 72px);
  195. height: 100%;
  196. align-self: flex-end;
  197. .log-box {
  198. height: 30%;
  199. width: calc(100% - 340px - 28px);
  200. margin-right: 28px;
  201. }
  202. .file-box {
  203. height: 25%;
  204. min-height: 210px;
  205. width: 340px;
  206. position: relative;
  207. .arrow-icon {
  208. top: -32px;
  209. left: 50%;
  210. position: absolute;
  211. background: #fff;
  212. width: 16px;
  213. height: 80px;
  214. line-height: 80px;
  215. border-radius: 5px 0 0 5px;
  216. text-align: center;
  217. transform: translateX(-50%) rotate(270deg);
  218. }
  219. .edit-btn {
  220. padding: 2px 24px;
  221. background: #2199f8;
  222. border-radius: 4px;
  223. }
  224. .file-chart {
  225. padding: 0 6px;
  226. height: 100%;
  227. display: flex;
  228. flex-direction: column;
  229. align-items: center;
  230. justify-content: center;
  231. .item-container {
  232. display: flex;
  233. width: 100%;
  234. color: #FFFFFF;
  235. margin-bottom: 12px;
  236. .file-label {
  237. width: 60px;
  238. text-align: right;
  239. font-size: 12px;
  240. }
  241. .file-bar {
  242. width: calc(100% - 56px);
  243. display: flex;
  244. padding-left: 6px;
  245. height: 18px;
  246. font-size: 10px;
  247. .bar-block {
  248. text-align: center;
  249. border-radius: 0px 4px 4px 0px;
  250. // border-image: linear-gradient(90deg, rgba(255, 223, 223, 0), rgba(234, 232, 232, 1)) 1 1;
  251. white-space: nowrap;
  252. overflow: hidden;
  253. text-overflow: ellipsis;
  254. &::before {
  255. content: "";
  256. position: absolute;
  257. top: -2px; /* 边框宽度的一半,且方向相反 */
  258. left: -2px; /* 边框宽度的一半,且方向相反 */
  259. right: -2px; /* 边框宽度的一半,且方向相反 */
  260. bottom: -2px; /* 边框宽度的一半,且方向相反 */
  261. background-image: linear-gradient(to right, rgba(255, 223, 223, 0), rgba(234, 232, 232, 1)); /* 渐变背景 */
  262. border-radius: 0px 4px 4px 0px; /* 继承容器的圆角半径 */
  263. z-index: -1; /* 放在容器内容之下 */
  264. }
  265. }
  266. .bg-0 {
  267. background-image: linear-gradient(to right, #042921, #0CBA93);
  268. }
  269. }
  270. }
  271. }
  272. }
  273. }
  274. }
  275. }
  276. .bottom-map {
  277. width: 100%;
  278. height: 100vh;
  279. position: absolute;
  280. z-index: 0;
  281. }
  282. </style>