|
|
@@ -1,46 +1,91 @@
|
|
|
<template>
|
|
|
- <div class="risk-report-content">
|
|
|
+ <div
|
|
|
+ class="risk-report-content"
|
|
|
+ :class="{ 'risk-report-content--scrollable': !loading && !isEmpty }"
|
|
|
+ >
|
|
|
<div v-if="loading" class="panel-state">{{ t("agriFile.loading") }}</div>
|
|
|
- <div v-else-if="!riskList.length" class="panel-state">{{ t("growthReport.noRiskData") }}</div>
|
|
|
- <div
|
|
|
- v-else
|
|
|
- v-for="(item, index) in riskList"
|
|
|
- :key="index"
|
|
|
- class="risk-card"
|
|
|
- >
|
|
|
- <div class="risk-card__head">
|
|
|
- <img class="risk-card__icon" src="@/assets/img/report/weather-icon.png" alt="" />
|
|
|
- <span class="risk-card__label">{{ item.title || t("growthReport.weatherRisk") }}</span>
|
|
|
+ <div v-else-if="isEmpty" class="panel-state">{{ t("growthReport.noRiskData") }}</div>
|
|
|
+ <template v-else>
|
|
|
+ <div v-if="hasRiskSection" class="report-section">
|
|
|
+ <div class="report-section__head">
|
|
|
+ <img class="report-section__icon" :src="riskSection.icon || weatherIcon" alt="" />
|
|
|
+ <span class="report-section__title">{{ riskSection.title || t("growthReport.weatherRisk") }}</span>
|
|
|
+ </div>
|
|
|
+ <div v-if="riskSection.summary" class="risk-summary-card">
|
|
|
+ {{ riskSection.summary }}
|
|
|
+ </div>
|
|
|
+ <div
|
|
|
+ v-for="(item, index) in riskSection.items"
|
|
|
+ :key="`risk-${index}`"
|
|
|
+ class="risk-detail-card"
|
|
|
+ >
|
|
|
+ <div
|
|
|
+ class="risk-detail-card__text"
|
|
|
+ v-html="formatBoldText(item.description, item.boldKeywords)"
|
|
|
+ ></div>
|
|
|
+ </div>
|
|
|
</div>
|
|
|
- <div class="risk-card__content">
|
|
|
- <img class="risk-card__thumb" :src="item.image || defaultThumb" alt="" />
|
|
|
- <span class="risk-card__desc">{{ item.description }}</span>
|
|
|
+
|
|
|
+ <div v-if="adviceList.length" class="report-section">
|
|
|
+ <div class="report-section__head">
|
|
|
+ <img class="report-section__icon" :src="adviceIcon" alt="" />
|
|
|
+ <span class="report-section__title">{{ t("growthReport.farmAdvice") }}</span>
|
|
|
+ </div>
|
|
|
+ <div
|
|
|
+ v-for="(item, index) in adviceList"
|
|
|
+ :key="`advice-${index}`"
|
|
|
+ class="advice-card"
|
|
|
+ >
|
|
|
+ <div class="advice-card__title">{{ item.title }}</div>
|
|
|
+ <div class="advice-card__desc">{{ item.description }}</div>
|
|
|
+ </div>
|
|
|
</div>
|
|
|
- </div>
|
|
|
+ </template>
|
|
|
</div>
|
|
|
</template>
|
|
|
|
|
|
<script setup>
|
|
|
+import { computed } from "vue";
|
|
|
import { useI18n } from "@/i18n";
|
|
|
+import { boldKeywordsInText } from "@/utils/boldKeywords";
|
|
|
|
|
|
const { t } = useI18n();
|
|
|
|
|
|
-defineProps({
|
|
|
+const props = defineProps({
|
|
|
loading: {
|
|
|
type: Boolean,
|
|
|
default: false,
|
|
|
},
|
|
|
- riskList: {
|
|
|
+ riskSection: {
|
|
|
+ type: Object,
|
|
|
+ default: () => ({}),
|
|
|
+ },
|
|
|
+ adviceList: {
|
|
|
type: Array,
|
|
|
default: () => [],
|
|
|
},
|
|
|
});
|
|
|
|
|
|
-const defaultThumb = require("@/assets/img/home/banner.png");
|
|
|
+const weatherIcon = require("@/assets/img/report/weather-icon.png");
|
|
|
+const adviceIcon = require("@/assets/img/report/wh-icon.png");
|
|
|
+
|
|
|
+const hasRiskSection = computed(() => {
|
|
|
+ return Boolean(props.riskSection?.summary || props.riskSection?.items?.length);
|
|
|
+});
|
|
|
+
|
|
|
+const isEmpty = computed(() => {
|
|
|
+ return !hasRiskSection.value && !props.adviceList.length;
|
|
|
+});
|
|
|
+
|
|
|
+const formatBoldText = (text, keywords) => boldKeywordsInText(text, keywords);
|
|
|
</script>
|
|
|
|
|
|
<style lang="scss" scoped>
|
|
|
.risk-report-content {
|
|
|
+ &--scrollable {
|
|
|
+ padding-bottom: 50px;
|
|
|
+ }
|
|
|
+
|
|
|
.panel-state {
|
|
|
text-align: center;
|
|
|
color: #9a9a9a;
|
|
|
@@ -48,48 +93,72 @@ const defaultThumb = require("@/assets/img/home/banner.png");
|
|
|
padding: 20px 0;
|
|
|
}
|
|
|
|
|
|
- .risk-card + .risk-card {
|
|
|
- margin-top: 10px;
|
|
|
+ .report-section + .report-section {
|
|
|
+ margin-top: 16px;
|
|
|
}
|
|
|
|
|
|
- .risk-card {
|
|
|
+ .report-section {
|
|
|
&__head {
|
|
|
display: flex;
|
|
|
align-items: center;
|
|
|
- gap: 4px;
|
|
|
+ gap: 6px;
|
|
|
margin-bottom: 10px;
|
|
|
}
|
|
|
|
|
|
&__icon {
|
|
|
width: 18px;
|
|
|
- height: 16px;
|
|
|
+ height: 15px;
|
|
|
}
|
|
|
|
|
|
- &__label {
|
|
|
- font-weight: 500;
|
|
|
- color: #474747;
|
|
|
+ &__title {
|
|
|
+ font-size: 15px;
|
|
|
+ font-weight: 600;
|
|
|
+ color: #333;
|
|
|
}
|
|
|
+ }
|
|
|
|
|
|
- &__content {
|
|
|
- display: flex;
|
|
|
- align-items: center;
|
|
|
- gap: 10px;
|
|
|
+ .risk-summary-card {
|
|
|
+ padding: 8px;
|
|
|
+ border-radius: 5px;
|
|
|
+ background: rgba(33, 153, 248, 0.1);
|
|
|
+ color: #2199F8;
|
|
|
+ font-size: 13px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .risk-detail-card {
|
|
|
+ margin-top: 8px;
|
|
|
+ padding: 12px;
|
|
|
+ border-radius: 8px;
|
|
|
+ background: #f7f8fa;
|
|
|
+
|
|
|
+ &__text {
|
|
|
+ font-size: 13px;
|
|
|
+ color: rgba(6, 6, 6, 0.5);
|
|
|
+
|
|
|
+ :deep(.text-bold) {
|
|
|
+ color: #060606;
|
|
|
+ }
|
|
|
}
|
|
|
+ }
|
|
|
|
|
|
- &__thumb {
|
|
|
- width: 63px;
|
|
|
- height: 63px;
|
|
|
- border-radius: 4px;
|
|
|
- object-fit: cover;
|
|
|
+ .advice-card {
|
|
|
+ margin-top: 8px;
|
|
|
+ padding: 12px;
|
|
|
+ border-radius: 8px;
|
|
|
+ background: #f7f8fa;
|
|
|
+
|
|
|
+ &__title {
|
|
|
+ font-size: 14px;
|
|
|
+ font-weight: 600;
|
|
|
+ color: #333;
|
|
|
+ line-height: 1.5;
|
|
|
+ margin-bottom: 6px;
|
|
|
}
|
|
|
|
|
|
&__desc {
|
|
|
- color: rgba(6, 6, 6, 0.5);
|
|
|
- display: -webkit-box;
|
|
|
- -webkit-box-orient: vertical;
|
|
|
- -webkit-line-clamp: 3;
|
|
|
- line-clamp: 3;
|
|
|
- overflow: hidden;
|
|
|
+ font-size: 13px;
|
|
|
+ line-height: 1.65;
|
|
|
+ color: rgba(0, 0, 0, 0.5);
|
|
|
}
|
|
|
}
|
|
|
}
|