odc.xiaohui
2024-03-01 f92f2762f6c7ccaffc7e0047c2903e52c127b585
Merge remote-tracking branch 'origin/master'
8个文件已修改
358 ■■■■■ 已修改文件
package-lock.json 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
package.json 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main.ts 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/daoAnOffice/right/analysis/index.vue 243 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/daoAnOffice/right/danger/imageSwiper.vue 13 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/daoAnOffice/right/danger/index.vue 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/daoAnOffice/right/publicize/index.vue 88 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/index/index.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
package-lock.json
@@ -19,6 +19,7 @@
        "mockjs": "^1.1.0",
        "pinia": "^2.1.6",
        "swiper": "^11.0.7",
        "viewerjs": "^1.11.6",
        "vue": "^3.3.4",
        "vue-echarts": "^6.6.1",
        "vue-router": "^4.2.5"
@@ -3562,6 +3563,11 @@
        "spdx-expression-parse": "^3.0.0"
      }
    },
    "node_modules/viewerjs": {
      "version": "1.11.6",
      "resolved": "https://registry.npmjs.org/viewerjs/-/viewerjs-1.11.6.tgz",
      "integrity": "sha512-TlhdSp2oEOLFXvEp4psKaeTjR5zBjTRcM/sHUN8PkV1UWuY8HKC8n7GaVdW5Xqnwdr/F1OmzLik1QwDjI4w/nw=="
    },
    "node_modules/vite": {
      "version": "4.4.11",
      "resolved": "https://registry.npmjs.org/vite/-/vite-4.4.11.tgz",
package.json
@@ -21,6 +21,7 @@
    "mockjs": "^1.1.0",
    "pinia": "^2.1.6",
    "swiper": "^11.0.7",
    "viewerjs": "^1.11.6",
    "vue": "^3.3.4",
    "vue-echarts": "^6.6.1",
    "vue-router": "^4.2.5"
src/main.ts
@@ -7,6 +7,7 @@
import '@/assets/css/main.scss'
import '@/assets/css/tailwind.css'
import 'swiper/swiper-bundle.css';
import 'viewerjs/dist/viewer.css';
import {registerEcharts} from "@/plugins/echarts"
//不使用mock 请注释掉
src/views/daoAnOffice/right/analysis/index.vue
@@ -3,7 +3,8 @@
  <RightTitle title="交通安全形势研判分析">
    <template #top>
      <div class="select-container flex">
        <div class="item whitespace-no-wrap cursor-pointer" v-for="item in selectItems" :key="item.itemIndex">
        <div class="item whitespace-no-wrap cursor-pointer" :class="{'select-active': item.isActive}" v-for="item in selectItems" :key="item.itemIndex"
          @click="changeChart(item)">
          {{ item.name }}
        </div>
      </div>
@@ -11,6 +12,11 @@
    <template #content>
      <div class="charts-container">
        <div id="analysisChart" ref="analysisChart"></div>
        <div class="type-select-container" v-show="isShowSelect">
          <el-select v-model="typeValue" class="select-style" @change="setConfig">
            <el-option v-for="item in testData1" :key="item.name" :label="item.name" :value="item.name" />
          </el-select>
        </div>
      </div>
    </template>
  </RightTitle>
@@ -20,14 +26,24 @@
import RightTitle from "@/components/right-title";
import * as echarts from 'echarts';
import { ref, onMounted } from 'vue';
// dom示例
// dom
const analysisChart = ref(null);
const echartRef = ref(null);
// echart实例
let echartObject = null;
// type选择
const typeValue = ref('');
// 是否显示下拉框
const isShowSelect = ref(true);
const selectItems = ref([
  { itemIndex: 1, name: '时间统计', isActive: false },
  { itemIndex: 2, name: '街道统计', isActive: true },
  { itemIndex: 1, name: '时间统计', isActive: true },
  { itemIndex: 2, name: '街道统计', isActive: false },
]);
const testData = ref([
@@ -43,11 +59,18 @@
]);
const testData1 = ref([
  {name: '都江堰市', '2023-01': 1000, '2023-02': 2000, '2023-03': 12132},
])
  { name: '都江堰市', state: { '2023-1': 1000, '2023-2': 2000, '2023-3': 1233 }, state2: { '2023-1': 12312, '2023-2': 23123, '2023-3': 2111 } },
  { name: '奎光塔街道', state: { '2023-1': 1000, '2023-2': 6000, '2023-3': 1233 }, state2: { '2023-1': 12312, '2023-2': 23123, '2023-3': 2111 } },
  { name: '蒲阳街道', state: { '2023-1': 1000, '2023-2': 2000, '2023-3': 1233 }, state2: { '2023-1': 12312, '2023-2': 23123, '2023-3': 2111 } },
  { name: '聚源镇', state: { '2023-1': 1000, '2023-2': 8000, '2023-3': 12233 }, state2: { '2023-1': 12312, '2023-2': 23123, '2023-3': 2111 } },
  { name: '银杏街道', state: { '2023-1': 1000, '2023-2': 2000, '2023-3': 1233 }, state2: { '2023-1': 12312, '2023-2': 23123, '2023-3': 2111 } },
  { name: '石羊镇', state: { '2023-1': 1000, '2023-2': 2000, '2023-3': 12313 }, state2: { '2023-1': 12312, '2023-2': 23123, '2023-3': 2111 } },
]);
let acitveData = ref(testData1.value[0]);
const echartsConfig = {
// 圆柱图表
const barConfig = ref({
  legend: {
    right: '0',
    icon: 'circle',
@@ -90,8 +113,6 @@
  },
  xAxis: { type: 'category', axisTick: false },
  yAxis: {},
  // Declare several bar series, each will be mapped
  // to a column of dataset.source by default.
  series: [
    {
      type: 'bar',
@@ -160,122 +181,105 @@
      },
    },
  ]
});
// line配置
const lineConfig = ref(null);
// 图表更换
const changeChart = (selectItem) => {
  selectItems.value.map(item => item.isActive = false);
  selectItem.isActive = true;
  if (selectItem.itemIndex == 1) {
    echartObject.setOption(lineConfig.value, true);
    isShowSelect.value = true;
  } else {
    echartObject.setOption(barConfig.value, true);
    isShowSelect.value = false;
  }
}
const echartsLineConfig = {
  legend: {
    right: '0',
    icon: 'circle',
    textStyle: {
      color: 'rgba(77, 118, 176, 1)'
// 配置数据
const setConfig = () => {
  acitveData.value = testData1.value.find((item) => item.name === typeValue.value);
  lineConfig.value = {
    legend: {
      right: '12%',
      icon: 'circle',
      textStyle: {
        color: 'rgba(77, 118, 176, 1)'
      },
      data: [
        {
          name: '酒驾',
          itemStyle: {
            color: 'rgba(207, 178, 73, 1)'
          }
        },
        {
          name: '其他',
          itemStyle: {
            color: 'rgba(43, 176, 109, 1)'
          }
        },
      ],
    },
    data: [
    tooltip: {
      show: true,
      trigger: 'axis',
      axisPointer: {
        type: 'shadow',
      }
    },
    grid: {
      left: 0,
      right: 0,
      bottom: 0,
      top: '15%',
      containLabel: true
    },
    xAxis: {
      type: 'category',
      data: Object.keys(acitveData.value.state)
    },
    yAxis: {
      type: 'value'
    },
    series: [
      {
        name: '酒驾',
        data: Object.entries(acitveData.value.state).map(([key, value]) => value),
        type: 'line',
        smooth: true,
        itemStyle: {
          color: 'rgba(207, 178, 73, 1)'
        }
      },
      {
        name: '其他',
        data: Object.entries(acitveData.value.state2).map(([key, value]) => value),
        type: 'line',
        smooth: true,
        itemStyle: {
          color: 'rgba(43, 176, 109, 1)'
        }
      },
      }
    ]
  },
  tooltip: {},
  grid: {
    left: 0,
    right: 0,
    bottom: 0,
    top: '15%',
    containLabel: true
  },
  dataset: {
    dimensions: ['name', 'state1', 'state2', 'state3'],
    source: testData.value
  },
  xAxis: { type: 'category', axisTick: false },
  yAxis: {},
  // Declare several bar series, each will be mapped
  // to a column of dataset.source by default.
  series: [
    {
      type: 'bar',
      name: '醉驾',
      barWidth: 13,
      barGap: '50%',
      label: {
        show: true, // 显示标签
        position: 'top', // 标签位置
        color: 'rgba(0, 168, 217, 1)', // 标签颜色
        fontSize: 10,
      },
      itemStyle: {
        // 设置渐变色
        color: new echarts.graphic.LinearGradient(
          0, 1, 0, 0,
          [
            { offset: 0, color: 'rgba(14, 32, 54, 1)' },    // 0% 处的颜色
            { offset: 1, color: 'rgba(0, 168, 217, 1)' }     // 100% 处的颜色
          ]
        )
      },
    },
    {
      type: 'bar',
      name: '酒驾',
      barWidth: 13,
      barGap: '50%',
      label: {
        show: true, // 显示标签
        position: 'top', // 标签位置
        color: 'rgba(207, 178, 73, 1)', // 标签颜色
        fontSize: 10,
      },
      itemStyle: {
        // 设置渐变色
        color: new echarts.graphic.LinearGradient(
          0, 1, 0, 0,
          [
            { offset: 0, color: 'rgba(14, 31, 53, 1)' },    // 0% 处的颜色
            { offset: 1, color: 'rgba(207, 178, 73, 1)' }     // 100% 处的颜色
          ]
        )
      },
    },
    {
      type: 'bar',
      name: '其他',
      barWidth: 13,
      barGap: '50%',
      label: {
        show: true, // 显示标签
        position: 'top', // 标签位置
        color: 'rgba(43, 176, 109, 1)', // 标签颜色
        fontSize: 10,
      },
      itemStyle: {
        // 设置渐变色
        color: new echarts.graphic.LinearGradient(
          0, 1, 0, 0,
          [
            { offset: 0, color: 'rgba(14, 31, 53, 1)' },    // 0% 处的颜色
            { offset: 1, color: 'rgba(43, 176, 109, 1)' }     // 100% 处的颜色
          ]
        )
      },
    },
  ]
  }
  echartObject.setOption(lineConfig.value, true);
}
// 挂载
onMounted(() => {
  echartRef.value = echarts.init(analysisChart.value);
  echartRef.value.setOption(echartsConfig);
  echartObject = echarts.init(analysisChart.value);
  typeValue.value = testData1.value[0].name;
  setConfig();
})
</script>
@@ -291,8 +295,11 @@
  background: rgba(67, 102, 155, 0.4);
  border: 1px solid rgba(47, 91, 157, 0.8);
  flex-shrink: 0;
  color: #5B83BD;
}
.select-active {
 color: #fff;
}
.item:last-child {
  margin-right: 0;
}
@@ -303,6 +310,15 @@
  padding: 20px;
  background-color: rgba(17, 34, 58, 0.6);
  border: 1px solid rgba(47, 91, 157, 0.8);
  position: relative;
}
.type-select-container {
  position: absolute;
  right: 20px;
  top: 14px;
  width: 120px;
  height: 23px;
}
#analysisChart {
@@ -310,4 +326,15 @@
  height: 100%;
  box-sizing: border-box;
}
::v-deep .el-input.el-input--suffix {
  .el-input__wrapper {
    background: rgba(67, 102, 155, 0.4) !important;
    border: 1px solid rgba(47, 91, 157, 0.8);
  }
  .el-input__inner {
    color: #4481DD;
  }
}
</style>
src/views/daoAnOffice/right/danger/imageSwiper.vue
@@ -2,9 +2,9 @@
  <div class="swiper_button mr-1" @click="prevSwiper">
    <img :src="leftIcon" class="">
  </div>
  <Swiper :slides-per-view="3" :space-between="18" class="image_swiper" @swiper="setSwiper">
    <SwiperSlide v-for="(slide, index) in imageList" :key="index" class="image_slide">
      <img :src="slide" class="item_img">
  <Swiper :slides-per-view="3" :space-between="18" class="image_swiper" @swiper="setSwiper" >
    <SwiperSlide v-for="(slide, index) in imageList" :key="index" class="image_slide" >
      <img :src="slide" class="item_img" @click="imageClick">
    </SwiperSlide>
  </Swiper>
@@ -14,12 +14,14 @@
</template>
<script setup>
import Viewer from 'viewerjs';
import { Swiper, SwiperSlide } from 'swiper/vue';
import leftIcon from '@/assets/img/icon/arrow_left.png';
import rightIcon from '@/assets/img/icon/arrow_right.png';
import { defineProps,ref } from 'vue';
const imgView = null;
const swiperRef = ref(null);
const props = defineProps({
  imageList: {
@@ -36,6 +38,10 @@
 const nextSwiper = () => {
  swiperRef.value.slideNext();
 }
 const imageClick = (event) => {
  new Viewer(event.target);
 }
</script>
@@ -55,6 +61,7 @@
  display: block;
  height: 100%;
  object-fit: fill;
  cursor: pointer;
}
.swiper_button {
src/views/daoAnOffice/right/danger/index.vue
@@ -31,8 +31,8 @@
const selectItems = ref([
  { itemIndex: 1, name: '安全隐患', isActive: false },
  { itemIndex: 2, name: '数据统计', isActive: true },
  { itemIndex: 1, name: '安全隐患', isActive: true },
  { itemIndex: 2, name: '数据统计', isActive: false },
]);
src/views/daoAnOffice/right/publicize/index.vue
@@ -5,14 +5,15 @@
  <RightTitle title="交通宣传">
    <template #top>
      <div class="select-container flex">
        <div class="item whitespace-no-wrap cursor-pointer" v-for="item in selectItems" :key="item.itemIndex">
        <div class="item whitespace-no-wrap cursor-pointer" :class="{ 'select-active': item.isActive }"
          v-for="item in selectItems" :key="item.itemIndex" @click="changeSelect(item)">
          {{ item.name }}
        </div>
      </div>
    </template>
    <template #content>
      <div class="content-container flex flex-wrap justify-between content-between">
        <div class="content-item" v-for="item in contentList" :key="item.itemIndex">
        <div class="content-item" v-for="item in contentList" :key="item.itemIndex" @click="openVideo(item)">
          <div class="content-wrapper">
            <div class="content-video-info">
              <img :src="item.image" class="video-cover">
@@ -30,18 +31,28 @@
      </div>
    </template>
  </RightTitle>
  <div class="video-container" v-show="isShowVideo">
    <div class="video-wrapper">
      <video :src="testVideo" ref="videoDom" class="video-player" controls></video>
      <div class="close-btn flex justify-center items-center" @click="closeVideo">X</div>
    </div>
  </div>
</template>
<script setup lang="ts">
<script setup>
import testImage from '@/assets/img/test_img/道安办.png';
import RightTitle from "@/components/right-title";
import { ref } from 'vue';
// 测试视频
const testVideo = 'https://www.w3schools.com/html/movie.mp4';
const isShowVideo = ref(false);
const videoDom = ref(null);
const selectItems = ref([
  { itemIndex: 1, name: '交通宣传', isActive: false },
  { itemIndex: 2, name: '交通事故', isActive: true },
  { itemIndex: 1, name: '交通宣传', isActive: true },
  { itemIndex: 2, name: '交通事故', isActive: false },
]);
const contentList = ref([
@@ -83,6 +94,22 @@
  },
]);
const changeSelect = (selectItem) => {
  selectItems.value.map(item => item.isActive = false);
  selectItem.isActive = true;
}
const openVideo = () => {
  isShowVideo.value = true;
  videoDom.value.play();
}
const closeVideo = () => {
  isShowVideo.value = false;
  videoDom.value.pause();
}
</script>
<style scoped lang="scss">
@@ -97,6 +124,11 @@
  background: rgba(67, 102, 155, 0.4);
  border: 1px solid rgba(47, 91, 157, 0.8);
  flex-shrink: 0;
  color: #5B83BD;
}
.select-active {
  color: #fff;
}
.item:last-child {
@@ -110,7 +142,7 @@
  background-color: rgba(17, 34, 58, 0.6);
  border: 1px solid rgba(47, 91, 157, 0.8);
  padding: 22px 20px;
}
.content-item {
@@ -119,9 +151,6 @@
  cursor: pointer;
  // margin-bottom: 24px;
}
// .content-item:last-child  {
//   margin-bottom: 0px;
// }
.content-video-info {
  width: 100%;
@@ -139,15 +168,54 @@
  font-size: 45px;
  opacity: 0.7;
}
.video-cover {
  width: 100%;
  height: 100%;
  object-fit: fill;
}
.content-video-name {
  text-align: center;
  margin-top: 16px;
  font-size: 12px;
  color: rgba(91, 131, 189, 1);
}
.video-container {
  position: fixed;
  z-index: 99999;
  width: 100%;
  height: 100%;
  top: 0;
  left: 0;
  .video-wrapper {
    position: absolute;
    width: 70%;
    height: 80%;
    left: 50%;
    top: 50%;
    transform: translate(-50%, -50%);
    background-color: rgba(0, 0, 0, 0.9);
  }
  .video-player {
    width: 100%;
    height: 100%;
  }
}
.close-btn {
  position: absolute;
  right: -80px;
  top: -10px;
  width: 40px;
  height: 40px;
  border: 2px solid #fff;
  border-radius: 50%;
  font-size: 18px;
  cursor: pointer;
}
</style>
src/views/index/index.vue
@@ -10,7 +10,7 @@
import RightTop1 from "./right-top2.vue";
import RightCenter from "./right-center.vue";
import RightBottom from "./right-bottom.vue";
import chart2 from "./chart2.vue";
// import chart2 from "./chart2.vue";
import BorderBox13 from "@/components/datav/border-box-13";
const config = {
  header: ['<span style="color:#42C3E8;font-size: 16px">排名</span>', '<span style="color:#42C3E8;font-size: 16px">行政区划</span>','<span style="color:#42C3E8;font-size: 16px">数值</span>'],