Эх сурвалжийг харах

数智双碳4个页面模型开发完成。

DESKTOP-6LTVLN7\Liumouren 2 жил өмнө
parent
commit
c6f636f01d

+ 1 - 0
.gitignore

@@ -25,3 +25,4 @@ dist-ssr
 *.njsproj
 *.njsproj
 *.sln
 *.sln
 *.sw?
 *.sw?
+package-lock.json

+ 136 - 0
src/components/doubleCarbon/AnalogData.js

@@ -0,0 +1,136 @@
+// 双碳概览-模拟数据
+const optionsNameOfUnit = [
+    { value: "1", label: "中讯邮电咨询设计院有限公司" },
+    { value: "2", label: "北京电信规划设计院" }
+]
+const CHART_DATA = {
+    BarChartData: {
+        yAxisData: ["中讯", "北京规划院", "郑分", "广分", "上分"],
+        seriesData: {
+            碳配额存量: [120, 132, 101, 134, 90, 230, 210],
+            碳配额消耗: [220, 182, 191, 234, 290, 330, 310]
+        }
+    },
+    LineChartData: {
+        xAxisData: ["1月", "2月", "3月", "4月", "5月", "6月", "7月"],
+        seriesData: {
+            中讯: [120, 132, 101, 134, 90, 230, 210],
+            北京规划院: [220, 182, 191, 234, 290, 330, 310],
+            郑分: [150, 232, 201, 154, 190, 330, 410],
+            广分: [320, 332, 301, 334, 390, 330, 320],
+            上分: [820, 932, 901, 934, 1290, 1330, 1320]
+        }
+    },
+    PieChartData: {
+        seriesName: "碳排放占比",
+        seriesData: [
+            { value: 1048, name: "汽油" },
+            { value: 735, name: "柴油" },
+            { value: 580, name: "天然气" },
+            { value: 484, name: "热力" },
+            { value: 300, name: "电力" },
+            { value: 199, name: "其他" }
+        ]
+    }
+}
+const doubleCarbonNewsInfoList = [
+    {
+        title: "【助力“双碳”,人才缺口这么补】",
+        content: `<div class="article"><p>  近日,天津市科学技术局等6部门发布《天津市科技支撑碳达峰碳中和实施方案(2022—2030年)》,提出加强绿色低碳领域人才选拔培养,加大对绿色低碳领域科技人才的支持力度,积极引进绿色低碳科技创新发展急需的各类人才,加强人才队伍建设。</p>
+<p>  不只是天津,放眼全国,上海、吉林、贵州、内蒙古等地相关政府部门也已经陆续发布了关于科技支撑碳达峰、碳中和(以下简称“双碳”)的实施方案,其中“提升绿色低碳人才培养能力”成为各地方案中都提到的一项内容。</p>
+<p>  <strong>产业、技术变革催生新需求</strong></p>
+<p>  2020年,我国提出采取更加有力的政策和措施,二氧化碳排放力争2030年前达到峰值,努力争取2060年前实现碳中和。这就是人们熟知的“双碳”目标。</p>
+<p>  其实,早在“双碳”目标提出前,我国的清洁能源建设已经取得重大成就,在水电、风电、光伏及氢能、储能等领域,人才队伍培养与建设均在有序进行。而当“双碳”目标提出后,一场广泛而深刻的经济社会系统性变革就此开始,清洁能源领域人才队伍开始走上助力实现“双碳”目标的转型之路。</p>
+<p>  面对新形势,原有人才队伍能否满足需求呢?</p>
+<p>  答案是否定的。</p>
+<p>  科技部科技人才交流开发服务中心开发服务处处长牛萍在具体调研中发现,战略科学家不足、复合型人才稀少、产业人才短缺成为当前“双碳”科技人才市场的主要特点。</p>
+<p>  牛萍告诉科技日报记者,面向“双碳”目标,通识教育难以满足复合型“双碳”科技人才的培养需求,导致高校“双碳”科技人才培养与市场需求不匹配。与此同时,“双碳”领域相关产学研合作不足,产业人才缺乏,这些都是导致“双碳”人才出现紧缺的原因。</p>
+<p>  在具体产业方面,从教育部下发的方案中可以看出,储能与氢能、碳捕集利用与封存、碳金融和碳交易等领域尤其缺乏人才支撑。</p>
+<p>  “人才需求的改变,源于产业需求的变化。”相关业内专家表示,“在‘双碳’目标提出前,氢能和储能产业关注的是‘能’,而在‘双碳’目标提出后,产业的关注点转变为‘碳’。换言之,‘双碳’目标的提出使氢能和储能等相关产业的技术目标,由追求相对减排率转变为追求绝对减排量。”</p>
+<p>  不仅是产业变化,技术变革也会带来人才需求的改变。</p>
+<p>  二氧化碳捕集、利用与封存(CCUS)技术被形象地称为“碳捕手”,其可将二氧化碳从工业或其他碳排放源中捕集,并运输到特定地点加以利用或封存,具有减排规模大、减排效益明显的特点。</p>
+<p>  不过,在过去很长一段时间内,二氧化碳捕集、利用与封存技术并未“合体”,而是各自分散在不同行业。伴随降碳要求的不断增加,化石能源大规模低碳化利用的技术需求也随之增加,二氧化碳捕集、利用与封存技术被有机地“组合”到一起。同时,行业从业者也要完成技能、知识等的“交叉融合”,此外还需要复合型人才的加入。</p>
+<p>  <strong>产学研多方推进人才培养</strong></p>
+<p>  在内蒙古乌兰察布市,三峡现代能源创新示范园(以下简称示范园)拔地而起。示范园里,中国长江三峡集团有限公司(以下简称三峡集团)“拉了个群”,联合产学研合作伙伴,共同探索“源网荷储”(以“电源、电网、负荷、储能”为整体规划的新型电力运行模式)一体化新型能源系统发展,建设源网荷储技术研发试验基地。</p>
+<p>  “示范园中的源网荷储技术研发试验基地,是三峡集团培养储能技术人才的一个基地。”三峡集团科学技术研究院综合能源技术研究中心主任尹立坤告诉科技日报记者,2020年,他们综合考量全球先进储能技术,结合我国地理、气候特点,选择对8种新型储能技术进行研究,并建成2个行业急需的大型实验室,联合中国科学院、清华大学、华北电力大学等20余家科研单位进行技术攻关,联合培养人才。</p>
+<p>  此后短短2年,一系列储能技术成果相继落地:当前国内容量最大的功率路由器设备,国内规模最大、类型最丰富的储能系统动态模拟平台,兆瓦时级固态锂离子电池储能关键技术及工程应用项目……</p>
+<p>  科研成果创下“行业之最”的同时,科研人才也不断涌现。三峡集团科学技术研究院统计资料显示,目前集团已培养博士20余名,其中15名青年骨干研发人员已走上企业储能一线工作岗位。</p>
+<p>  产业之外,以培养人才为己任的高校也加快了探索的脚步。</p>
+<p>  2021年9月,清华大学成立碳中和研究院。作为学科交叉研究平台,该研究院整合清华大学相关领域学科优势,直面“双碳”领域复合型人才稀少等难题,协同打造低碳、零碳、负碳等颠覆性的核心技术,推动碳中和相关学科建设和高层次人才培养。</p>
+<p>  清华大学碳中和研究院院长助理、环境学院教授鲁玺介绍,目前清华大学碳中和研究院有8个研究中心,研究方向涵盖低碳能源、新型电力系统、零碳建筑、零碳交通、工业深度减碳、减污降碳协同增效、气候变化与碳中和战略及气候治理与碳金融等交叉领域,以系统思维推动碳中和人才队伍建设和培养。</p>
+<p>  <strong>关键一步在于转变观念</strong></p>
+<p>  2021年10月24日,《中共中央国务院关于完整准确全面贯彻新发展理念做好碳达峰碳中和工作的意见》和《国务院关于印发2030年前碳达峰行动方案的通知》正式印发,从国家层面对“双碳”工作进行顶层设计。此后,各领域“双碳”行动方案陆续出台,“双碳”“1+N”政策体系不断完善,“双碳”科技人才培养的政策举措不断优化。</p>
+<p>  2022年4月24日,教育部印发《加强碳达峰碳中和高等教育人才培养体系建设工作方案》,从加快紧缺人才培养、促进传统专业转型升级、加强高水平教师队伍建设等9个方面,明确22条主要任务和重点举措。同年8月17日,科技部等九部门发布《科技支撑碳达峰碳中和实施方案(2022—2030)》,提出推动国家绿色低碳创新基地建设和人才培养,培养和发展壮大碳达峰碳中和领域战略科学家、科技领军人才和创新团队、青年人才和创新创业人才,建设面向实现碳达峰碳中和目标的可持续人才队伍。</p>
+<p>  “对于‘双碳’人才的培养,我国在‘双碳’‘1+N’政策体系下,不断统筹优化‘双碳’科技人才培养举措,顶层设计已相对健全。”牛萍介绍,但在省市区县各级政府部门制定的“双碳”工作实施方案及规划中,对“双碳”人才培养虽有所提及,却仍然缺乏关于“双碳”人才的专项政策,缺少更具体的实施举措。</p>
+<p>  在牛萍看来,双碳人才培养的关键一步在于转变观念。从科研人才到产业人才,都需要将“碳”的观念树立起来,提升自身的“双碳”素养,让“双碳”理念先行。尤其是各级政府部门,可以通过开展科技人才“双碳”素养提升行动,为各类“双碳”人才涌现营造良好的生态环境。</p>
+<p>  未来,面向“双碳”科技人才的培养需求,牛萍建议,要建立“双碳”重点领域全球高层次人才动态监测机制,为“双碳”科技人才靶向引进和自主培养提供决策参考;加强符合“双碳”标准的复合型科技人才培养,在国际标准平台上扩大中国的影响力。</p></div>`,
+        author: "科技日报",
+        pushTime: "2023-02-13 15:30"
+    },
+    {
+        title: "【减碳小妙招】",
+        content: "xxxxxxxxxxxxxxxxxx165465465465xxxxx",
+        author: "中讯邮电设计院-张三",
+        pushTime: "2021-08-09"
+    },
+    {
+        title: "【减碳小妙招】",
+        content: "xxxxxxxxxxxxxxxxxxxxxxx",
+        author: "中讯邮电设计院-张三",
+        pushTime: "2021-08-09"
+    }
+]
+const core_List = [
+    {
+        title: "碳配额存量",
+        value: "60%",
+        leavel: 1
+    },
+    {
+        title: "碳排放存量",
+        value: 500,
+        unit: "tCO2e",
+        info: {
+            title: "同比上升",
+            leavel: 3,
+            value: "0.4%"
+        }
+    },
+    {
+        title: "单位面积碳排放",
+        value: 380,
+        unit: "tCO2e/m²",
+        info: {
+            title: "同比上升",
+            leavel: 3,
+            value: "0.4%"
+        }
+    },
+    {
+        title: "人均碳排放",
+        value: 80,
+        unit: "tCO2e/人",
+        info: {
+            title: "同比上升",
+            leavel: 3,
+            value: "0.4%"
+        }
+    },
+    {
+        title: "光伏减排",
+        value: 40,
+        unit: "tCO2e",
+        info: {
+            title: "同比上升",
+            leavel: 3,
+            value: "0.4%"
+        }
+    },
+    {
+        title: "值得关注",
+        value: "减少2辆车出行一周"
+    }
+]
+export default {
+    optionsNameOfUnit, CHART_DATA, doubleCarbonNewsInfoList, core_List
+}

+ 456 - 3
src/components/doubleCarbon/PV/doubleCarbonPv.vue

@@ -4,11 +4,464 @@
     @date 2023年2月8日
     @date 2023年2月8日
 -->
 -->
 <template>
 <template>
-  <div>光伏发电页面类似双碳概览页面</div>
+  <div class="doubleCarbon-main-box flexColumn">
+    <a-spin class="spinStyle" size="large" tip="Loading..." v-show="searchLoading"></a-spin>
+    <!-- 头部搜索区域 -->
+    <div class="borderColor">
+      <div class="flex flex_between margin5rem">
+        <div class="flex">
+          <div class="mr1rem">
+            单位名称:
+            <a-select
+              style="width:200px;"
+              v-model="searchParam.nameOfUnit"
+              :allowClear="selectProps.allowClear"
+              :mode="selectProps.mode"
+              :options="options.nameOfUnit"
+              :notFoundConent="selectProps.notFoundConent"
+              :placeholder="selectProps.placeholder"
+            ></a-select>
+          </div>
+          <div>
+            时间范围: <a-month-picker id="startTime" format="YYYY-MM" @change="changeTimeRangeS" placeholder="开始时间" />~
+            <a-month-picker id="endTime" format="YYYY-MM" @change="changeTimeRangeE" placeholder="结束时间" />
+          </div>
+        </div>
+        <div>
+          <a-button class="mr1rem" @click="reset">重置</a-button>
+          <a-button type="primary" @click="search">查询</a-button>
+        </div>
+      </div>
+      <div class="cardTitle margin5rem">核心指标</div>
+      <div v-if="coreList.length > 0" class="flex flex_around coreListBox margin5rem">
+        <div v-for="(item, index) in coreList" :key="'coreList' + index">
+          <div class="core_title">{{ item.title }}</div>
+          <div class="core_value">
+            {{ item.value ? item.value : "--" }}<span class="core_unit">{{ item.unit ? item.unit : "" }}</span
+            ><span class="core_leavel" v-if="item.leavel" :style="{ color: $constant.COLOR_LEAVEL[item.leavel] }">!</span>
+          </div>
+          <div v-if="item.info" class="core_info">
+            <span class="core_info_title">{{ item.info.title }}</span
+            ><span class="core_info_value" :style="{ color: $constant.COLOR_LEAVEL[item.info.leavel] }"
+              >{{ item.info.value
+              }}<i
+                v-if="item.info.leavel && (item.info.leavel == 1 || item.info.leavel == 3)"
+                :class="item.info.leavel == 3 ? 'el-icon-caret-top' : 'el-icon-caret-bottom'"
+            /></span>
+          </div>
+        </div>
+      </div>
+      <div class="flex flex_around coreListBox margin5rem" v-if="coreList.length == 0" style="height:120px;">
+        <a-empty></a-empty>
+      </div>
+    </div>
+    <!-- 碳排放分析和碳配额构成 -->
+    <div class="flex" style="height:400px;">
+      <div class="echartBox_left borderColor">
+        <div class="cardTitle margin5rem">碳排放分析</div>
+        <div class="margin5rem chartDomBox">
+          <LineChart v-if="chartData.LineChartData" :echartData="chartData.LineChartData" />
+          <a-empty v-else></a-empty>
+        </div>
+      </div>
+      <div class="echartBox_right borderColor">
+        <div class="cardTitle margin5rem">碳配额构成</div>
+        <div class="margin5rem chartDomBox">
+          <BarChart v-if="chartData.BarChartData" :echartData="chartData.BarChartData" />
+          <a-empty v-else></a-empty>
+        </div>
+      </div>
+    </div>
+  </div>
 </template>
 </template>
 
 
 <script>
 <script>
-export default {};
+import LineChart from "../../echart/LineChart.vue";
+import BarChart from "../../echart/BarChart.vue";
+import PieChart from "../../echart/PieChart.vue";
+// 模拟数据
+import  AnalogData from "../AnalogData.js"
+export default {
+  components: {
+    LineChart,
+    BarChart,
+    PieChart
+  },
+  data() {
+    return {
+      // selectProps配置
+      selectProps: {
+        allowClear: true, // 支持清除
+        mode: "default", // 模式['default'|'multiple'|'tags'|'combobox']
+        notFoundConent: "Not Found", // 当下拉列表为空时显示的内容
+        placeholder: "请选择", // 选择框默认文字 string|slot
+        showArrow: true, // 是否显示下拉小箭头
+        size: "large" // 选择框大小['large'|'small']
+      },
+      // 单位名称option可选值
+      options: {
+        nameOfUnit: [] // options 数据,如果设置则不需要手动构造 selectOption 节点
+      },
+      // loading状态
+      searchLoading: true,
+      // 头部搜索条件中绑定值
+      monthArr: [],
+      searchParam: {
+        nameOfUnit: undefined,
+        timeRange: [undefined, undefined]
+      },
+      // 头部核心指标循环显示数据
+      coreList: [],
+      // 双碳新闻模拟数据
+      DoubleCarbonNewsInfoList: [],
+      // 双碳新闻弹窗打开状态
+      showModalStatus: false,
+      // 弹窗暂存数据对象
+      showModalInfo: {
+        title: "--",
+        content: "--",
+        author: "--",
+        pushTime: "--"
+      },
+      // chart暂存数据对象
+      chartData: []
+    };
+  },
+  created() {},
+  mounted() {
+    // 页面初始化
+    this.init();
+    //默认是当年的1月到12月
+    this.defaulTimeRangeS();
+    this.defaulTimeRangeE();
+  },
+  methods: {
+    // 开始时间初始化
+    defaulTimeRangeS() {
+      this.searchParam.timeRange[0] = this.$moment()
+        .startOf("year")
+        .format("YYYY-MM-DD 00:00:00");
+      document.getElementById("startTime").querySelector("input").value = this.$moment()
+        .startOf("year")
+        .format("YYYY-MM");
+    },
+    // 结束时间初始化
+    defaulTimeRangeE() {
+      this.searchParam.timeRange[1] = this.$moment()
+        .endOf("year")
+        .format("YYYY-MM-DD 23:59:59");
+      document.getElementById("endTime").querySelector("input").value = this.$moment()
+        .endOf("year")
+        .format("YYYY-MM");
+    },
+    // 修改开始时间时
+    changeTimeRangeS(date, dateStr) {
+      // 修改时间前判断是否合理
+      if (this.searchParam.timeRange[1]) {
+        if (
+          this.$moment(this.$moment(dateStr, "YYYY-MM").format("YYYY-MM-DD 00:00:00")).diff(
+            this.$moment(this.searchParam.timeRange[1])
+          ) > 0
+        ) {
+          this.$message.error("开始时间不能大于结束时间!请重新选择!");
+          setTimeout(() => {
+            document.getElementById("startTime").querySelector("input").value = this.$moment()
+              .startOf("year")
+              .format("YYYY-MM");
+          }, 10);
+        }
+      }
+      if (dateStr) {
+        this.searchParam.timeRange[0] = this.$moment(dateStr, "YYYY-MM").format("YYYY-MM-DD 00:00:00");
+      } else {
+        this.searchParam.timeRange[0] = undefined;
+      }
+    },
+    // 修改结束时间时
+    changeTimeRangeE(date, dateStr) {
+      // 修改时间前判断是否合理
+      if (this.searchParam.timeRange[0]) {
+        if (
+          this.$moment(this.searchParam.timeRange[0]).diff(
+            this.$moment(
+              this.$moment(dateStr, "YYYY-MM")
+                .endOf("month")
+                .format("YYYY-MM-DD 23:59:59")
+            )
+          ) > 0
+        ) {
+          this.$message.error("结束时间不能小于开始时间!请重新选择!");
+          setTimeout(() => {
+            document.getElementById("endTime").querySelector("input").value = this.$moment()
+              .endOf("year")
+              .format("YYYY-MM");
+          }, 10);
+        }
+      }
+      if (dateStr) {
+        this.searchParam.timeRange[1] = this.$moment(dateStr, "YYYY-MM")
+          .endOf("month")
+          .format("YYYY-MM-DD 23:59:59");
+      } else {
+        this.searchParam.timeRange[1] = undefined;
+      }
+    },
+    // 查询事件
+    search() {
+      // 时间范围条件不合理判断
+      if (this.searchParam.timeRange[0] || this.searchParam.timeRange[1]) {
+        if (!this.searchParam.timeRange[0]) {
+          this.$message.info("请选择开始时间!");
+          return;
+        } else if (!this.searchParam.timeRange[1]) {
+          this.$message.info("请选择结束时间!");
+          return;
+        }
+      }
+      this.searchLoading = true;
+      console.log("查询条件:", this.searchParam.nameOfUnit, this.searchParam.timeRange[0], this.searchParam.timeRange[1]);
+      setTimeout(() => {
+        this.searchLoading = false;
+      }, 1000);
+    },
+    // 重置事件
+    reset() {
+      document.getElementById("startTime").querySelector("input").value = this.$moment()
+        .startOf("year")
+        .format("YYYY-MM");
+      document.getElementById("endTime").querySelector("input").value = this.$moment()
+        .endOf("year")
+        .format("YYYY-MM");
+      this.searchParam = {
+        nameOfUnit: undefined,
+        timeRange: [
+          this.$moment()
+            .startOf("year")
+            .format("YYYY-MM-DD 00:00:00"),
+          this.$moment()
+            .endOf("year")
+            .format("YYYY-MM-DD 23:59:59")
+        ]
+      };
+    },
+    // 弹窗显示事件
+    showModal(item) {
+      this.showModalStatus = true;
+      this.showModalInfo = item;
+    },
+    // 弹窗隐藏事件
+    onCancel() {
+      this.showModalStatus = false;
+    },
+    init() {
+      // 初始化加载[单位名称列表、核心指标、碳排放分析、碳配额构成、碳排放占比、双碳新闻]
+      setTimeout(() => {
+        this.options.nameOfUnit = AnalogData.optionsNameOfUnit;
+        this.coreList = AnalogData.core_List;
+        this.chartData = AnalogData.CHART_DATA;
+        this.DoubleCarbonNewsInfoList = AnalogData.doubleCarbonNewsInfoList;
+        this.searchLoading = false;
+      }, 1000);
+    }
+  }
+};
 </script>
 </script>
 
 
-<style lang="less" scoped></style>
+<style lang="less" scoped>
+// 复用样式
+.flexColumn {
+  display: flex;
+  flex-direction: column;
+  flex-wrap: nowrap;
+}
+.flex {
+  display: flex;
+  flex-wrap: wrap;
+  align-content: center;
+  align-items: center;
+  &_center {
+    display: flex;
+    flex-wrap: wrap;
+    align-content: center;
+    align-items: center;
+    justify-content: center;
+  }
+  &_between {
+    display: flex;
+    flex-wrap: wrap;
+    align-content: center;
+    align-items: center;
+    justify-content: space-between;
+  }
+  &_around {
+    display: flex;
+    flex-wrap: wrap;
+    align-content: center;
+    align-items: center;
+    justify-content: space-around;
+  }
+}
+.borderColor {
+  border: 1px solid #e7eaf1;
+}
+.margin5rem {
+  margin: 0.5rem;
+}
+.padding5rem {
+  padding: 0.5rem;
+}
+// 页面主题样式
+.doubleCarbon-main-box {
+  position: relative;
+  width: 100%;
+  height: 100%;
+  & * {
+    user-select: none;
+    -moz-user-select: none;
+    -webkit-user-select: none;
+    -ms-user-select: none;
+    ::-webkit-scrollbar {
+      width: 0 !important;
+    }
+    -ms-overflow-style: none;
+    overflow: -moz-scrollbars-none;
+  }
+  & > div {
+    // padding: 5px 10px;
+    border-radius: 2px;
+    margin-bottom: 10px;
+  }
+  .spinStyle {
+    position: absolute;
+    width: 100%;
+    height: 100%;
+    background: rgba(255, 255, 255, 0.75);
+    z-index: 2;
+  }
+}
+// 头部搜索框和(重置、查询)按钮之间的间距样式
+.mr1rem {
+  margin-right: 1rem;
+}
+// 每个card标题的字体样式
+.cardTitle {
+  padding-left: 5px;
+  font-size: 14px;
+  font-weight: bold;
+  border-left: 5px solid @primary-color;
+}
+// 核心指标
+.coreListBox {
+  border-radius: 0.5rem;
+  background-color: rgb(233, 246, 253);
+  & > div {
+    position: relative;
+    // border-left: 1px solid #909399;
+    padding: 10px;
+    margin: 10px;
+    cursor: pointer;
+    border-radius: 0.5rem;
+    &:hover {
+      background-color: rgb(210, 239, 255);
+    }
+    // &::before {
+    //   content: "";
+    //   position: absolute;
+    //   left: -10px;
+    //   height: calc(100% - 20px);
+    //   width: 1px;
+    //   background: #c9c9c9;
+    // }
+  }
+}
+// 核心指标中value的样式
+.core {
+  &_title {
+    font-size: 12px;
+    padding-bottom: 10px;
+  }
+  &_leavel {
+    font-size: 16px;
+    font-weight: bold;
+  }
+  &_value {
+    font-size: 16px;
+    font-weight: 500;
+    color: #000;
+  }
+  &_unit {
+    padding-left: 0.5rem;
+    font-size: 12px;
+    font-weight: bold;
+    color: #909399;
+  }
+  &_info {
+    padding-top: 10px;
+    font-size: 12px;
+    &_title {
+      color: #afafaf;
+    }
+    &_value {
+      padding-left: 0.5rem;
+      font-weight: bold;
+    }
+  }
+}
+// echartBox样式
+.echartBox {
+  &_left {
+    width: calc(100% - 300px - 10px);
+    height: 100%;
+  }
+  &_right {
+    margin-left: 10px;
+    width: 300px;
+    height: 100%;
+  }
+}
+.chartDomBox {
+  position: relative;
+  width: calc(100% - 20px);
+  height: calc(100% - 41px);
+  display: flex;
+  justify-content: center;
+}
+.DoubleCarbonNews {
+  padding: 10px 0;
+  font-weight: bold;
+  color: #000;
+  cursor: pointer;
+  border-bottom: 1px solid #c9c9c9;
+  &:hover {
+    color: @primary-color;
+  }
+  & > div {
+    overflow: hidden;
+    text-overflow: ellipsis;
+    white-space: nowrap;
+  }
+  & > div:nth-child(1) {
+    width: 15%;
+  }
+  & > div:nth-child(2) {
+    height: 21px;
+    overflow: hidden;
+    width: calc(50% - 110px);
+  }
+  & > div:nth-child(3) {
+    width: 20%;
+  }
+  & > div:nth-child(4) {
+    width: 15%;
+  }
+  & > div:nth-child(5) {
+    width: 30px;
+  }
+}
+// loading样式
+.spin-content {
+  border: 1px solid #91d5ff;
+  background-color: #e6f7ff;
+  padding: 30px;
+}
+</style>

+ 456 - 3
src/components/doubleCarbon/car/doubleCarbonCar.vue

@@ -4,11 +4,464 @@
     @date 2023年2月8日
     @date 2023年2月8日
 -->
 -->
 <template>
 <template>
-  <div>车辆排放页面类似双碳概览页面</div>
+  <div class="doubleCarbon-main-box flexColumn">
+    <a-spin class="spinStyle" size="large" tip="Loading..." v-show="searchLoading"></a-spin>
+    <!-- 头部搜索区域 -->
+    <div class="borderColor">
+      <div class="flex flex_between margin5rem">
+        <div class="flex">
+          <div class="mr1rem">
+            单位名称:
+            <a-select
+              style="width:200px;"
+              v-model="searchParam.nameOfUnit"
+              :allowClear="selectProps.allowClear"
+              :mode="selectProps.mode"
+              :options="options.nameOfUnit"
+              :notFoundConent="selectProps.notFoundConent"
+              :placeholder="selectProps.placeholder"
+            ></a-select>
+          </div>
+          <div>
+            时间范围: <a-month-picker id="startTime" format="YYYY-MM" @change="changeTimeRangeS" placeholder="开始时间" />~
+            <a-month-picker id="endTime" format="YYYY-MM" @change="changeTimeRangeE" placeholder="结束时间" />
+          </div>
+        </div>
+        <div>
+          <a-button class="mr1rem" @click="reset">重置</a-button>
+          <a-button type="primary" @click="search">查询</a-button>
+        </div>
+      </div>
+      <div class="cardTitle margin5rem">核心指标</div>
+      <div v-if="coreList.length > 0" class="flex flex_around coreListBox margin5rem">
+        <div v-for="(item, index) in coreList" :key="'coreList' + index">
+          <div class="core_title">{{ item.title }}</div>
+          <div class="core_value">
+            {{ item.value ? item.value : "--" }}<span class="core_unit">{{ item.unit ? item.unit : "" }}</span
+            ><span class="core_leavel" v-if="item.leavel" :style="{ color: $constant.COLOR_LEAVEL[item.leavel] }">!</span>
+          </div>
+          <div v-if="item.info" class="core_info">
+            <span class="core_info_title">{{ item.info.title }}</span
+            ><span class="core_info_value" :style="{ color: $constant.COLOR_LEAVEL[item.info.leavel] }"
+              >{{ item.info.value
+              }}<i
+                v-if="item.info.leavel && (item.info.leavel == 1 || item.info.leavel == 3)"
+                :class="item.info.leavel == 3 ? 'el-icon-caret-top' : 'el-icon-caret-bottom'"
+            /></span>
+          </div>
+        </div>
+      </div>
+      <div class="flex flex_around coreListBox margin5rem" v-if="coreList.length == 0" style="height:120px;">
+        <a-empty></a-empty>
+      </div>
+    </div>
+    <!-- 碳排放分析和碳配额构成 -->
+    <div class="flex" style="height:400px;">
+      <div class="echartBox_left borderColor">
+        <div class="cardTitle margin5rem">碳排放分析</div>
+        <div class="margin5rem chartDomBox">
+          <LineChart v-if="chartData.LineChartData" :echartData="chartData.LineChartData" />
+          <a-empty v-else></a-empty>
+        </div>
+      </div>
+      <div class="echartBox_right borderColor">
+        <div class="cardTitle margin5rem">碳配额构成</div>
+        <div class="margin5rem chartDomBox">
+          <BarChart v-if="chartData.BarChartData" :echartData="chartData.BarChartData" />
+          <a-empty v-else></a-empty>
+        </div>
+      </div>
+    </div>
+  </div>
 </template>
 </template>
 
 
 <script>
 <script>
-export default {};
+import LineChart from "../../echart/LineChart.vue";
+import BarChart from "../../echart/BarChart.vue";
+import PieChart from "../../echart/PieChart.vue";
+// 模拟数据
+import  AnalogData from "../AnalogData.js"
+export default {
+  components: {
+    LineChart,
+    BarChart,
+    PieChart
+  },
+  data() {
+    return {
+      // selectProps配置
+      selectProps: {
+        allowClear: true, // 支持清除
+        mode: "default", // 模式['default'|'multiple'|'tags'|'combobox']
+        notFoundConent: "Not Found", // 当下拉列表为空时显示的内容
+        placeholder: "请选择", // 选择框默认文字 string|slot
+        showArrow: true, // 是否显示下拉小箭头
+        size: "large" // 选择框大小['large'|'small']
+      },
+      // 单位名称option可选值
+      options: {
+        nameOfUnit: [] // options 数据,如果设置则不需要手动构造 selectOption 节点
+      },
+      // loading状态
+      searchLoading: true,
+      // 头部搜索条件中绑定值
+      monthArr: [],
+      searchParam: {
+        nameOfUnit: undefined,
+        timeRange: [undefined, undefined]
+      },
+      // 头部核心指标循环显示数据
+      coreList: [],
+      // 双碳新闻模拟数据
+      DoubleCarbonNewsInfoList: [],
+      // 双碳新闻弹窗打开状态
+      showModalStatus: false,
+      // 弹窗暂存数据对象
+      showModalInfo: {
+        title: "--",
+        content: "--",
+        author: "--",
+        pushTime: "--"
+      },
+      // chart暂存数据对象
+      chartData: []
+    };
+  },
+  created() {},
+  mounted() {
+    // 页面初始化
+    this.init();
+    //默认是当年的1月到12月
+    this.defaulTimeRangeS();
+    this.defaulTimeRangeE();
+  },
+  methods: {
+    // 开始时间初始化
+    defaulTimeRangeS() {
+      this.searchParam.timeRange[0] = this.$moment()
+        .startOf("year")
+        .format("YYYY-MM-DD 00:00:00");
+      document.getElementById("startTime").querySelector("input").value = this.$moment()
+        .startOf("year")
+        .format("YYYY-MM");
+    },
+    // 结束时间初始化
+    defaulTimeRangeE() {
+      this.searchParam.timeRange[1] = this.$moment()
+        .endOf("year")
+        .format("YYYY-MM-DD 23:59:59");
+      document.getElementById("endTime").querySelector("input").value = this.$moment()
+        .endOf("year")
+        .format("YYYY-MM");
+    },
+    // 修改开始时间时
+    changeTimeRangeS(date, dateStr) {
+      // 修改时间前判断是否合理
+      if (this.searchParam.timeRange[1]) {
+        if (
+          this.$moment(this.$moment(dateStr, "YYYY-MM").format("YYYY-MM-DD 00:00:00")).diff(
+            this.$moment(this.searchParam.timeRange[1])
+          ) > 0
+        ) {
+          this.$message.error("开始时间不能大于结束时间!请重新选择!");
+          setTimeout(() => {
+            document.getElementById("startTime").querySelector("input").value = this.$moment()
+              .startOf("year")
+              .format("YYYY-MM");
+          }, 10);
+        }
+      }
+      if (dateStr) {
+        this.searchParam.timeRange[0] = this.$moment(dateStr, "YYYY-MM").format("YYYY-MM-DD 00:00:00");
+      } else {
+        this.searchParam.timeRange[0] = undefined;
+      }
+    },
+    // 修改结束时间时
+    changeTimeRangeE(date, dateStr) {
+      // 修改时间前判断是否合理
+      if (this.searchParam.timeRange[0]) {
+        if (
+          this.$moment(this.searchParam.timeRange[0]).diff(
+            this.$moment(
+              this.$moment(dateStr, "YYYY-MM")
+                .endOf("month")
+                .format("YYYY-MM-DD 23:59:59")
+            )
+          ) > 0
+        ) {
+          this.$message.error("结束时间不能小于开始时间!请重新选择!");
+          setTimeout(() => {
+            document.getElementById("endTime").querySelector("input").value = this.$moment()
+              .endOf("year")
+              .format("YYYY-MM");
+          }, 10);
+        }
+      }
+      if (dateStr) {
+        this.searchParam.timeRange[1] = this.$moment(dateStr, "YYYY-MM")
+          .endOf("month")
+          .format("YYYY-MM-DD 23:59:59");
+      } else {
+        this.searchParam.timeRange[1] = undefined;
+      }
+    },
+    // 查询事件
+    search() {
+      // 时间范围条件不合理判断
+      if (this.searchParam.timeRange[0] || this.searchParam.timeRange[1]) {
+        if (!this.searchParam.timeRange[0]) {
+          this.$message.info("请选择开始时间!");
+          return;
+        } else if (!this.searchParam.timeRange[1]) {
+          this.$message.info("请选择结束时间!");
+          return;
+        }
+      }
+      this.searchLoading = true;
+      console.log("查询条件:", this.searchParam.nameOfUnit, this.searchParam.timeRange[0], this.searchParam.timeRange[1]);
+      setTimeout(() => {
+        this.searchLoading = false;
+      }, 1000);
+    },
+    // 重置事件
+    reset() {
+      document.getElementById("startTime").querySelector("input").value = this.$moment()
+        .startOf("year")
+        .format("YYYY-MM");
+      document.getElementById("endTime").querySelector("input").value = this.$moment()
+        .endOf("year")
+        .format("YYYY-MM");
+      this.searchParam = {
+        nameOfUnit: undefined,
+        timeRange: [
+          this.$moment()
+            .startOf("year")
+            .format("YYYY-MM-DD 00:00:00"),
+          this.$moment()
+            .endOf("year")
+            .format("YYYY-MM-DD 23:59:59")
+        ]
+      };
+    },
+    // 弹窗显示事件
+    showModal(item) {
+      this.showModalStatus = true;
+      this.showModalInfo = item;
+    },
+    // 弹窗隐藏事件
+    onCancel() {
+      this.showModalStatus = false;
+    },
+    init() {
+      // 初始化加载[单位名称列表、核心指标、碳排放分析、碳配额构成、碳排放占比、双碳新闻]
+      setTimeout(() => {
+        this.options.nameOfUnit = AnalogData.optionsNameOfUnit;
+        this.coreList = AnalogData.core_List;
+        this.chartData = AnalogData.CHART_DATA;
+        this.DoubleCarbonNewsInfoList = AnalogData.doubleCarbonNewsInfoList;
+        this.searchLoading = false;
+      }, 1000);
+    }
+  }
+};
 </script>
 </script>
 
 
-<style lang="less" scoped></style>
+<style lang="less" scoped>
+// 复用样式
+.flexColumn {
+  display: flex;
+  flex-direction: column;
+  flex-wrap: nowrap;
+}
+.flex {
+  display: flex;
+  flex-wrap: wrap;
+  align-content: center;
+  align-items: center;
+  &_center {
+    display: flex;
+    flex-wrap: wrap;
+    align-content: center;
+    align-items: center;
+    justify-content: center;
+  }
+  &_between {
+    display: flex;
+    flex-wrap: wrap;
+    align-content: center;
+    align-items: center;
+    justify-content: space-between;
+  }
+  &_around {
+    display: flex;
+    flex-wrap: wrap;
+    align-content: center;
+    align-items: center;
+    justify-content: space-around;
+  }
+}
+.borderColor {
+  border: 1px solid #e7eaf1;
+}
+.margin5rem {
+  margin: 0.5rem;
+}
+.padding5rem {
+  padding: 0.5rem;
+}
+// 页面主题样式
+.doubleCarbon-main-box {
+  position: relative;
+  width: 100%;
+  height: 100%;
+  & * {
+    user-select: none;
+    -moz-user-select: none;
+    -webkit-user-select: none;
+    -ms-user-select: none;
+    ::-webkit-scrollbar {
+      width: 0 !important;
+    }
+    -ms-overflow-style: none;
+    overflow: -moz-scrollbars-none;
+  }
+  & > div {
+    // padding: 5px 10px;
+    border-radius: 2px;
+    margin-bottom: 10px;
+  }
+  .spinStyle {
+    position: absolute;
+    width: 100%;
+    height: 100%;
+    background: rgba(255, 255, 255, 0.75);
+    z-index: 2;
+  }
+}
+// 头部搜索框和(重置、查询)按钮之间的间距样式
+.mr1rem {
+  margin-right: 1rem;
+}
+// 每个card标题的字体样式
+.cardTitle {
+  padding-left: 5px;
+  font-size: 14px;
+  font-weight: bold;
+  border-left: 5px solid @primary-color;
+}
+// 核心指标
+.coreListBox {
+  border-radius: 0.5rem;
+  background-color: rgb(233, 246, 253);
+  & > div {
+    position: relative;
+    // border-left: 1px solid #909399;
+    padding: 10px;
+    margin: 10px;
+    cursor: pointer;
+    border-radius: 0.5rem;
+    &:hover {
+      background-color: rgb(210, 239, 255);
+    }
+    // &::before {
+    //   content: "";
+    //   position: absolute;
+    //   left: -10px;
+    //   height: calc(100% - 20px);
+    //   width: 1px;
+    //   background: #c9c9c9;
+    // }
+  }
+}
+// 核心指标中value的样式
+.core {
+  &_title {
+    font-size: 12px;
+    padding-bottom: 10px;
+  }
+  &_leavel {
+    font-size: 16px;
+    font-weight: bold;
+  }
+  &_value {
+    font-size: 16px;
+    font-weight: 500;
+    color: #000;
+  }
+  &_unit {
+    padding-left: 0.5rem;
+    font-size: 12px;
+    font-weight: bold;
+    color: #909399;
+  }
+  &_info {
+    padding-top: 10px;
+    font-size: 12px;
+    &_title {
+      color: #afafaf;
+    }
+    &_value {
+      padding-left: 0.5rem;
+      font-weight: bold;
+    }
+  }
+}
+// echartBox样式
+.echartBox {
+  &_left {
+    width: calc(100% - 300px - 10px);
+    height: 100%;
+  }
+  &_right {
+    margin-left: 10px;
+    width: 300px;
+    height: 100%;
+  }
+}
+.chartDomBox {
+  position: relative;
+  width: calc(100% - 20px);
+  height: calc(100% - 41px);
+  display: flex;
+  justify-content: center;
+}
+.DoubleCarbonNews {
+  padding: 10px 0;
+  font-weight: bold;
+  color: #000;
+  cursor: pointer;
+  border-bottom: 1px solid #c9c9c9;
+  &:hover {
+    color: @primary-color;
+  }
+  & > div {
+    overflow: hidden;
+    text-overflow: ellipsis;
+    white-space: nowrap;
+  }
+  & > div:nth-child(1) {
+    width: 15%;
+  }
+  & > div:nth-child(2) {
+    height: 21px;
+    overflow: hidden;
+    width: calc(50% - 110px);
+  }
+  & > div:nth-child(3) {
+    width: 20%;
+  }
+  & > div:nth-child(4) {
+    width: 15%;
+  }
+  & > div:nth-child(5) {
+    width: 30px;
+  }
+}
+// loading样式
+.spin-content {
+  border: 1px solid #91d5ff;
+  background-color: #e6f7ff;
+  padding: 30px;
+}
+</style>

+ 199 - 165
src/components/doubleCarbon/overview/doubleCarbonOverview.vue

@@ -4,31 +4,27 @@
     @date 2023年2月8日
     @date 2023年2月8日
 -->
 -->
 <template>
 <template>
-  <div class="doubleCarbon-main-box flexColumn" v-loading="searchLoading">
+  <div class="doubleCarbon-main-box flexColumn">
+    <a-spin class="spinStyle" size="large" tip="Loading..." v-show="searchLoading"></a-spin>
     <!-- 头部搜索区域 -->
     <!-- 头部搜索区域 -->
     <div class="borderColor">
     <div class="borderColor">
       <div class="flex flex_between margin5rem">
       <div class="flex flex_between margin5rem">
         <div class="flex">
         <div class="flex">
           <div class="mr1rem">
           <div class="mr1rem">
             单位名称:
             单位名称:
-            <el-select v-model="searchParam.nameOfUnit" clearable placeholder="全部">
-              <el-option v-for="item in options.nameOfUnit" :key="item.value" :label="item.label" :value="item.value">
-              </el-option>
-            </el-select>
+            <a-select
+              style="width:200px;"
+              v-model="searchParam.nameOfUnit"
+              :allowClear="selectProps.allowClear"
+              :mode="selectProps.mode"
+              :options="options.nameOfUnit"
+              :notFoundConent="selectProps.notFoundConent"
+              :placeholder="selectProps.placeholder"
+            ></a-select>
           </div>
           </div>
           <div>
           <div>
-            时间范围:
-            <el-date-picker
-              v-model="searchParam.timeRange"
-              type="monthrange"
-              align="right"
-              unlink-panels
-              range-separator="-"
-              start-placeholder="开始时间"
-              end-placeholder="结束时间"
-              :picker-options="$constant.PICKER_OPTIONS"
-            >
-            </el-date-picker>
+            时间范围: <a-month-picker id="startTime" format="YYYY-MM" @change="changeTimeRangeS" placeholder="开始时间" />~
+            <a-month-picker id="endTime" format="YYYY-MM" @change="changeTimeRangeE" placeholder="结束时间" />
           </div>
           </div>
         </div>
         </div>
         <div>
         <div>
@@ -55,8 +51,8 @@
           </div>
           </div>
         </div>
         </div>
       </div>
       </div>
-      <div class="flex flex_around coreListBox margin5rem">
-        <el-empty v-if="coreList.length == 0" description="暂无数据"></el-empty>
+      <div class="flex flex_around coreListBox margin5rem" v-if="coreList.length == 0" style="height:120px;">
+        <a-empty></a-empty>
       </div>
       </div>
     </div>
     </div>
     <!-- 碳排放分析和碳配额构成 -->
     <!-- 碳排放分析和碳配额构成 -->
@@ -65,28 +61,33 @@
         <div class="cardTitle margin5rem">碳排放分析</div>
         <div class="cardTitle margin5rem">碳排放分析</div>
         <div class="margin5rem chartDomBox">
         <div class="margin5rem chartDomBox">
           <LineChart v-if="chartData.LineChartData" :echartData="chartData.LineChartData" />
           <LineChart v-if="chartData.LineChartData" :echartData="chartData.LineChartData" />
-          <el-empty v-else description="暂无数据"></el-empty>
+          <a-empty v-else></a-empty>
         </div>
         </div>
       </div>
       </div>
       <div class="echartBox_right borderColor">
       <div class="echartBox_right borderColor">
         <div class="cardTitle margin5rem">碳配额构成</div>
         <div class="cardTitle margin5rem">碳配额构成</div>
         <div class="margin5rem chartDomBox">
         <div class="margin5rem chartDomBox">
           <BarChart v-if="chartData.BarChartData" :echartData="chartData.BarChartData" />
           <BarChart v-if="chartData.BarChartData" :echartData="chartData.BarChartData" />
-          <el-empty v-else description="暂无数据"></el-empty>
+          <a-empty v-else></a-empty>
         </div>
         </div>
       </div>
       </div>
     </div>
     </div>
     <!-- 双碳新闻和碳排放占比 -->
     <!-- 双碳新闻和碳排放占比 -->
     <div class="flex" style="height:300px;">
     <div class="flex" style="height:300px;">
       <div class="echartBox_left borderColor">
       <div class="echartBox_left borderColor">
-        <el-dialog title="双碳新闻" :visible.sync="showModalStatus" width="60%" :before-close="onCancel">
-          <p>{{ showModalInfo.title }}</p>
-          <div class="flex flex_between">
-            <div>{{ showModalInfo.author }}</div>
-            <div>{{ showModalInfo.pushTime }}</div>
-          </div>
-          <p>{{ showModalInfo.content }}</p>
-        </el-dialog>
+        <a-modal title="双碳新闻" :visible.sync="showModalStatus" width="60%" :footer="null" @cancel="onCancel" centered>
+          <p style="font-size: 20px;font-weight:blod;color:#000;">{{ showModalInfo.title }}</p>
+          <div style="margin-bottom:10px;border-bottom: 1px solid #CCCCCC;">{{ showModalInfo.pushTime }}</div>
+          <div
+            style="max-height: calc(100vh - 300px);overflow:auto;background: rgba(10,100,100,0.05);font-size:16px;"
+            v-if="showModalInfo.content.indexOf(`<p>`) != -1"
+            v-html="showModalInfo.content"
+          ></div>
+          <p v-else style="font-size: 16px;font-weight:400;color:#000;background: rgba(10,100,100,0.05);">
+            {{ showModalInfo.content }}
+          </p>
+          <div style="margin-top:10px;border-top: 1px solid #CCCCCC;">{{ showModalInfo.author }}</div>
+        </a-modal>
         <div class="cardTitle margin5rem">双碳新闻</div>
         <div class="cardTitle margin5rem">双碳新闻</div>
         <div class="margin5rem" v-if="DoubleCarbonNewsInfoList.length > 0" style="overflow-y:auto;height: calc(100% - 53px);">
         <div class="margin5rem" v-if="DoubleCarbonNewsInfoList.length > 0" style="overflow-y:auto;height: calc(100% - 53px);">
           <div
           <div
@@ -96,7 +97,8 @@
             @click="showModal(item)"
             @click="showModal(item)"
           >
           >
             <div>{{ item.title }}</div>
             <div>{{ item.title }}</div>
-            <div>{{ item.content }}</div>
+            <div v-if="item.content.indexOf(`<p>`) != -1" v-html="item.content"></div>
+            <div v-else>{{ item.content }}</div>
             <div>{{ item.author }}</div>
             <div>{{ item.author }}</div>
             <div>{{ item.pushTime }}</div>
             <div>{{ item.pushTime }}</div>
             <div>>></div>
             <div>>></div>
@@ -107,14 +109,14 @@
           v-if="DoubleCarbonNewsInfoList.length == 0"
           v-if="DoubleCarbonNewsInfoList.length == 0"
           style="overflow-y:auto;height: calc(100% - 53px);"
           style="overflow-y:auto;height: calc(100% - 53px);"
         >
         >
-          <el-empty description="暂无数据"></el-empty>
+          <a-empty></a-empty>
         </div>
         </div>
       </div>
       </div>
       <div class="echartBox_right borderColor">
       <div class="echartBox_right borderColor">
         <div class="cardTitle margin5rem">碳排放占比</div>
         <div class="cardTitle margin5rem">碳排放占比</div>
         <div class="margin5rem chartDomBox">
         <div class="margin5rem chartDomBox">
           <PieChart v-if="chartData.PieChartData" :echartData="chartData.PieChartData" />
           <PieChart v-if="chartData.PieChartData" :echartData="chartData.PieChartData" />
-          <el-empty v-else description="暂无数据"></el-empty>
+          <a-empty v-else></a-empty>
         </div>
         </div>
       </div>
       </div>
     </div>
     </div>
@@ -125,6 +127,8 @@
 import LineChart from "../../echart/LineChart.vue";
 import LineChart from "../../echart/LineChart.vue";
 import BarChart from "../../echart/BarChart.vue";
 import BarChart from "../../echart/BarChart.vue";
 import PieChart from "../../echart/PieChart.vue";
 import PieChart from "../../echart/PieChart.vue";
+// 模拟数据
+import  AnalogData from "../AnalogData.js"
 export default {
 export default {
   components: {
   components: {
     LineChart,
     LineChart,
@@ -133,16 +137,26 @@ export default {
   },
   },
   data() {
   data() {
     return {
     return {
-      // loading状态
-      searchLoading: true,
+      // selectProps配置
+      selectProps: {
+        allowClear: true, // 支持清除
+        mode: "default", // 模式['default'|'multiple'|'tags'|'combobox']
+        notFoundConent: "Not Found", // 当下拉列表为空时显示的内容
+        placeholder: "请选择", // 选择框默认文字 string|slot
+        showArrow: true, // 是否显示下拉小箭头
+        size: "large" // 选择框大小['large'|'small']
+      },
       // 单位名称option可选值
       // 单位名称option可选值
       options: {
       options: {
-        nameOfUnit: []
+        nameOfUnit: [] // options 数据,如果设置则不需要手动构造 selectOption 节点
       },
       },
+      // loading状态
+      searchLoading: true,
       // 头部搜索条件中绑定值
       // 头部搜索条件中绑定值
+      monthArr: [],
       searchParam: {
       searchParam: {
-        nameOfUnit: "",
-        timeRange: []
+        nameOfUnit: undefined,
+        timeRange: [undefined, undefined]
       },
       },
       // 头部核心指标循环显示数据
       // 头部核心指标循环显示数据
       coreList: [],
       coreList: [],
@@ -165,138 +179,117 @@ export default {
   mounted() {
   mounted() {
     // 页面初始化
     // 页面初始化
     this.init();
     this.init();
+    //默认是当年的1月到12月
+    this.defaulTimeRangeS();
+    this.defaulTimeRangeE();
   },
   },
   methods: {
   methods: {
-    init() {
-      // 初始化加载[单位名称列表、核心指标、碳排放分析、碳配额构成、双碳新闻、碳排放占比]
-      setTimeout(() => {
-        this.options.nameOfUnit = [
-          { value: "1", label: "中讯邮电咨询设计院有限公司" },
-          { value: "2", label: "北京电信规划设计院" }
-        ];
-        this.chartData = {
-          BarChartData: {
-            yAxisData: ["中讯", "北京规划院", "郑分", "广分", "上分"],
-            seriesData: {
-              碳配额存量: [120, 132, 101, 134, 90, 230, 210],
-              碳配额消耗: [220, 182, 191, 234, 290, 330, 310]
-            }
-          },
-          LineChartData: {
-            xAxisData: ["1月", "2月", "3月", "4月", "5月", "6月", "7月"],
-            seriesData: {
-              中讯: [120, 132, 101, 134, 90, 230, 210],
-              北京规划院: [220, 182, 191, 234, 290, 330, 310],
-              郑分: [150, 232, 201, 154, 190, 330, 410],
-              广分: [320, 332, 301, 334, 390, 330, 320],
-              上分: [820, 932, 901, 934, 1290, 1330, 1320]
-            }
-          },
-          PieChartData: {
-            seriesName: "碳排放占比",
-            seriesData: [
-              { value: 1048, name: "汽油" },
-              { value: 735, name: "柴油" },
-              { value: 580, name: "天然气" },
-              { value: 484, name: "热力" },
-              { value: 300, name: "电力" },
-              { value: 199, name: "其他" }
-            ]
-          }
-        };
-        this.DoubleCarbonNewsInfoList = [
-          {
-            title: "【减碳小妙招】",
-            content: "xxxxxxxxxxxxxxxxxxxxxxx",
-            author: "中讯邮电设计院-张三",
-            pushTime: "2021-08-09"
-          },
-          {
-            title: "【减碳小妙招】",
-            content: "xxxxxxxxxxxxxxxxxxxxxxx",
-            author: "中讯邮电设计院-张三",
-            pushTime: "2021-08-09"
-          },
-          {
-            title: "【减碳小妙招】",
-            content: "xxxxxxxxxxxxxxxxxxxxxxx",
-            author: "中讯邮电设计院-张三",
-            pushTime: "2021-08-09"
-          }
-        ];
-        this.coreList = [
-          {
-            title: "碳配额存量",
-            value: "60%",
-            leavel: 1
-          },
-          {
-            title: "碳排放存量",
-            value: 500,
-            unit: "tCO2e",
-            info: {
-              title: "同比上升",
-              leavel: 3,
-              value: "0.4%"
-            }
-          },
-          {
-            title: "单位面积碳排放",
-            value: 380,
-            unit: "tCO2e/m²",
-            info: {
-              title: "同比上升",
-              leavel: 3,
-              value: "0.4%"
-            }
-          },
-          {
-            title: "人均碳排放",
-            value: 80,
-            unit: "tCO2e/人",
-            info: {
-              title: "同比上升",
-              leavel: 3,
-              value: "0.4%"
-            }
-          },
-          {
-            title: "光伏减排",
-            value: 40,
-            unit: "tCO2e",
-            info: {
-              title: "同比上升",
-              leavel: 3,
-              value: "0.4%"
-            }
-          },
-          {
-            title: "值得关注",
-            value: "减少2辆车出行一周"
-          }
-        ];
-        this.searchLoading = false;
-      }, 1000);
+    // 开始时间初始化
+    defaulTimeRangeS() {
+      this.searchParam.timeRange[0] = this.$moment()
+        .startOf("year")
+        .format("YYYY-MM-DD 00:00:00");
+      document.getElementById("startTime").querySelector("input").value = this.$moment()
+        .startOf("year")
+        .format("YYYY-MM");
+    },
+    // 结束时间初始化
+    defaulTimeRangeE() {
+      this.searchParam.timeRange[1] = this.$moment()
+        .endOf("year")
+        .format("YYYY-MM-DD 23:59:59");
+      document.getElementById("endTime").querySelector("input").value = this.$moment()
+        .endOf("year")
+        .format("YYYY-MM");
+    },
+    // 修改开始时间时
+    changeTimeRangeS(date, dateStr) {
+      // 修改时间前判断是否合理
+      if (this.searchParam.timeRange[1]) {
+        if (
+          this.$moment(this.$moment(dateStr, "YYYY-MM").format("YYYY-MM-DD 00:00:00")).diff(
+            this.$moment(this.searchParam.timeRange[1])
+          ) > 0
+        ) {
+          this.$message.error("开始时间不能大于结束时间!请重新选择!");
+          setTimeout(() => {
+            document.getElementById("startTime").querySelector("input").value = this.$moment()
+              .startOf("year")
+              .format("YYYY-MM");
+          }, 10);
+        }
+      }
+      if (dateStr) {
+        this.searchParam.timeRange[0] = this.$moment(dateStr, "YYYY-MM").format("YYYY-MM-DD 00:00:00");
+      } else {
+        this.searchParam.timeRange[0] = undefined;
+      }
+    },
+    // 修改结束时间时
+    changeTimeRangeE(date, dateStr) {
+      // 修改时间前判断是否合理
+      if (this.searchParam.timeRange[0]) {
+        if (
+          this.$moment(this.searchParam.timeRange[0]).diff(
+            this.$moment(
+              this.$moment(dateStr, "YYYY-MM")
+                .endOf("month")
+                .format("YYYY-MM-DD 23:59:59")
+            )
+          ) > 0
+        ) {
+          this.$message.error("结束时间不能小于开始时间!请重新选择!");
+          setTimeout(() => {
+            document.getElementById("endTime").querySelector("input").value = this.$moment()
+              .endOf("year")
+              .format("YYYY-MM");
+          }, 10);
+        }
+      }
+      if (dateStr) {
+        this.searchParam.timeRange[1] = this.$moment(dateStr, "YYYY-MM")
+          .endOf("month")
+          .format("YYYY-MM-DD 23:59:59");
+      } else {
+        this.searchParam.timeRange[1] = undefined;
+      }
     },
     },
     // 查询事件
     // 查询事件
     search() {
     search() {
+      // 时间范围条件不合理判断
+      if (this.searchParam.timeRange[0] || this.searchParam.timeRange[1]) {
+        if (!this.searchParam.timeRange[0]) {
+          this.$message.info("请选择开始时间!");
+          return;
+        } else if (!this.searchParam.timeRange[1]) {
+          this.$message.info("请选择结束时间!");
+          return;
+        }
+      }
       this.searchLoading = true;
       this.searchLoading = true;
-      /* dayjs舍弃,使用moment.js */
-      // console.log(
-      //   "查询条件:",
-      //   this.searchParam.nameOfUnit,
-      //   this.searchParam.timeRange[0] ? this.$dayjs(this.searchParam.timeRange[0]).format("YYYY-MM-DD 00:00:00") : "",
-      //   this.searchParam.timeRange[1] ? this.$dayjs(this.searchParam.timeRange[1]).format("YYYY-MM-DD 00:00:00") : ""
-      // );
+      console.log("查询条件:", this.searchParam.nameOfUnit, this.searchParam.timeRange[0], this.searchParam.timeRange[1]);
       setTimeout(() => {
       setTimeout(() => {
         this.searchLoading = false;
         this.searchLoading = false;
       }, 1000);
       }, 1000);
     },
     },
     // 重置事件
     // 重置事件
     reset() {
     reset() {
+      document.getElementById("startTime").querySelector("input").value = this.$moment()
+        .startOf("year")
+        .format("YYYY-MM");
+      document.getElementById("endTime").querySelector("input").value = this.$moment()
+        .endOf("year")
+        .format("YYYY-MM");
       this.searchParam = {
       this.searchParam = {
-        nameOfUnit: "",
-        timeRange: []
+        nameOfUnit: undefined,
+        timeRange: [
+          this.$moment()
+            .startOf("year")
+            .format("YYYY-MM-DD 00:00:00"),
+          this.$moment()
+            .endOf("year")
+            .format("YYYY-MM-DD 23:59:59")
+        ]
       };
       };
     },
     },
     // 弹窗显示事件
     // 弹窗显示事件
@@ -306,11 +299,17 @@ export default {
     },
     },
     // 弹窗隐藏事件
     // 弹窗隐藏事件
     onCancel() {
     onCancel() {
-      this.$confirm("确认关闭?")
-        .then(_ => {
-          this.showModalStatus = false;
-        })
-        .catch(_ => {});
+      this.showModalStatus = false;
+    },
+    init() {
+      // 初始化加载[单位名称列表、核心指标、碳排放分析、碳配额构成、碳排放占比、双碳新闻]
+      setTimeout(() => {
+        this.options.nameOfUnit = AnalogData.optionsNameOfUnit;
+        this.coreList = AnalogData.core_List;
+        this.chartData = AnalogData.CHART_DATA;
+        this.DoubleCarbonNewsInfoList = AnalogData.doubleCarbonNewsInfoList;
+        this.searchLoading = false;
+      }, 1000);
     }
     }
   }
   }
 };
 };
@@ -320,9 +319,8 @@ export default {
 // 复用样式
 // 复用样式
 .flexColumn {
 .flexColumn {
   display: flex;
   display: flex;
-  overflow-y: auto;
   flex-direction: column;
   flex-direction: column;
-  flex-wrap: wrap;
+  flex-wrap: nowrap;
 }
 }
 .flex {
 .flex {
   display: flex;
   display: flex;
@@ -362,8 +360,9 @@ export default {
 }
 }
 // 页面主题样式
 // 页面主题样式
 .doubleCarbon-main-box {
 .doubleCarbon-main-box {
-  width: calc(100% - 16px);
-  height: calc(100% - 16px);
+  position: relative;
+  width: 100%;
+  height: 100%;
   & * {
   & * {
     user-select: none;
     user-select: none;
     -moz-user-select: none;
     -moz-user-select: none;
@@ -380,6 +379,13 @@ export default {
     border-radius: 2px;
     border-radius: 2px;
     margin-bottom: 10px;
     margin-bottom: 10px;
   }
   }
+  .spinStyle {
+    position: absolute;
+    width: 100%;
+    height: 100%;
+    background: rgba(255, 255, 255, 0.75);
+    z-index: 2;
+  }
 }
 }
 // 头部搜索框和(重置、查询)按钮之间的间距样式
 // 头部搜索框和(重置、查询)按钮之间的间距样式
 .mr1rem {
 .mr1rem {
@@ -477,5 +483,33 @@ export default {
   &:hover {
   &:hover {
     color: @primary-color;
     color: @primary-color;
   }
   }
+  & > div {
+    overflow: hidden;
+    text-overflow: ellipsis;
+    white-space: nowrap;
+  }
+  & > div:nth-child(1) {
+    width: 15%;
+  }
+  & > div:nth-child(2) {
+    height: 21px;
+    overflow: hidden;
+    width: calc(50% - 110px);
+  }
+  & > div:nth-child(3) {
+    width: 20%;
+  }
+  & > div:nth-child(4) {
+    width: 15%;
+  }
+  & > div:nth-child(5) {
+    width: 30px;
+  }
+}
+// loading样式
+.spin-content {
+  border: 1px solid #91d5ff;
+  background-color: #e6f7ff;
+  padding: 30px;
 }
 }
 </style>
 </style>

+ 456 - 3
src/components/doubleCarbon/print/doubleCarbonPrint.vue

@@ -4,11 +4,464 @@
     @date 2023年2月8日
     @date 2023年2月8日
 -->
 -->
 <template>
 <template>
-  <div>文印排放页面类似双碳概览页面</div>
+  <div class="doubleCarbon-main-box flexColumn">
+    <a-spin class="spinStyle" size="large" tip="Loading..." v-show="searchLoading"></a-spin>
+    <!-- 头部搜索区域 -->
+    <div class="borderColor">
+      <div class="flex flex_between margin5rem">
+        <div class="flex">
+          <div class="mr1rem">
+            单位名称:
+            <a-select
+              style="width:200px;"
+              v-model="searchParam.nameOfUnit"
+              :allowClear="selectProps.allowClear"
+              :mode="selectProps.mode"
+              :options="options.nameOfUnit"
+              :notFoundConent="selectProps.notFoundConent"
+              :placeholder="selectProps.placeholder"
+            ></a-select>
+          </div>
+          <div>
+            时间范围: <a-month-picker id="startTime" format="YYYY-MM" @change="changeTimeRangeS" placeholder="开始时间" />~
+            <a-month-picker id="endTime" format="YYYY-MM" @change="changeTimeRangeE" placeholder="结束时间" />
+          </div>
+        </div>
+        <div>
+          <a-button class="mr1rem" @click="reset">重置</a-button>
+          <a-button type="primary" @click="search">查询</a-button>
+        </div>
+      </div>
+      <div class="cardTitle margin5rem">核心指标</div>
+      <div v-if="coreList.length > 0" class="flex flex_around coreListBox margin5rem">
+        <div v-for="(item, index) in coreList" :key="'coreList' + index">
+          <div class="core_title">{{ item.title }}</div>
+          <div class="core_value">
+            {{ item.value ? item.value : "--" }}<span class="core_unit">{{ item.unit ? item.unit : "" }}</span
+            ><span class="core_leavel" v-if="item.leavel" :style="{ color: $constant.COLOR_LEAVEL[item.leavel] }">!</span>
+          </div>
+          <div v-if="item.info" class="core_info">
+            <span class="core_info_title">{{ item.info.title }}</span
+            ><span class="core_info_value" :style="{ color: $constant.COLOR_LEAVEL[item.info.leavel] }"
+              >{{ item.info.value
+              }}<i
+                v-if="item.info.leavel && (item.info.leavel == 1 || item.info.leavel == 3)"
+                :class="item.info.leavel == 3 ? 'el-icon-caret-top' : 'el-icon-caret-bottom'"
+            /></span>
+          </div>
+        </div>
+      </div>
+      <div class="flex flex_around coreListBox margin5rem" v-if="coreList.length == 0" style="height:120px;">
+        <a-empty></a-empty>
+      </div>
+    </div>
+    <!-- 碳排放分析和碳配额构成 -->
+    <div class="flex" style="height:400px;">
+      <div class="echartBox_left borderColor">
+        <div class="cardTitle margin5rem">碳排放分析</div>
+        <div class="margin5rem chartDomBox">
+          <LineChart v-if="chartData.LineChartData" :echartData="chartData.LineChartData" />
+          <a-empty v-else></a-empty>
+        </div>
+      </div>
+      <div class="echartBox_right borderColor">
+        <div class="cardTitle margin5rem">碳配额构成</div>
+        <div class="margin5rem chartDomBox">
+          <BarChart v-if="chartData.BarChartData" :echartData="chartData.BarChartData" />
+          <a-empty v-else></a-empty>
+        </div>
+      </div>
+    </div>
+  </div>
 </template>
 </template>
 
 
 <script>
 <script>
-export default {};
+import LineChart from "../../echart/LineChart.vue";
+import BarChart from "../../echart/BarChart.vue";
+import PieChart from "../../echart/PieChart.vue";
+// 模拟数据
+import  AnalogData from "../AnalogData.js"
+export default {
+  components: {
+    LineChart,
+    BarChart,
+    PieChart
+  },
+  data() {
+    return {
+      // selectProps配置
+      selectProps: {
+        allowClear: true, // 支持清除
+        mode: "default", // 模式['default'|'multiple'|'tags'|'combobox']
+        notFoundConent: "Not Found", // 当下拉列表为空时显示的内容
+        placeholder: "请选择", // 选择框默认文字 string|slot
+        showArrow: true, // 是否显示下拉小箭头
+        size: "large" // 选择框大小['large'|'small']
+      },
+      // 单位名称option可选值
+      options: {
+        nameOfUnit: [] // options 数据,如果设置则不需要手动构造 selectOption 节点
+      },
+      // loading状态
+      searchLoading: true,
+      // 头部搜索条件中绑定值
+      monthArr: [],
+      searchParam: {
+        nameOfUnit: undefined,
+        timeRange: [undefined, undefined]
+      },
+      // 头部核心指标循环显示数据
+      coreList: [],
+      // 双碳新闻模拟数据
+      DoubleCarbonNewsInfoList: [],
+      // 双碳新闻弹窗打开状态
+      showModalStatus: false,
+      // 弹窗暂存数据对象
+      showModalInfo: {
+        title: "--",
+        content: "--",
+        author: "--",
+        pushTime: "--"
+      },
+      // chart暂存数据对象
+      chartData: []
+    };
+  },
+  created() {},
+  mounted() {
+    // 页面初始化
+    this.init();
+    //默认是当年的1月到12月
+    this.defaulTimeRangeS();
+    this.defaulTimeRangeE();
+  },
+  methods: {
+    // 开始时间初始化
+    defaulTimeRangeS() {
+      this.searchParam.timeRange[0] = this.$moment()
+        .startOf("year")
+        .format("YYYY-MM-DD 00:00:00");
+      document.getElementById("startTime").querySelector("input").value = this.$moment()
+        .startOf("year")
+        .format("YYYY-MM");
+    },
+    // 结束时间初始化
+    defaulTimeRangeE() {
+      this.searchParam.timeRange[1] = this.$moment()
+        .endOf("year")
+        .format("YYYY-MM-DD 23:59:59");
+      document.getElementById("endTime").querySelector("input").value = this.$moment()
+        .endOf("year")
+        .format("YYYY-MM");
+    },
+    // 修改开始时间时
+    changeTimeRangeS(date, dateStr) {
+      // 修改时间前判断是否合理
+      if (this.searchParam.timeRange[1]) {
+        if (
+          this.$moment(this.$moment(dateStr, "YYYY-MM").format("YYYY-MM-DD 00:00:00")).diff(
+            this.$moment(this.searchParam.timeRange[1])
+          ) > 0
+        ) {
+          this.$message.error("开始时间不能大于结束时间!请重新选择!");
+          setTimeout(() => {
+            document.getElementById("startTime").querySelector("input").value = this.$moment()
+              .startOf("year")
+              .format("YYYY-MM");
+          }, 10);
+        }
+      }
+      if (dateStr) {
+        this.searchParam.timeRange[0] = this.$moment(dateStr, "YYYY-MM").format("YYYY-MM-DD 00:00:00");
+      } else {
+        this.searchParam.timeRange[0] = undefined;
+      }
+    },
+    // 修改结束时间时
+    changeTimeRangeE(date, dateStr) {
+      // 修改时间前判断是否合理
+      if (this.searchParam.timeRange[0]) {
+        if (
+          this.$moment(this.searchParam.timeRange[0]).diff(
+            this.$moment(
+              this.$moment(dateStr, "YYYY-MM")
+                .endOf("month")
+                .format("YYYY-MM-DD 23:59:59")
+            )
+          ) > 0
+        ) {
+          this.$message.error("结束时间不能小于开始时间!请重新选择!");
+          setTimeout(() => {
+            document.getElementById("endTime").querySelector("input").value = this.$moment()
+              .endOf("year")
+              .format("YYYY-MM");
+          }, 10);
+        }
+      }
+      if (dateStr) {
+        this.searchParam.timeRange[1] = this.$moment(dateStr, "YYYY-MM")
+          .endOf("month")
+          .format("YYYY-MM-DD 23:59:59");
+      } else {
+        this.searchParam.timeRange[1] = undefined;
+      }
+    },
+    // 查询事件
+    search() {
+      // 时间范围条件不合理判断
+      if (this.searchParam.timeRange[0] || this.searchParam.timeRange[1]) {
+        if (!this.searchParam.timeRange[0]) {
+          this.$message.info("请选择开始时间!");
+          return;
+        } else if (!this.searchParam.timeRange[1]) {
+          this.$message.info("请选择结束时间!");
+          return;
+        }
+      }
+      this.searchLoading = true;
+      console.log("查询条件:", this.searchParam.nameOfUnit, this.searchParam.timeRange[0], this.searchParam.timeRange[1]);
+      setTimeout(() => {
+        this.searchLoading = false;
+      }, 1000);
+    },
+    // 重置事件
+    reset() {
+      document.getElementById("startTime").querySelector("input").value = this.$moment()
+        .startOf("year")
+        .format("YYYY-MM");
+      document.getElementById("endTime").querySelector("input").value = this.$moment()
+        .endOf("year")
+        .format("YYYY-MM");
+      this.searchParam = {
+        nameOfUnit: undefined,
+        timeRange: [
+          this.$moment()
+            .startOf("year")
+            .format("YYYY-MM-DD 00:00:00"),
+          this.$moment()
+            .endOf("year")
+            .format("YYYY-MM-DD 23:59:59")
+        ]
+      };
+    },
+    // 弹窗显示事件
+    showModal(item) {
+      this.showModalStatus = true;
+      this.showModalInfo = item;
+    },
+    // 弹窗隐藏事件
+    onCancel() {
+      this.showModalStatus = false;
+    },
+    init() {
+      // 初始化加载[单位名称列表、核心指标、碳排放分析、碳配额构成、碳排放占比、双碳新闻]
+      setTimeout(() => {
+        this.options.nameOfUnit = AnalogData.optionsNameOfUnit;
+        this.coreList = AnalogData.core_List;
+        this.chartData = AnalogData.CHART_DATA;
+        this.DoubleCarbonNewsInfoList = AnalogData.doubleCarbonNewsInfoList;
+        this.searchLoading = false;
+      }, 1000);
+    }
+  }
+};
 </script>
 </script>
 
 
-<style lang="less" scoped></style>
+<style lang="less" scoped>
+// 复用样式
+.flexColumn {
+  display: flex;
+  flex-direction: column;
+  flex-wrap: nowrap;
+}
+.flex {
+  display: flex;
+  flex-wrap: wrap;
+  align-content: center;
+  align-items: center;
+  &_center {
+    display: flex;
+    flex-wrap: wrap;
+    align-content: center;
+    align-items: center;
+    justify-content: center;
+  }
+  &_between {
+    display: flex;
+    flex-wrap: wrap;
+    align-content: center;
+    align-items: center;
+    justify-content: space-between;
+  }
+  &_around {
+    display: flex;
+    flex-wrap: wrap;
+    align-content: center;
+    align-items: center;
+    justify-content: space-around;
+  }
+}
+.borderColor {
+  border: 1px solid #e7eaf1;
+}
+.margin5rem {
+  margin: 0.5rem;
+}
+.padding5rem {
+  padding: 0.5rem;
+}
+// 页面主题样式
+.doubleCarbon-main-box {
+  position: relative;
+  width: 100%;
+  height: 100%;
+  & * {
+    user-select: none;
+    -moz-user-select: none;
+    -webkit-user-select: none;
+    -ms-user-select: none;
+    ::-webkit-scrollbar {
+      width: 0 !important;
+    }
+    -ms-overflow-style: none;
+    overflow: -moz-scrollbars-none;
+  }
+  & > div {
+    // padding: 5px 10px;
+    border-radius: 2px;
+    margin-bottom: 10px;
+  }
+  .spinStyle {
+    position: absolute;
+    width: 100%;
+    height: 100%;
+    background: rgba(255, 255, 255, 0.75);
+    z-index: 2;
+  }
+}
+// 头部搜索框和(重置、查询)按钮之间的间距样式
+.mr1rem {
+  margin-right: 1rem;
+}
+// 每个card标题的字体样式
+.cardTitle {
+  padding-left: 5px;
+  font-size: 14px;
+  font-weight: bold;
+  border-left: 5px solid @primary-color;
+}
+// 核心指标
+.coreListBox {
+  border-radius: 0.5rem;
+  background-color: rgb(233, 246, 253);
+  & > div {
+    position: relative;
+    // border-left: 1px solid #909399;
+    padding: 10px;
+    margin: 10px;
+    cursor: pointer;
+    border-radius: 0.5rem;
+    &:hover {
+      background-color: rgb(210, 239, 255);
+    }
+    // &::before {
+    //   content: "";
+    //   position: absolute;
+    //   left: -10px;
+    //   height: calc(100% - 20px);
+    //   width: 1px;
+    //   background: #c9c9c9;
+    // }
+  }
+}
+// 核心指标中value的样式
+.core {
+  &_title {
+    font-size: 12px;
+    padding-bottom: 10px;
+  }
+  &_leavel {
+    font-size: 16px;
+    font-weight: bold;
+  }
+  &_value {
+    font-size: 16px;
+    font-weight: 500;
+    color: #000;
+  }
+  &_unit {
+    padding-left: 0.5rem;
+    font-size: 12px;
+    font-weight: bold;
+    color: #909399;
+  }
+  &_info {
+    padding-top: 10px;
+    font-size: 12px;
+    &_title {
+      color: #afafaf;
+    }
+    &_value {
+      padding-left: 0.5rem;
+      font-weight: bold;
+    }
+  }
+}
+// echartBox样式
+.echartBox {
+  &_left {
+    width: calc(100% - 300px - 10px);
+    height: 100%;
+  }
+  &_right {
+    margin-left: 10px;
+    width: 300px;
+    height: 100%;
+  }
+}
+.chartDomBox {
+  position: relative;
+  width: calc(100% - 20px);
+  height: calc(100% - 41px);
+  display: flex;
+  justify-content: center;
+}
+.DoubleCarbonNews {
+  padding: 10px 0;
+  font-weight: bold;
+  color: #000;
+  cursor: pointer;
+  border-bottom: 1px solid #c9c9c9;
+  &:hover {
+    color: @primary-color;
+  }
+  & > div {
+    overflow: hidden;
+    text-overflow: ellipsis;
+    white-space: nowrap;
+  }
+  & > div:nth-child(1) {
+    width: 15%;
+  }
+  & > div:nth-child(2) {
+    height: 21px;
+    overflow: hidden;
+    width: calc(50% - 110px);
+  }
+  & > div:nth-child(3) {
+    width: 20%;
+  }
+  & > div:nth-child(4) {
+    width: 15%;
+  }
+  & > div:nth-child(5) {
+    width: 30px;
+  }
+}
+// loading样式
+.spin-content {
+  border: 1px solid #91d5ff;
+  background-color: #e6f7ff;
+  padding: 30px;
+}
+</style>