pyt
2025-03-26 03cd344a15bf63bf7968dc77a026c77c78c304f4
Merge branch 'master' of http://120.76.84.145:10101/gitblit/r/H5/chongzhou-screen
13个文件已修改
17个文件已删除
3个文件已添加
1660 ■■■■ 已修改文件
.gitignore 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
README.md 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
package-lock.json 69 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
package.json 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
public/favicon.ico 补丁 | 查看 | 原始文档 | blame | 历史
public/img/icons/android-chrome-192x192.png 补丁 | 查看 | 原始文档 | blame | 历史
public/img/icons/android-chrome-512x512.png 补丁 | 查看 | 原始文档 | blame | 历史
public/img/icons/android-chrome-maskable-192x192.png 补丁 | 查看 | 原始文档 | blame | 历史
public/img/icons/android-chrome-maskable-512x512.png 补丁 | 查看 | 原始文档 | blame | 历史
public/img/icons/apple-touch-icon-120x120.png 补丁 | 查看 | 原始文档 | blame | 历史
public/img/icons/apple-touch-icon-152x152.png 补丁 | 查看 | 原始文档 | blame | 历史
public/img/icons/apple-touch-icon-180x180.png 补丁 | 查看 | 原始文档 | blame | 历史
public/img/icons/apple-touch-icon-60x60.png 补丁 | 查看 | 原始文档 | blame | 历史
public/img/icons/apple-touch-icon-76x76.png 补丁 | 查看 | 原始文档 | blame | 历史
public/img/icons/apple-touch-icon.png 补丁 | 查看 | 原始文档 | blame | 历史
public/img/icons/favicon-16x16.png 补丁 | 查看 | 原始文档 | blame | 历史
public/img/icons/favicon-32x32.png 补丁 | 查看 | 原始文档 | blame | 历史
public/img/icons/msapplication-icon-144x144.png 补丁 | 查看 | 原始文档 | blame | 历史
public/img/icons/mstile-150x150.png 补丁 | 查看 | 原始文档 | blame | 历史
public/img/icons/safari-pinned-tab.svg 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
public/index.html 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
public/robots.txt 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/bg.png 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/echartsBg.png 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/unbg.png 补丁 | 查看 | 原始文档 | blame | 历史
src/components/datascreen/CenterPanel.vue 201 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/datascreen/HeaderPanel.vue 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/datascreen/RightPanel.vue 1113 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/datascreen/map.vue 117 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main.js 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/utils/map/chongzhou.json 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/utils/request.js 10 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/DataScreen.vue 100 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
.gitignore
@@ -1,6 +1,7 @@
.DS_Store
node_modules
/dist
package-lock.json
# local env files
README.md
@@ -1,4 +1,4 @@
# chongzhou-screen
# 崇州市自主安置购房信息化大数据平台
## Project setup
```
package-lock.json
@@ -1878,6 +1878,49 @@
        "webpack-merge": "^5.7.3",
        "webpack-virtual-modules": "^0.4.2",
        "whatwg-fetch": "^3.6.2"
      },
      "dependencies": {
        "@vue/vue-loader-v15": {
          "version": "npm:vue-loader@15.11.1",
          "resolved": "https://registry.npmmirror.com/vue-loader/-/vue-loader-15.11.1.tgz",
          "integrity": "sha512-0iw4VchYLePqJfJu9s62ACWUXeSqM30SQqlIftbYWM3C+jpPcEHKSPUZBLjSF9au4HTHQ/naF6OGnO3Q/qGR3Q==",
          "dev": true,
          "requires": {
            "@vue/component-compiler-utils": "^3.1.0",
            "hash-sum": "^1.0.2",
            "loader-utils": "^1.1.0",
            "vue-hot-reload-api": "^2.3.0",
            "vue-style-loader": "^4.1.0"
          },
          "dependencies": {
            "hash-sum": {
              "version": "1.0.2",
              "resolved": "https://registry.npmmirror.com/hash-sum/-/hash-sum-1.0.2.tgz",
              "integrity": "sha512-fUs4B4L+mlt8/XAtSOGMUO1TXmAelItBPtJG7CyHJfYTdDjwisntGO2JQz7oUsatOY9o68+57eziUVNw/mRHmA==",
              "dev": true
            }
          }
        },
        "json5": {
          "version": "1.0.2",
          "resolved": "https://registry.npmmirror.com/json5/-/json5-1.0.2.tgz",
          "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==",
          "dev": true,
          "requires": {
            "minimist": "^1.2.0"
          }
        },
        "loader-utils": {
          "version": "1.4.2",
          "resolved": "https://registry.npmmirror.com/loader-utils/-/loader-utils-1.4.2.tgz",
          "integrity": "sha512-I5d00Pd/jwMD2QCduo657+YM/6L3KZu++pmX9VFncxaxvHcru9jx1lBaFft+r4Mt2jK0Yhp41XlRAihzPxHNCg==",
          "dev": true,
          "requires": {
            "big.js": "^5.2.2",
            "emojis-list": "^3.0.0",
            "json5": "^1.0.1"
          }
        }
      }
    },
    "@vue/cli-shared-utils": {
@@ -2038,7 +2081,7 @@
    },
    "@vue/vue-loader-v15": {
      "version": "npm:vue-loader@15.11.1",
      "resolved": "https://registry.npmmirror.com/vue-loader/-/vue-loader-15.11.1.tgz",
      "resolved": "https://mirrors.cloud.tencent.com/npm/vue-loader/-/vue-loader-15.11.1.tgz",
      "integrity": "sha512-0iw4VchYLePqJfJu9s62ACWUXeSqM30SQqlIftbYWM3C+jpPcEHKSPUZBLjSF9au4HTHQ/naF6OGnO3Q/qGR3Q==",
      "dev": true,
      "requires": {
@@ -2051,13 +2094,13 @@
      "dependencies": {
        "hash-sum": {
          "version": "1.0.2",
          "resolved": "https://registry.npmmirror.com/hash-sum/-/hash-sum-1.0.2.tgz",
          "resolved": "https://mirrors.cloud.tencent.com/npm/hash-sum/-/hash-sum-1.0.2.tgz",
          "integrity": "sha512-fUs4B4L+mlt8/XAtSOGMUO1TXmAelItBPtJG7CyHJfYTdDjwisntGO2JQz7oUsatOY9o68+57eziUVNw/mRHmA==",
          "dev": true
        },
        "json5": {
          "version": "1.0.2",
          "resolved": "https://registry.npmmirror.com/json5/-/json5-1.0.2.tgz",
          "resolved": "https://mirrors.cloud.tencent.com/npm/json5/-/json5-1.0.2.tgz",
          "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==",
          "dev": true,
          "requires": {
@@ -2066,7 +2109,7 @@
        },
        "loader-utils": {
          "version": "1.4.2",
          "resolved": "https://registry.npmmirror.com/loader-utils/-/loader-utils-1.4.2.tgz",
          "resolved": "https://mirrors.cloud.tencent.com/npm/loader-utils/-/loader-utils-1.4.2.tgz",
          "integrity": "sha512-I5d00Pd/jwMD2QCduo657+YM/6L3KZu++pmX9VFncxaxvHcru9jx1lBaFft+r4Mt2jK0Yhp41XlRAihzPxHNCg==",
          "dev": true,
          "requires": {
@@ -2868,6 +2911,11 @@
      "resolved": "https://registry.npmmirror.com/chrome-trace-event/-/chrome-trace-event-1.0.4.tgz",
      "integrity": "sha512-rNjApaLzuwaOTjCiT8lSDdGN1APCiqkChLMJxJPWLunPAt5fy8xgU9/jNOchV84wfIxrA0lRQB7oCT8jrn/wrQ==",
      "dev": true
    },
    "claygl": {
      "version": "1.3.0",
      "resolved": "https://mirrors.cloud.tencent.com/npm/claygl/-/claygl-1.3.0.tgz",
      "integrity": "sha512-+gGtJjT6SSHD2l2yC3MCubW/sCV40tZuSs5opdtn79vFSGUgp/lH139RNEQ6Jy078/L0aV8odCw8RSrUcMfLaQ=="
    },
    "clean-css": {
      "version": "5.3.3",
@@ -3706,7 +3754,7 @@
    },
    "echarts": {
      "version": "5.6.0",
      "resolved": "https://registry.npmmirror.com/echarts/-/echarts-5.6.0.tgz",
      "resolved": "https://mirrors.cloud.tencent.com/npm/echarts/-/echarts-5.6.0.tgz",
      "integrity": "sha512-oTbVTsXfKuEhxftHqL5xprgLoc0k7uScAwtryCgWF6hPYFLRwOUHiFmHGCBKP5NPFNkDVopOieyUqYGH8Fa3kA==",
      "requires": {
        "tslib": "2.3.0",
@@ -3718,6 +3766,15 @@
          "resolved": "https://registry.npmmirror.com/tslib/-/tslib-2.3.0.tgz",
          "integrity": "sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg=="
        }
      }
    },
    "echarts-gl": {
      "version": "2.0.9",
      "resolved": "https://mirrors.cloud.tencent.com/npm/echarts-gl/-/echarts-gl-2.0.9.tgz",
      "integrity": "sha512-oKeMdkkkpJGWOzjgZUsF41DOh6cMsyrGGXimbjK2l6Xeq/dBQu4ShG2w2Dzrs/1bD27b2pLTGSaUzouY191gzA==",
      "requires": {
        "claygl": "^1.2.1",
        "zrender": "^5.1.1"
      }
    },
    "ee-first": {
@@ -8215,7 +8272,7 @@
    },
    "vue-hot-reload-api": {
      "version": "2.3.4",
      "resolved": "https://registry.npmmirror.com/vue-hot-reload-api/-/vue-hot-reload-api-2.3.4.tgz",
      "resolved": "https://mirrors.cloud.tencent.com/npm/vue-hot-reload-api/-/vue-hot-reload-api-2.3.4.tgz",
      "integrity": "sha512-BXq3jwIagosjgNVae6tkHzzIk6a8MHFtzAdwhnV5VlvPTFxDCvIttgSiHWjdGoTJvXtmRu5HacExfdarRcFhog==",
      "dev": true
    },
package.json
@@ -11,6 +11,7 @@
    "axios": "^1.8.4",
    "core-js": "^3.8.3",
    "echarts": "^5.6.0",
    "echarts-gl": "^2.0.9",
    "register-service-worker": "^1.7.2",
    "vue": "^2.6.14",
    "vue-echarts": "^7.0.3",
public/favicon.ico
Binary files differ
public/img/icons/android-chrome-192x192.png
Binary files differ
public/img/icons/android-chrome-512x512.png
Binary files differ
public/img/icons/android-chrome-maskable-192x192.png
Binary files differ
public/img/icons/android-chrome-maskable-512x512.png
Binary files differ
public/img/icons/apple-touch-icon-120x120.png
Binary files differ
public/img/icons/apple-touch-icon-152x152.png
Binary files differ
public/img/icons/apple-touch-icon-180x180.png
Binary files differ
public/img/icons/apple-touch-icon-60x60.png
Binary files differ
public/img/icons/apple-touch-icon-76x76.png
Binary files differ
public/img/icons/apple-touch-icon.png
Binary files differ
public/img/icons/favicon-16x16.png
Binary files differ
public/img/icons/favicon-32x32.png
Binary files differ
public/img/icons/msapplication-icon-144x144.png
Binary files differ
public/img/icons/mstile-150x150.png
Binary files differ
public/img/icons/safari-pinned-tab.svg
File was deleted
public/index.html
@@ -4,7 +4,7 @@
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width,initial-scale=1.0">
    <!-- <link rel="icon" href="<%= BASE_URL %>favicon.ico"> -->
    <link rel="icon" href="<%= BASE_URL %>favicon.ico">
    <title><%= htmlWebpackPlugin.options.title %></title>
  </head>
  <body>
public/robots.txt
File was deleted
src/assets/bg.png
src/assets/echartsBg.png
src/assets/unbg.png
src/components/datascreen/CenterPanel.vue
@@ -15,14 +15,16 @@
          <img src="@/assets/center-top-right.png" alt="">
          <div>
            <div class="label">本月应补偿总额(万元)</div>
            <div class="value">{{ data.monthCompensationAmount }} <span>环比</span><span class="value-change value-change-down">{{ data.monthCompensationAmountRate }}</span></div>
            <div class="value">{{ data.monthCompensationAmount }} <span>环比</span><span
                class="value-change value-change-down">{{ data.monthCompensationAmountRate }}</span></div>
          </div>
        </div>
        <div class="data-item">
          <img src="@/assets/center-top-right.png" alt="">
          <div>
            <div class="label">下月应补偿总额(万元)</div>
            <div class="value">{{ data.nextMonthCompensationAmount }} <span>环比</span><span class="value-change value-change-up">{{ data.nextMonthCompensationAmountRate }}</span></div>
            <div class="value">{{ data.nextMonthCompensationAmount }} <span>环比</span><span
                class="value-change value-change-up">{{ data.nextMonthCompensationAmountRate }}</span></div>
          </div>
        </div>
      </div>
@@ -35,7 +37,31 @@
    <!-- 中间下部数据 -->
    <div class="center-bottom panel-item">
      <div class="compensation-table">
        <div class="table-header">
          <div class="batch-number txt-center">安置批次</div>
          <div class="household-count txt-center">户主名称</div>
          <div class="people-count txt-center">安置人数</div>
          <div class="progress-wrapper txt-center">补偿阶段</div>
        </div>
        <div class="table-content">
          <div class="table-row" v-for="(item, index) in data.quarterProcessResponses" :key="index">
            <div class="batch-number text-center">{{ item.batchNumber }}</div>
            <div class="household-count text-center">{{ item.householdHead }}</div>
            <div class="people-count text-center">{{ item.currentCount }}</div>
            <div class="progress-wrapper">
              <div class="progress-bar">
                <div class="progress-fill">
                  <div class="progress-color"
                    :class="item.process <= 5 ? 'progress-yellow' : item.process <= 10&&item.process>5 ? 'progress-green' : item.process <= 15&&item.process>10 ? 'progress-blue' : 'progress-gray'">
                  </div>
                </div>
              </div>
              <div class="progress-text">{{ item.process }}/20</div>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>
@@ -59,6 +85,9 @@
        { label: '已受理', value: '2021103000001', percentage: 90 },
        { label: '已审核', value: '2021103000002', percentage: 70 },
        { label: '已完成', value: '2021103000003', percentage: 50 }
      ],
      compensationList: [
      ]
    };
  }
@@ -66,6 +95,14 @@
</script>
<style lang="less" scoped>
.pl-20 {
  padding-left: 20px;
}
.text-center {
  text-align: center;
}
.center-panel {
  position: absolute;
  left: 481px;
@@ -95,7 +132,164 @@
    height: 245px;
    background: url('@/assets/center-bottom-bg.png') no-repeat center center;
    background-size: 100% 100%;
    padding: 20px;
    .compensation-table {
      height: 100%;
      display: flex;
      flex-direction: column;
      .table-header {
        display: flex;
        align-items: center;
        color: rgba(255, 255, 255, 0.6);
        font-size: 12px;
        // margin-top: 20px;
        margin-bottom: 15px;
        >div {
          margin-right: 40px;
        }
        .batch-number {
          width: 150px;
        }
        .household-count {
          width: 80px;
          text-align: center;
        }
        .people-count {
          width: 100px;
          text-align: center;
        }
        .progress-wrapper {
          flex: 1;
          padding-right: 20px;
          padding-left: 20px;
        }
      }
      .table-content {
        // flex: 1;
        height: 174px;
        display: flex;
        overflow-y: auto;
        scrollbar-width: none;
        /* Firefox */
        -ms-overflow-style: none;
        /* IE 和 Edge */
        &::-webkit-scrollbar {
          display: none;
          /* Chrome, Safari 和 Opera */
        }
        flex-direction: column;
        justify-content: space-between;
        .table-row {
          display: flex;
          align-items: center;
          color: #fff;
          font-size: 14px;
          padding: 8px 0;
          margin-bottom: 5px;
          box-sizing: border-box;
          >div {
            margin-right: 40px;
          }
          .batch-number {
            width: 150px;
          }
          .household-count {
            width: 80px;
            text-align: center;
          }
          .people-count {
            width: 100px;
            text-align: center;
          }
          .progress-wrapper {
            flex: 1;
            display: flex;
            align-items: center;
            .progress-bar {
              flex: 1;
              height: 10px;
              background: rgba(255, 255, 255, 0.1);
              border-radius: 5px;
              margin-right: 15px;
              overflow: hidden;
              .progress-fill {
                height: 100%;
                display: flex;
                .progress-yellow {
                  height: 100%;
                  background: #FEDB65;
                }
                .progress-blue {
                  height: 100%;
                  background: #00C6FF;
                }
                .progress-green {
                  height: 100%;
                  background: rgba(0, 220, 171, 1);
                }
                .progress-gray {
                  height: 100%;
                  background: rgba(0, 242, 240, 1);
                }
              }
            }
            .progress-text {
              width: 50px;
              text-align: right;
            }
          }
          &:nth-child(2n + 1) {
            background: url('@/assets/bg.png') no-repeat center center;
            border: 2px solid;
            border-image: linear-gradient(180deg, rgba(255, 255, 255, 0), rgba(1, 10, 40, 0), rgba(255, 255, 255, 0.6)) 2 2;
          }
          &:nth-child(2n) {
            background: url('@/assets/unbg.png') no-repeat center center;
            border: 2px solid;
            border-image: linear-gradient(180deg, rgba(255, 255, 255, 0), rgba(1, 10, 40, 0), rgba(255, 255, 255, 0.2)) 2 2;
          }
          &:last-child {
            margin-bottom: 0;
          }
        }
      }
    }
  }
  .txt-center {
    text-align: center;
    font-size: 12px;
    color: #19ECFF;
    line-height: 18px;
  }
  .map-data {
@@ -109,6 +303,7 @@
    .data-item {
      display: flex;
      flex-shrink: 0;
      img {
        width: 94px;
        height: 80px;
src/components/datascreen/HeaderPanel.vue
@@ -2,8 +2,10 @@
  <div class="header">
    <!-- 左侧天气 -->
    <div class="weather">
      <!-- <img :src="require(`@/assets/weather/${weatherInfo.icon}.png`)" alt="weather" class="weather-icon"> -->
      <span class="weather-text">{{ weatherInfo.text }}</span>
      <div class="mask"></div>
      <div class="box"></div>
      <iframe allowtransparency="true" frameborder="0" width="180" height="36" scrolling="no"
        src="//tianqi.2345.com/plugin/widget/index.htm?s=3&z=3&t=1&v=0&d=3&bd=0&k=000000&f=ffffff&ltf=ffffff&htf=ffffff&q=1&e=1&a=1&c=60910&w=103&h=36&align=left" />
    </div>
    <!-- 中间标题 -->
@@ -76,15 +78,24 @@
    display: flex;
    margin-top: 61px;
    .weather-icon {
      width: 30px;
      height: 30px;
      margin-right: 10px;
    .mask {
      position: absolute;
      width: 180px;
      height: 36px;
      z-index: 1;
      filter: alpha(opacity=0);
      opacity: 0;
      background: #040A56
    }
    .weather-text {
      color: #fff;
      font-size: 16px;
    .box {
      position: absolute;
      width: 20px;
      height: 36px;
      left: 140px;
      z-index: 1;
      background: #040A56
    }
  }
src/components/datascreen/RightPanel.vue
@@ -2,129 +2,683 @@
  <div class="right-panel">
    <!-- 右侧第一块 -->
    <div class="panel-item top-panel-item">
      <div class="box-title">本月进度值比</div>
      <div class="circle-progress">
        <!-- <v-chart class="chart" :option="circleOption" autoresize /> -->
      <div class="box-title">安置房类型占比</div>
      <div class="house-type-content">
        <div class="relative">
          <div class="cityGreenLand-charts" ref="cityGreenLandCharts"></div>
          <div class="chartBg"></div>
          <div class="chart-content">
            <div class="chart-num">{{ currentType.rate }}</div>
            <div class="chart-title">{{ currentType.type }}</div>
          </div>
          <div class="chart-black"></div>
        </div>
        <div class="right-content">
          <div class="table-header">
            <div class="header-item">数量</div>
            <div class="header-item">面积</div>
            <div class="header-item">占比</div>
          </div>
          <div class="data-list">
            <div
              class="data-item"
              :class="{ activeItem: item.type === currentType.type }"
              v-for="(item, index) in houseTypeData"
              :key="index"
              @click="changeCurrentType(item)"
            >
              <div class="item-dot" :style="{ background: item.color }"></div>
              <div class="item-name">{{ item.type }}</div>
              <div class="item-value" :style="{ color: item.color }">
                {{ item.total }}
              </div>
              <div class="item-area" :style="{ color: item.color }">
                {{ item.area }}
              </div>
              <div class="item-percent" :style="{ color: item.color }">
                {{ item.rate }}
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
    <!-- 右侧第二块 -->
    <div class="panel-item middle-panel-item">
      <div class="box-title">各季度进度值统计</div>
      <div class="bar-chart">
        <!-- <v-chart class="chart" :option="barOption" autoresize /> -->
      <div class="box-title">本月应补偿占比</div>
      <div class="compensation-content">
        <div class="circle-chart">
          <div
            ref="compensationCharts"
            id="compensationCharts"
            style="width: 100%; height: 100%"
          ></div>
          <div class="compensation-list">
            <div class="compensation-center">
              <div class="total-value">{{ (total * 1).toFixed(2) }}</div>
              <div class="total-name">总额(万元)</div>
            </div>
            <div class="compensation-item">
              <div
                class="compensation-item-name"
                v-for="item in twoEcharts"
                :key="item.name"
              >
                <div class="item-name">{{ item.amountRate }}</div>
                <div class="item-value">{{ item.type }}</div>
                <div class="item-dot" :style="{ background: item.color }"></div>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
    <!-- 右侧第三块 -->
    <div class="panel-item bottom-panel-item">
      <div class="box-title">安置房类型分布</div>
      <div class="box-title">各季度应补偿金额</div>
      <div class="pie-chart">
        <!-- <v-chart class="chart" :option="typeDistOption" autoresize /> -->
        <v-chart class="chart" :option="barOption" autoresize />
      </div>
    </div>
  </div>
</template>
<script>
import * as echarts from "echarts";
import "echarts-gl";
export default {
  name: 'RightPanel',
  name: "RightPanel",
  props: {
    data: {
      type: Object,
      default: () => {},
    },
  },
  data() {
    return {
      circleOption: {
        series: [{
          type: 'pie',
          radius: ['75%', '80%'],
          label: {
            show: false
          },
          data: [
            {
              value: 78.8,
              name: '完成率',
              itemStyle: {
                color: '#00ffff'
              }
            },
            {
              value: 21.2,
              name: '剩余',
              itemStyle: {
                color: 'rgba(0,255,255,0.2)'
              }
            }
          ]
        }]
      },
      barOption: {
      houseTypeData: [],
      currentType: {},
      total: null,
      barOption: {},
      twoEcharts: [],
      typeDistOption: {
        tooltip: {
          trigger: 'axis'
          trigger: "item",
        },
        series: [
          {
            type: "pie",
            radius: ["65%", "80%"],
            label: {
              show: false,
            },
            data: [
              { value: 40, name: "商品房" },
              { value: 30, name: "安置房" },
              { value: 30, name: "其他" },
            ],
            itemStyle: {
              color: function (params) {
                const colorList = ["#00ffff", "#7cb9e8", "rgba(0,255,255,0.5)"];
                return colorList[params.dataIndex];
              },
            },
          },
        ],
      },
    };
  },
  mounted() {
    this.$nextTick(() => {
      this.init(this.data.placementTypeResponses);
      this.initCompensationOption(this.data.monthCompensationResponses);
      this.initBarChart();
    });
  },
  methods: {
    changeCurrentType(type) {
      this.currentType = type;
    },
    initBarChart() {
      if (!this.data.quarterPayResponses || !this.data.quarterPayResponses[0])
        return;
      const sortedData = Object.entries(this.data.quarterPayResponses[0]).sort(
        (a, b) => {
          const dateA = new Date(a[0].replace("-", "/"));
          const dateB = new Date(b[0].replace("-", "/"));
          return dateA - dateB;
        }
      );
      const maxValue = Math.max(...sortedData.map((item) => item[1]));
      const yAxisMax = Math.ceil(maxValue / 100) * 100;
      this.barOption = {
        tooltip: {
          trigger: "axis",
          formatter: function (params) {
            const dataParams = params[1];
            // 获取当前柱子的颜色(取渐变色的起始色)
            let color;
            if (dataParams.dataIndex === 0) {
              color = "#FFEF00";
            } else if (dataParams.dataIndex === 1) {
              color = "#00FFC3";
            } else if (dataParams.dataIndex === 2) {
              color = "#00DBFF";
            } else {
              color = "#057BFF";
            }
            return `${dataParams.name}<br/><span style="display:inline-block;width:8px;height:8px;border-radius:50%;background-color:${color};margin-right:6px;"></span>${dataParams.value}`;
          },
          backgroundColor: "#ffffff",
          borderWidth: 1,
          textStyle: {
            color: "#333333",
            fontSize: 14,
          },
          padding: [8, 12],
        },
        grid: {
          top: "10%",
          left: "3%",
          right: "4%",
          bottom: "3%",
          containLabel: true,
        },
        xAxis: {
          type: 'category',
          data: ['2023年4月', '2023年5月', '2023年7月', '2023年10月'],
          type: "category",
          data: sortedData.map((item) => item[0]),
          axisLine: {
            lineStyle: {
              color: '#7cb9e8'
            }
              color: "rgba(30, 44, 88, 1)",
            },
          },
          axisTick: {
            show: false,
          },
          axisLabel: {
            color: '#7cb9e8'
          }
            color: "#ffffff",
            fontSize: 12,
          },
        },
        yAxis: {
          type: 'value',
          axisLine: {
            lineStyle: {
              color: '#7cb9e8'
            }
          },
          type: "value",
          max: yAxisMax,
          splitNumber: 4,
          axisLabel: {
            color: '#7cb9e8'
            color: "rgba(88, 115, 150, 1)",
            fontSize: 12,
          },
          splitLine: {
            lineStyle: {
              color: 'rgba(124,185,232,0.1)'
            }
          }
        },
        series: [{
          data: [120, 200, 150, 80],
          type: 'bar',
          itemStyle: {
            color: '#00ffff'
          }
        }]
      },
      typeDistOption: {
        tooltip: {
          trigger: 'item'
        },
        series: [{
          type: 'pie',
          radius: ['65%', '80%'],
          label: {
            show: false
              color: "rgba(30, 44, 88, 1)",
            },
          },
          data: [
            { value: 40, name: '商品房' },
            { value: 30, name: '安置房' },
            { value: 30, name: '其他' }
          ],
          itemStyle: {
            color: function(params) {
              const colorList = ['#00ffff', '#7cb9e8', 'rgba(0,255,255,0.5)'];
              return colorList[params.dataIndex];
            }
          }
        }]
        },
        series: [
          {
            type: "bar",
            barWidth: "30%",
            z: 1,
            data: Array(sortedData.length).fill(yAxisMax),
            itemStyle: {
              color: "rgba(0, 255, 255, 0.1)",
            },
          },
          {
            type: "pictorialBar",
            symbol: "roundRect",
            symbolSize: [20, 6],
            symbolRepeat: "fixed",
            symbolMargin: 1,
            symbolClip: true,
            symbolPosition: "start",
            symbolOffset: [0, 0],
            symbolBoundingData: yAxisMax,
            z: 2,
            data: sortedData.map((item, index) => ({
              value: item[1],
              itemStyle: {
                color:
                  index === 0
                    ? new this.$echarts.graphic.LinearGradient(0, 0, 0, 1, [
                        { offset: 0, color: "#FFEF00" },
                        { offset: 0.5, color: "#C86A01" },
                        { offset: 1, color: "#402303" },
                      ])
                    : index === 1
                    ? new this.$echarts.graphic.LinearGradient(0, 0, 0, 1, [
                        { offset: 0, color: "#00FFC3" },
                        { offset: 1, color: "#008570" },
                      ])
                    : index === 2
                    ? new this.$echarts.graphic.LinearGradient(0, 0, 0, 1, [
                        { offset: 0, color: "#00DBFF" },
                        { offset: 1, color: "#0093A8" },
                      ])
                    : new this.$echarts.graphic.LinearGradient(0, 0, 0, 1, [
                        { offset: 0, color: "#05DBFF" },
                        { offset: 0.5, color: "#057BFF" },
                        { offset: 1, color: "#030E3F" },
                      ]),
              },
            })),
          },
        ],
      };
    },
    init(data) {
      if (!data || data.length == 0) {
        this.houseTypeData = [];
        this.currentType = {};
        return;
      }
    };
  }
      const chartDom = this.$refs.cityGreenLandCharts;
      if (!chartDom) return;
      const myChart = echarts.init(chartDom);
      let colors = ["#286DF7ee", "#04F7FDee", "#E23AA9ee", "#FFC852ee"];
      this.houseTypeData = data.map((item, index) => {
        return {
          ...item,
          color: colors[index],
        };
      });
      this.currentType = this.houseTypeData[0];
      let xData = data.map((item) => item.type);
      let yData = data.map((item) => item.total);
      // 传入数据生成 option
      let optionsData = [];
      for (let i = 0; i < xData.length; i++) {
        optionsData.push({
          name: xData[i],
          value: yData[i],
          itemStyle: {
            color: colors[i],
          },
        });
      }
      const series = this.getPie3D(optionsData, 0.55);
      series.push({
        name: "pie2d",
        type: "pie",
        labelLine: {
          show: false,
          length: 60,
          length2: 60,
        },
        startAngle: -50,
        clockwise: false,
        radius: ["0", "0"],
        center: ["50%", "50%"],
        data: optionsData,
        itemStyle: {
          opacity: 0,
        },
      });
      let option = {
        animation: true,
        labelLine: {
          show: false,
        },
        xAxis3D: {
          min: -1,
          max: 1,
        },
        yAxis3D: {
          min: -1,
          max: 1,
        },
        zAxis3D: {
          min: -1,
          max: 1,
        },
        grid3D: {
          show: false,
          boxHeight: 1,
          bottom: "50%",
          viewControl: {
            distance: 280,
            alpha: 30,
            beta: 40,
            zoom: 40,
            rotateSensitivity: 0,
            zoomSensitivity: 0,
            panSensitivity: 0,
            autoRotate: false,
          },
        },
        series: series,
      };
      myChart.setOption(option);
      window.addEventListener("resize", () => {
        myChart.resize();
      });
    },
    getParametricEquation(
      startRatio,
      endRatio,
      isSelected,
      isHovered,
      k,
      height
    ) {
      let midRatio = (startRatio + endRatio) / 2;
      let startRadian = startRatio * Math.PI * 2;
      let endRadian = endRatio * Math.PI * 2;
      let midRadian = midRatio * Math.PI * 2;
      if (startRatio === 0 && endRatio === 1) {
        isSelected = false;
      }
      k = typeof k !== "undefined" ? k : 1 / 3;
      let offsetX = isSelected ? Math.cos(midRadian) * 0.1 : 0;
      let offsetY = isSelected ? Math.sin(midRadian) * 0.1 : 0;
      let hoverRate = isHovered ? 1.05 : 1;
      return {
        u: {
          min: -Math.PI,
          max: Math.PI * 3,
          step: Math.PI / 32,
        },
        v: {
          min: 0,
          max: Math.PI * 2,
          step: Math.PI / 20,
        },
        x: function (u, v) {
          if (u < startRadian) {
            return (
              offsetX +
              Math.cos(startRadian) * (1 + Math.cos(v) * k) * hoverRate
            );
          }
          if (u > endRadian) {
            return (
              offsetX + Math.cos(endRadian) * (1 + Math.cos(v) * k) * hoverRate
            );
          }
          return offsetX + Math.cos(u) * (1 + Math.cos(v) * k) * hoverRate;
        },
        y: function (u, v) {
          if (u < startRadian) {
            return (
              offsetY +
              Math.sin(startRadian) * (1 + Math.cos(v) * k) * hoverRate
            );
          }
          if (u > endRadian) {
            return (
              offsetY + Math.sin(endRadian) * (1 + Math.cos(v) * k) * hoverRate
            );
          }
          return offsetY + Math.sin(u) * (1 + Math.cos(v) * k) * hoverRate;
        },
        z: function (u, v) {
          if (u < -Math.PI * 0.5) {
            return Math.sin(u);
          }
          if (u > Math.PI * 2.5) {
            return Math.sin(u);
          }
          return Math.sin(v) > 0 ? 27 : -1; //柱状体高度
        },
      };
    },
    getPie3D(pieData, internalDiameterRatio) {
      let series = [];
      let sumValue = 0;
      let startValue = 0;
      let endValue = 0;
      let k =
        typeof internalDiameterRatio !== "undefined"
          ? (1 - internalDiameterRatio) / (1 + internalDiameterRatio)
          : 1 / 3;
      for (let i = 0; i < pieData.length; i++) {
        sumValue += pieData[i].value;
        let seriesItem = {
          name:
            typeof pieData[i].name === "undefined"
              ? `series${i}`
              : pieData[i].name,
          type: "surface",
          parametric: true,
          wireframe: {
            show: false,
          },
          pieData: pieData[i],
          pieStatus: {
            selected: false,
            hovered: false,
            k: k,
          },
        };
        if (typeof pieData[i].itemStyle != "undefined") {
          let itemStyle = {};
          typeof pieData[i].itemStyle.color != "undefined"
            ? (itemStyle.color = pieData[i].itemStyle.color)
            : null;
          typeof pieData[i].itemStyle.opacity != "undefined"
            ? (itemStyle.opacity = pieData[i].itemStyle.opacity)
            : null;
          seriesItem.itemStyle = itemStyle;
        }
        series.push(seriesItem);
      }
      for (let i = 0; i < series.length; i++) {
        endValue = startValue + series[i].pieData.value;
        series[i].pieData.startRatio = startValue / sumValue;
        series[i].pieData.endRatio = endValue / sumValue;
        series[i].parametricEquation = this.getParametricEquation(
          series[i].pieData.startRatio,
          series[i].pieData.endRatio,
          false,
          false,
          k,
          series[i].pieData.value
        );
        startValue = endValue;
      }
      series.push({
        name: "mouseoutSeries",
        type: "surface",
        parametric: true,
        wireframe: {
          show: false,
        },
        itemStyle: {
          opacity: 0,
          color: "#f0f",
        },
        parametricEquation: {
          u: {
            min: 0,
            max: Math.PI * 2,
            step: Math.PI / 20,
          },
          v: {
            min: 0,
            max: Math.PI,
            step: Math.PI / 20,
          },
          x: function (u, v) {
            return ((Math.sin(v) * Math.sin(u) + Math.sin(u)) / Math.PI) * 2;
          },
          y: function (u, v) {
            return ((Math.sin(v) * Math.cos(u) + Math.cos(u)) / Math.PI) * 2;
          },
          z: function (u, v) {
            return Math.cos(v) > 0 ? 0 : -20;
          },
        },
      });
      series.push({
        name: "mouseoutSeries",
        type: "surface",
        parametric: true,
        wireframe: {
          show: false,
        },
        itemStyle: {
          opacity: 0.05,
          color: "#0ff",
        },
        parametricEquation: {
          u: {
            min: 0,
            max: Math.PI * 2,
            step: Math.PI / 20,
          },
          v: {
            min: 0,
            max: Math.PI,
            step: Math.PI / 20,
          },
          x: function (u, v) {
            return ((Math.sin(v) * Math.sin(u) + Math.sin(u)) / Math.PI) * 2;
          },
          y: function (u, v) {
            return ((Math.sin(v) * Math.cos(u) + Math.cos(u)) / Math.PI) * 2;
          },
          z: function (u, v) {
            return Math.cos(v) > 0 ? -15 : -30;
          },
        },
      });
      return series;
    },
    // 随机颜色
    getRandomColor() {
      const letters = "0123456789ABCDEF";
      let color = "#";
      for (let i = 0; i < 6; i++) {
        color += letters[Math.floor(Math.random() * 16)];
      }
      return color;
    },
    initCompensationOption(data) {
      if (!data || !data.length) {
        this.twoEcharts = [];
        return;
      }
      let list = ["#00ffff", "#34D160", "#F8B551"];
      data = data.map((item, index) => {
        return {
          ...item,
          color: list[index],
        };
      });
      this.twoEcharts = data || [];
      const chartDom = this.$refs.compensationCharts;
      if (!chartDom) return;
      const chartCompensation = echarts.init(chartDom);
      let option = {
        polar: {
          radius: [50, "70%"],
          center: ["50%", "40%"],
        },
        grid: {
          left: "10%",
          bottom: "40%",
          width: "80%",
          height: "100%",
        },
        angleAxis: {
          max: 7,
          startAngle: 75,
          show: false,
          axisTick: {
            show: false,
          },
          axisLine: { show: false },
          minorSplitLine: { show: false },
        },
        radiusAxis: {
          type: "category",
          show: false,
          data: [],
          axisTick: {
            show: false,
          },
        },
        tooltip: { show: false },
        series: {
          type: "bar",
          barMaxWidth: "11px",
          showBackground: true,
          roundCap: true,
          backgroundStyle: {
            color: "rgba(255, 255, 255, 0.1)",
          },
          data: [],
          coordinateSystem: "polar",
        },
      };
      let max = 0;
      let total = 0;
      let arr = [];
      for (let i = 0; i < data.length; i++) {
        max = Math.max(max, data[i].amount);
        total += data[i].amount;
        arr.push({
          value: data[i].amount,
          itemStyle: { color: data[i].color },
        });
      }
      this.total = total;
      option.angleAxis.max = total;
      option.radiusAxis.data = data.map((item) => item.type);
      option.series.data = arr;
      chartCompensation.setOption(option);
      window.addEventListener("resize", () => {
        chartCompensation.resize();
      });
    },
  },
};
</script>
<style lang="less" scoped>
.water-eval-container {
  width: 100%;
  height: 100%;
}
.cityGreenLand-charts {
  width: 170px;
  height: 100%;
}
.right-panel {
  position: absolute;
  top: 111px;
@@ -138,35 +692,414 @@
  .top-panel-item {
    height: 268px;
    background: url('@/assets/right-top-bg.png') no-repeat center center;
    background: url("@/assets/right-middle-bg.png") no-repeat center center;
    background-size: 100% 100%;
  }
  .middle-panel-item {
    margin-top: 21px;
    height: 303px;
    background: url('@/assets/right-middle-bg.png') no-repeat center center;
    background: url("@/assets/right-middle-bg.png") no-repeat center center;
    background-size: 100% 100%;
  }
  .bottom-panel-item {
    margin-top: 21px;
    height: 335px;
    background: url('@/assets/right-bottom-bg.png') no-repeat center center;
    background: url("@/assets/right-bottom-bg.png") no-repeat center center;
    background-size: 100% 100%;
  }
  .box-title {
    font-size: 14px;
    color: #19ECFF;
    color: #19ecff;
    text-align: center;
    padding-top: 9px;
    line-height: 21px;
  }
  .house-type-content {
    height: calc(100% - 30px);
    display: flex;
    padding: 10px 13px;
    .relative {
      position: relative;
      .chartBg {
        position: absolute;
        width: 100%;
        height: 58%;
        top: 56px;
        left: 0px;
        background: url("@/assets/echartsBg.png") no-repeat center center;
        background-size: 100% 100%;
      }
      .chart-content {
        position: absolute;
        width: 100%;
        height: 100%;
        top: 0px;
        left: 0px;
        z-index: 99;
        text-align: center;
        display: flex;
        justify-content: center;
        flex-direction: column;
        align-items: center;
        .chart-num {
          height: 20px;
          font-family: "pangmenzhengdao";
          font-size: 20px;
          color: #ffffff;
          text-shadow: 0px 2px 4px #40a9ff;
        }
        .chart-title {
          font-family: PingFangSC, PingFang SC;
          font-weight: 400;
          font-size: 14px;
          color: #ffffff;
          margin-top: 23px;
          margin-bottom: 60px;
        }
      }
      .chart-black {
        position: absolute;
    left: 55px;
    top: 86px;
    height: 12%;
    width: 35%;
    background: rgba(0, 0, 0, 0.5);
    border-radius: 28px / 10px;
    padding-top: 17px;
      }
    }
    .pie-chart {
      position: relative;
      width: 45%;
      height: 100%;
      display: flex;
      align-items: center;
      &::after {
        content: "";
        position: absolute;
        bottom: 15%;
        left: 50%;
        transform: translateX(-50%);
        width: 60%;
        height: 10px;
        background: radial-gradient(
          ellipse at center,
          rgba(0, 255, 255, 0.3) 0%,
          rgba(0, 0, 0, 0) 70%
        );
        border-radius: 50%;
        filter: blur(3px);
        z-index: 0;
      }
      .center-text {
        position: absolute;
        left: 40%;
        top: 50%;
        transform: translate(-50%, -50%);
        text-align: center;
        z-index: 2;
        padding: 10px 15px;
        border-radius: 4px;
        background: rgba(0, 0, 0, 0.2);
        backdrop-filter: blur(2px);
        .percent {
          display: block;
          font-size: 28px;
          color: #fff;
          font-weight: bold;
        }
        .type {
          display: block;
          font-size: 14px;
          color: #19ecff;
          margin-top: 5px;
        }
      }
    }
    .type-list {
      flex: 1;
      margin-left: 30px;
      display: flex;
      flex-direction: column;
      justify-content: space-around;
      .type-item {
        display: grid;
        grid-template-columns: auto 1fr 1fr 1fr;
        gap: 15px;
        align-items: center;
        cursor: pointer;
        padding: 5px 10px;
        transition: all 0.3s;
        position: relative;
        &:hover {
          background: rgba(25, 236, 255, 0.1);
          border-radius: 4px;
        }
        &::before {
          content: "";
          position: absolute;
          left: 0;
          right: 0;
          bottom: -5px;
          height: 1px;
          background: linear-gradient(
            90deg,
            transparent,
            rgba(25, 236, 255, 0.2),
            transparent
          );
        }
        .dot {
          width: 8px;
          height: 8px;
          border-radius: 50%;
          margin-right: 8px;
          box-shadow: 0 0 5px rgba(255, 255, 255, 0.3);
        }
        .name {
          color: #fff;
          font-size: 14px;
        }
        .value {
          color: #00ffff;
          font-size: 14px;
          text-align: center;
        }
        .area {
          color: #00ffff;
          font-size: 14px;
          text-align: center;
        }
        .percent {
          color: #00ffff;
          font-size: 14px;
          text-align: right;
        }
      }
    }
    .right-content {
      flex: 1;
      height: 100%;
      overflow: hidden;
      display: flex;
      flex-direction: column;
      padding-top: 27px;
      .table-header {
        display: flex;
        align-items: center;
        padding: 0 19px 0px 118px;
        margin-bottom: 8px;
        .header-item {
          color: #b6d9fc;
          font-weight: 400;
          font-size: 10px;
          text-align: center;
          &:nth-child(1) {
            width: 60px;
          }
          &:nth-child(2) {
            width: 80px;
          }
          &:nth-child(3) {
            width: 60px;
            text-align: right;
          }
        }
      }
      .data-list {
        flex: 1;
        overflow-y: auto;
        // padding-right: 10px;
        &::-webkit-scrollbar {
          display: none;
        }
        .data-item {
          display: flex;
          align-items: center;
          padding: 5px 7px 5px 4px;
          position: relative;
          margin-bottom: 21px;
          cursor: pointer;
          &:not(:last-child)::after {
            content: "";
            position: absolute;
            left: 0;
            right: 0;
            bottom: 0;
            height: 1px;
            background: linear-gradient(
              90deg,
              transparent,
              rgba(25, 236, 255, 0.2),
              transparent
            );
          }
          .item-dot {
            width: 8px;
            height: 8px;
            flex-shrink: 0;
            border-radius: 50%;
            margin-right: 3px;
            box-shadow: 0 0 5px rgba(255, 255, 255, 0.3);
          }
          .item-name {
            font-family: "pangmenzhengdao";
            width: 100px;
            color: #fff;
            font-weight: 500;
            font-size: 12px;
            white-space: nowrap;
            overflow: hidden;
            text-overflow: ellipsis;
          }
          .item-value {
            width: 60px;
            color: #00ffff;
            font-size: 12px;
            text-align: center;
          }
          .item-area {
            width: 80px;
            color: #00ffff;
            font-size: 12px;
            text-align: center;
          }
          .item-percent {
            width: 60px;
            color: #00ffff;
            font-size: 12px;
            text-align: right;
          }
        }
        .activeItem {
          box-sizing: border-box;
          background: rgba(105, 192, 255, 0.12);
          border-radius: 4px;
          border: 1px solid rgba(105, 192, 255, 0.29);
        }
      }
    }
  }
  .chart {
    width: 100%;
    height: calc(100% - 35px);
    height: 100%;
  }
  .middle-panel-item {
    .compensation-content {
      height: calc(100% - 30px);
      display: flex;
      flex-direction: column;
      align-items: center;
      padding: 20px;
      .circle-chart {
        width: 100%;
        height: 260px;
        position: relative;
      }
      .compensation-list {
        position: absolute;
        bottom: 0;
        left: 0;
        width: 100%;
        height: 100%;
        display: flex;
        flex-direction: column;
        margin-top: 20px;
        padding: 0 40px 0px 40px;
        .compensation-center {
          display: flex;
          flex: 1;
          justify-content: center;
          align-items: center;
          flex-direction: column;
          .total-value {
            font-family: PangMenZhengDao;
            font-size: 28px;
            color: #ffffff;
            margin-bottom: 11px;
          }
          .total-name {
            font-family: SourceHanSansCN, SourceHanSansCN;
            font-weight: 400;
            font-size: 12px;
            color: rgba(255, 255, 255, 1);
          }
        }
        .compensation-item {
          width: 100%;
          height: 45px;
          display: flex;
          justify-content: space-between;
          align-items: center;
          .compensation-item-name {
            display: flex;
            flex-direction: column;
            align-items: center;
            justify-content: center;
            .item-name {
              font-size: 16px;
              color: #ffffff;
              margin-bottom: 5px;
              font-family: "pangmenzhengdao";
            }
            .item-value {
              font-weight: 400;
              font-size: 12px;
              color: #ffffff;
              margin-bottom: 2px;
            }
            .item-dot {
              width: 8px;
              height: 8px;
              border-radius: 50%;
            }
          }
        }
      }
    }
  }
}
</style>
.pie-chart {
  height: calc(100% - 35px);
}
</style>
src/components/datascreen/map.vue
@@ -274,67 +274,66 @@
        // 生成标记点系列的配置
        getMarkerSeries(type) {
            return {
                name: type === "blue" ? "蓝色标记" : "橙色标记",  // 系列名称
                type: "scatter",         // 散点图类型
                coordinateSystem: "geo", // 使用地理坐标系
                geoIndex: 0,            // 关联第一个geo组件
                data: this.mapPoints.filter(point => point.type === type), // 筛选对应类型的数据
                symbol: `image://${type === "blue" ? tooltipBlue : tooltipOrange}`, // 标记图标
                symbolSize: [20, 30],    // 标记大小
                symbolOffset: [0, -15],  // 标记偏移量
                z: 20,                   // 层级
                name: type === "blue" ? "蓝色标记" : "橙色标记",
                type: "scatter",
                coordinateSystem: "geo",
                geoIndex: 0,
                data: this.mapPoints.filter(point => point.type === type),
                symbol: `image://${type === "blue" ? tooltipBlue : tooltipOrange}`,
                symbolSize: MAP_CONSTANTS.MARKER.SIZE,
                symbolOffset: MAP_CONSTANTS.MARKER.OFFSET,
                z: MAP_CONSTANTS.MARKER.Z_INDEX,
                // 提示框配置
                label: {
                    show: false  // 禁用标签显示
                },
                // 修复tooltip配置
                tooltip: {
                    show: true,          // 显示提示框
                    trigger: 'item',     // 触发类型:数据项
                    backgroundColor: 'transparent', // 背景透明
                    borderWidth: 0,      // 无边框
                    padding: [0, 0, 0, 0], // 内边距
                    // 提示框位置
                    show: true,
                    trigger: 'item',
                    backgroundColor: 'transparent',
                    borderWidth: 0,
                    padding: 0,
                    className: 'map-tooltip',
                    position: function (point) {
                        // 固定偏移量
                        return [point[0] - 100, point[1] - 160];
                    },
                    // 提示框内容格式化
                    formatter: function (params) {
                        // 返回自定义HTML结构的提示框内容
                        return `<div style="
                            background: url(${tooltipBg}) no-repeat center center;
                            background-size: 100% 100%;
                            width: 211px;
                            padding-bottom: 24px;
                            display: flex;
                            flex-direction: column;
                            justify-content: center;
                            align-items: center;
                        ">
                            <div style="color: #fff; font-size: 16px; margin: 21px 0;font-weight: bold;">${params.name}</div>
                            <div style="display: flex; justify-content: space-around; width: 100%;">
                                <div style="text-align: center;">
                                    <div style="color: rgba(102, 255, 255, 1); font-size: 20px;margin-bottom: 8px;font-family: 'pangmenzhengdao';">${params.data.householdCount}</div>
                                    <div style="color: #fff; font-size: 12px;">安置户数(户)</div>
                                </div>
                                <div style="text-align: center;">
                                    <div style="color: rgba(102, 255, 255, 1); font-size: 20px;margin-bottom: 8px;font-family: 'pangmenzhengdao';">${params.data.personCount}</div>
                                    <div style="color: #fff; font-size: 12px;">安置人数(人)</div>
                        const { name, data } = params;
                        return `
                            <div style="
                                background: url(${tooltipBg}) no-repeat center center;
                                background-size: 100% 100%;
                                width: 211px;
                                padding: 20px 0;
                                display: flex;
                                flex-direction: column;
                                align-items: center;
                            ">
                                <div style="color: #fff; font-size: 16px; margin-bottom: 16px; font-weight: bold;">${name}</div>
                                <div style="display: flex; justify-content: space-around; width: 100%; padding: 0 21px;">
                                    <div style="text-align: center;">
                                        <div style="color: #66ffff; font-size: 20px; font-family: 'pangmenzhengdao'; margin-bottom: 8px;">${data.householdCount}</div>
                                        <div style="color: #fff; font-size: 12px;">安置户数(户)</div>
                                    </div>
                                    <div style="text-align: center;">
                                        <div style="color: #66ffff; font-size: 20px; font-family: 'pangmenzhengdao'; margin-bottom: 8px;">${data.personCount}</div>
                                        <div style="color: #fff; font-size: 12px;">安置人数(人)</div>
                                    </div>
                                </div>
                            </div>
                        </div>`;
                        `;
                    }
                },
                // 标签配置
                label: {
                    show: false         // 不显示标签
                },
                // 高亮效果配置
                emphasis: {
                    scale: true,        // 启用缩放效果
                    scaleSize: 1.2,     // 放大比例
                    scale: true,
                    scaleSize: 1.2,
                    itemStyle: {
                        shadowBlur: 10,  // 阴影模糊大小
                        shadowColor: type === "blue" ? '#00eaff' : '#ff8e3a' // 根据类型设置阴影颜色
                        shadowBlur: 10,
                        shadowColor: type === "blue" ? MAP_CONSTANTS.SHADOW.COLOR : '#ff8e3a'
                    }
                }
            };
@@ -456,14 +455,12 @@
                            disabled: false,   // 启用高亮效果
                            label: {
                                show: true,       // 显示标签
                                textStyle: {      // 标签文字样式
                                    color: "#fff",
                                    fontSize: 10,
                                    fontWeight: "normal",
                                    opacity: 1
                                }
                                color: "#fff",    // 文字颜色
                                fontSize: 10,     // 文字大小
                                fontWeight: "normal", // 文字粗细
                                opacity: 1        // 不透明度
                            },
                            itemStyle: {      // 高亮时的样式
                            itemStyle: {
                                areaColor: {  // 区域填充,保持与正常状态相同的背景
                                    type: 'pattern',
                                    image: mapBg,
@@ -494,12 +491,10 @@
                        // 标签配置
                        label: {
                            show: true,       // 显示标签
                            textStyle: {      // 标签文字样式
                                color: "#fff",
                                fontSize: 10,
                                fontWeight: "normal",
                                opacity: 1
                            }
                            color: "#fff",    // 文字颜色
                            fontSize: 10,     // 文字大小
                            fontWeight: "normal", // 文字粗细
                            opacity: 1        // 不透明度
                        },
                        tooltip: {
src/main.js
@@ -4,7 +4,9 @@
import router from './router'
import store from './store'
import * as echarts from 'echarts';
import 'echarts-gl'
import ECharts from 'vue-echarts';
import '@/assets/font/font.css'
import 'echarts/lib/chart/pie';
import 'echarts/lib/chart/bar';
import 'echarts/lib/component/tooltip';
src/utils/map/chongzhou.json
@@ -4509,7 +4509,7 @@
        {
            "type": "Feature",
            "properties": {
                "name": "三江镇",
                "name": "三江街道",
                "BM_Time": "2025-03-21 16:00:33",
                "BM_Area": 48138721.767335184,
                "adcode": "510184101000"
@@ -5137,7 +5137,7 @@
        {
            "type": "Feature",
            "properties": {
                "name": "江源镇",
                "name": "江源街道",
                "BM_Time": "2025-03-21 16:00:33",
                "BM_Area": 26895967.457464911,
                "adcode": "510184102000"
@@ -5773,7 +5773,7 @@
        {
            "type": "Feature",
            "properties": {
                "name": "羊马镇",
                "name": "羊马街道",
                "BM_Time": "2025-03-21 16:00:33",
                "BM_Area": 42733001.744975172,
                "adcode": "510184103000"
@@ -14613,7 +14613,7 @@
        {
            "type": "Feature",
            "properties": {
                "name": "大划镇",
                "name": "大划街道",
                "BM_Time": "2025-03-21 16:00:34",
                "BM_Area": 18404576.628594477,
                "adcode": "510184116000"
src/utils/request.js
@@ -11,11 +11,11 @@
// 请求拦截
service.interceptors.request.use(
  config => {
    const token = localStorage.getItem('token') || 'Bearer eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJhZG1pbiIsImxvZ2luX3VzZXJfa2V5IjoiZWFjMDUyNWMtZjk4Mi00OWY3LWI5MTYtOTZlMmM0NzNjYjg1In0.zUMiAEKOfuto9pX4r3sKK7rfRDm-YRfSERi-0bRoBnvZKB7mApG2SdYPKRIiB6IyX7Fwz7o8IC9D3Svl2v5gMw'
    if (token) {
      // 添加token到请求头
      config.headers['Authorization'] = token
    }
    // const token = localStorage.getItem('token') || 'Bearer eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJhZG1pbiIsImxvZ2luX3VzZXJfa2V5IjoiZWFjMDUyNWMtZjk4Mi00OWY3LWI5MTYtOTZlMmM0NzNjYjg1In0.zUMiAEKOfuto9pX4r3sKK7rfRDm-YRfSERi-0bRoBnvZKB7mApG2SdYPKRIiB6IyX7Fwz7o8IC9D3Svl2v5gMw'
    // if (token) {
    //   // 添加token到请求头
    //   config.headers['Authorization'] = token
    // }
    if (config.method == 'get') {
      if (!config.params) config.params = {};
      config.params = {
src/views/DataScreen.vue
@@ -1,9 +1,15 @@
<template>
  <div class="data-screen" :style="screenStyle">
    <div v-if="!isFullscreen" class="fullscreen-mask" @click="enterFullScreen">
      <div class="fullscreen-tip">
        <i class="el-icon-full-screen"></i>
        <p>点击进入全屏模式</p>
      </div>
    </div>
    <header-panel />
    <left-panel v-if="!loading" :data="data" />
    <center-panel v-if="!loading" :data="data" />
    <right-panel />
    <right-panel v-if="!loading" :data="data" />
  </div>
</template>
@@ -31,24 +37,84 @@
        transformOrigin: 'left top'
      },
      data: {},
      loading: true
      loading: true,
      isFullscreen: false,
      timer: null
    };
  },
  created() {
    this.handleResize();
    getData().then(res => {
      this.data = res.data;
      this.loading = false;
    });
    this.timer = setInterval(() => {
      getData().then(res => {
        this.data = res.data;
        this.loading = false;
      });
    }, 10000);
  },
  mounted() {
    window.addEventListener('resize', this.handleResize);
    document.addEventListener('fullscreenchange', this.handleFullscreenChange);
    document.addEventListener('webkitfullscreenchange', this.handleFullscreenChange);
    document.addEventListener('mozfullscreenchange', this.handleFullscreenChange);
    document.addEventListener('MSFullscreenChange', this.handleFullscreenChange);
  },
  beforeDestroy() {
    window.removeEventListener('resize', this.handleResize);
    document.removeEventListener('fullscreenchange', this.handleFullscreenChange);
    document.removeEventListener('webkitfullscreenchange', this.handleFullscreenChange);
    document.removeEventListener('mozfullscreenchange', this.handleFullscreenChange);
    document.removeEventListener('MSFullscreenChange', this.handleFullscreenChange);
    this.exitFullScreen();
    clearInterval(this.timer);
  },
  methods: {
    handleResize() {
      this.screenStyle.transform = `scale(${window.innerWidth / 1920})`;
      const widthScale = window.innerWidth / 1920;
      const heightScale = window.innerHeight / 1080;
      const scale = Math.min(widthScale, heightScale);
      this.screenStyle.transform = `scale(${scale})`;
    },
    handleFullscreenChange() {
      this.isFullscreen = document.fullscreenElement ||
        document.webkitFullscreenElement ||
        document.mozFullScreenElement ||
        document.msFullscreenElement;
    },
    enterFullScreen() {
      const element = document.documentElement;
      try {
        if (element.requestFullscreen) {
          element.requestFullscreen();
        } else if (element.webkitRequestFullscreen) {
          element.webkitRequestFullscreen();
        } else if (element.mozRequestFullScreen) {
          element.mozRequestFullScreen();
        } else if (element.msRequestFullscreen) {
          element.msRequestFullscreen();
        }
      } catch (error) {
        console.error('全屏请求失败:', error);
      }
    },
    exitFullScreen() {
      const element = document;
      try {
        if (element.exitFullscreen) {
          element.exitFullscreen();
        } else if (element.webkitExitFullscreen) {
          element.webkitExitFullscreen();
        } else if (element.mozCancelFullScreen) {
          element.mozCancelFullScreen();
        } else if (element.msExitFullscreen) {
          element.msExitFullscreen();
        }
      } catch (error) {
        console.error('退出全屏失败:', error);
      }
    }
  }
};
@@ -62,5 +128,33 @@
  overflow: hidden;
  background: url('@/assets/背景色.png') no-repeat center center;
  background-size: 100% 100%;
  .fullscreen-mask {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    background: rgba(0, 0, 0, 0.8);
    z-index: 9999;
    display: flex;
    justify-content: center;
    align-items: center;
    cursor: pointer;
    .fullscreen-tip {
      text-align: center;
      color: #fff;
      i {
        font-size: 48px;
        margin-bottom: 16px;
      }
      p {
        font-size: 24px;
      }
    }
  }
}
</style>