bannerTwo.vue 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437
  1. <template>
  2. <view class="banner-wrap banner-two">
  3. <view class="title-wrap">
  4. <view class="title">遥感环境评估</view>
  5. <view class="score">
  6. <text class="score-text">有味指数</text>
  7. <up-rate :count="5" size="13" readonly :allowHalf="true" active-color="#FF8400" gutter="1"
  8. v-model="envScore"></up-rate>
  9. <!-- <rate v-model="envScore" readonly allow-half :size="12" color="#FF8400" /> -->
  10. </view>
  11. </view>
  12. <view class="chart-wrap">
  13. <view class="chart-bg">
  14. </view>
  15. <!-- <radar-chart class="radar-wrap" :pieData="boxList"></radar-chart> -->
  16. <view class="charts-box" v-if="chartData">
  17. <qiun-data-charts type="radar" :opts="opts" :chartData="chartData" />
  18. </view>
  19. <view class="radar-list">
  20. <view class="radar-item" :class="{ active: active === index }" :style="item.style"
  21. v-for="(item, index) in boxList" :key="index" @click="handleActive(index)">
  22. <text class="radar-item-text">{{ item.name }}</text>
  23. <up-rate :count="5" readonly size="12" :allowHalf="true"
  24. :active-color="active === index ? '#000' : '#fff'" v-model="item.score"></up-rate>
  25. </view>
  26. </view>
  27. <view class="legend">
  28. <view class="legend-item">
  29. <view class="line"></view>
  30. <text>当前果园</text>
  31. </view>
  32. <view class="legend-item">
  33. <view class="line white"></view>
  34. <text>平均值</text>
  35. </view>
  36. </view>
  37. </view>
  38. <view class="box-wrap" v-if="boxList.length">
  39. <view class="box-header">
  40. <view class="name">
  41. <view class="name-text">天选生态好果</view>
  42. <text class="sub-text">{{ boxList[active].title }}</text>
  43. </view>
  44. <view class="title-line"></view>
  45. <!-- <el-viewider class="viewider" direction="vertical" /> -->
  46. <view class="rate">
  47. <up-rate :count="5" readonly size="18" :allowHalf="true" active-color="#FFCF66"
  48. v-model="boxList[active].score"></up-rate>
  49. <!-- <rate v-model="boxList[active].score" readonly allow-half :size="18" color="#FFCF66" /> -->
  50. </view>
  51. </view>
  52. <view class="text">
  53. {{ boxList[active].text }}
  54. </view>
  55. <view class="btn" @click="handleShowTwo(boxList[active].name)">查看评分方法</view>
  56. </view>
  57. </view>
  58. </template>
  59. <script setup>
  60. import { ref, watch, onMounted, onUnmounted } from "vue";
  61. import HOME from '@/api/home.js'
  62. import { onLoad } from '@dcloudio/uni-app'
  63. const props = defineProps({
  64. baseData: {
  65. type: Object,
  66. defalut: {}
  67. },
  68. activeIndex: {
  69. type: Number,
  70. defalut: 0,
  71. }
  72. })
  73. const envScore = ref(3)
  74. let autoClickTimer = null; // 自动点击定时器
  75. let lastUserClickTime = 0; // 记录用户最后一次点击时间
  76. watch(() => props.baseData, (newValue) => {
  77. envScore.value = newValue.envScore
  78. getData(newValue)
  79. })
  80. watch(() => props.activeIndex, (newValue) => {
  81. if (newValue === 2) {
  82. startAutoClick();
  83. } else {
  84. stopAutoClick();
  85. }
  86. })
  87. const emit = defineEmits(["handleShow"]);
  88. const handleShowTwo = (name) => {
  89. emit("handleShow", name);
  90. };
  91. const boxList = ref([]);
  92. const active = ref(0);
  93. // 处理点击事件
  94. const handleActive = (index) => {
  95. active.value = index;
  96. lastUserClickTime = Date.now(); // 更新用户最后点击时间
  97. resetAutoClickTimer(); // 重置自动点击计时器
  98. }
  99. // 开始自动点击
  100. const startAutoClick = () => {
  101. // 先清除已有定时器
  102. stopAutoClick();
  103. autoClickTimer = setInterval(() => {
  104. // 计算下一个要激活的索引
  105. const nextIndex = (active.value + 1) % boxList.value.length;
  106. active.value = nextIndex;
  107. }, 5000); // 每5秒执行一次
  108. }
  109. // 停止自动点击
  110. const stopAutoClick = () => {
  111. if (autoClickTimer) {
  112. clearInterval(autoClickTimer);
  113. autoClickTimer = null;
  114. }
  115. }
  116. // 重置自动点击计时器
  117. const resetAutoClickTimer = () => {
  118. stopAutoClick();
  119. startAutoClick();
  120. }
  121. // 组件挂载时启动自动点击
  122. onMounted(() => {
  123. // startAutoClick();
  124. })
  125. // 组件卸载时清除定时器
  126. onUnmounted(() => {
  127. stopAutoClick();
  128. })
  129. defineExpose({stopAutoClick, startAutoClick})
  130. const getData = (data) => {
  131. if (data.envDataItems.length < 0) return;
  132. const list = data.envDataItems.map((item, index) => {
  133. return {
  134. ...item,
  135. style: radarList.value[index].style,
  136. };
  137. });
  138. boxList.value = list;
  139. chartData.value = {
  140. categories: ["生境", "光照", "水源", "土壤", "风水"],
  141. series: [
  142. {
  143. name: "当前果园",
  144. data: list.map(item => item.score).reverse()
  145. },
  146. {
  147. name: "平均值",
  148. data: list.map(item => item.scoreAvg).reverse()
  149. }
  150. ]
  151. }
  152. // 数据加载后启动自动点击
  153. // resetAutoClickTimer();
  154. };
  155. const radarList = ref([
  156. {
  157. name: "生境",
  158. style: {
  159. top: "-2px",
  160. left: "calc(50% - 112px / 2)",
  161. },
  162. },
  163. {
  164. name: "光照",
  165. style: {
  166. top: "50px",
  167. right: "8px",
  168. },
  169. },
  170. {
  171. name: "水源",
  172. style: {
  173. top: "172px",
  174. right: "30px",
  175. },
  176. },
  177. {
  178. name: "土壤",
  179. style: {
  180. top: "172px",
  181. left: "30px",
  182. },
  183. },
  184. {
  185. name: "风水",
  186. style: {
  187. top: "50px",
  188. left: "8px",
  189. },
  190. },
  191. ]);
  192. const chartData = ref(null)
  193. const opts = {
  194. color: ["#FFCF66", "#FFFFFF"],
  195. padding: [0, 5, 5, 5],
  196. dataLabel: false,
  197. enableScroll: false,
  198. legend: {
  199. show: false,
  200. },
  201. extra: {
  202. radar: {
  203. gridType: "radar",
  204. gridColor: "#afbdc6",
  205. gridCount: 3,
  206. opacity: 0.2,
  207. max: 5,
  208. labelShow: false,
  209. border: true
  210. }
  211. }
  212. }
  213. </script>
  214. <style lang="scss" scoped>
  215. .banner-wrap {
  216. width: 100%;
  217. height: 100%;
  218. background-size: 100% 100%;
  219. background-repeat: no-repeat;
  220. background-position: center center;
  221. .title {
  222. font-size: 36px;
  223. letter-spacing: 4px;
  224. font-family: "jiangxizhuokai";
  225. }
  226. .charts-box {
  227. width: 327px;
  228. height: 238px;
  229. position: relative;
  230. left: 50%;
  231. transform: translateX(-50%);
  232. z-index: 3;
  233. }
  234. &.banner-two {
  235. background-image: url("https://birdseye-img.sysuimars.com/youwei-uniapp/home/report-banner-2.png");
  236. padding: 60px 14px;
  237. box-sizing: border-box;
  238. .score {
  239. color: #ff8400;
  240. font-size: 15px;
  241. font-family: "jiangxizhuokai";
  242. background: rgba(255, 255, 255, 0.4);
  243. border: 1px solid rgba(255, 255, 255, 0.55);
  244. border-radius: 5px;
  245. padding: 8px 16px;
  246. width: fit-content;
  247. box-sizing: border-box;
  248. margin: 12px 0 32px 0;
  249. display: flex;
  250. align-items: center;
  251. .score-text {
  252. margin-right: 6px;
  253. }
  254. }
  255. .chart-wrap {
  256. width: 100%;
  257. position: relative;
  258. ::v-deep {
  259. .van-rate__icon {
  260. color: inherit;
  261. }
  262. }
  263. .chart-bg {
  264. position: absolute;
  265. z-index: 2;
  266. top: 12px;
  267. left: 50%;
  268. transform: translateX(-50%);
  269. background: rgba(0, 0, 0, 0.2);
  270. width: 208px;
  271. height: 208px;
  272. border-radius: 50%;
  273. }
  274. .radar-wrap {
  275. width: 100%;
  276. height: 220px;
  277. }
  278. .radar-list {
  279. .radar-item {
  280. position: absolute;
  281. z-index: 3;
  282. top: 0;
  283. padding: 5px 8px;
  284. background: rgba(0, 0, 0, 0.3);
  285. border-radius: 20px;
  286. font-size: 13px;
  287. font-family: "jiangxizhuokai";
  288. display: flex;
  289. align-items: center;
  290. border: 1px solid transparent;
  291. &.active {
  292. background: #ffcf66;
  293. border: 1px solid #fff;
  294. color: #000;
  295. &::before {
  296. content: "";
  297. position: absolute;
  298. left: -15px;
  299. background: url("https://birdseye-img.sysuimars.com/youwei-uniapp/home/arrow.png") no-repeat center center / 100% 100%;
  300. width: 13px;
  301. height: 16px;
  302. transform: rotate(180deg);
  303. }
  304. &::after {
  305. content: "";
  306. position: absolute;
  307. right: -15px;
  308. background: url("https://birdseye-img.sysuimars.com/youwei-uniapp/home/arrow.png") no-repeat center center / 100% 100%;
  309. width: 13px;
  310. height: 16px;
  311. }
  312. }
  313. .radar-item-text {
  314. margin-right: 4px;
  315. }
  316. }
  317. }
  318. .legend {
  319. position: absolute;
  320. right: 12px;
  321. top: -5px;
  322. background: rgba(0, 0, 0, 0.4);
  323. border-radius: 6px;
  324. padding: 4px 6px;
  325. .legend-item {
  326. display: flex;
  327. align-items: center;
  328. font-size: 10px;
  329. .line {
  330. background: #ffc33f;
  331. border-radius: 2px;
  332. width: 7px;
  333. height: 3px;
  334. margin-right: 4px;
  335. }
  336. .white {
  337. background: #fff;
  338. }
  339. }
  340. }
  341. }
  342. .box-wrap {
  343. margin-top: 14px;
  344. background: rgba(0, 0, 0, 0.3);
  345. padding: 10px 12px;
  346. border-radius: 8px;
  347. border: 1px solid #ffcf66;
  348. backdrop-filter: blur(2px);
  349. // min-height: 154px;
  350. // box-sizing: border-box;
  351. .box-header {
  352. display: flex;
  353. align-items: center;
  354. justify-content: center;
  355. font-family: "jiangxizhuokai";
  356. .name {
  357. .name-text {
  358. font-family: "jiangxizhuokai";
  359. color: #ffcf66;
  360. letter-spacing: 5px;
  361. }
  362. .sub-text {
  363. font-size: 11px;
  364. }
  365. }
  366. .title-line {
  367. margin: 0 24rpx;
  368. width: 2rpx;
  369. height: 26px;
  370. background: rgba(255, 255, 255, 0.3);
  371. }
  372. }
  373. .text {
  374. font-size: 12px;
  375. margin: 10px 0 5px 0;
  376. }
  377. .btn {
  378. font-size: 11px;
  379. padding: 7px 12px;
  380. border-radius: 20px;
  381. background: rgba(255, 255, 255, 0.3);
  382. text-align: center;
  383. width: 90px;
  384. box-sizing: border-box;
  385. margin: auto;
  386. }
  387. }
  388. }
  389. }
  390. </style>