first commit

This commit is contained in:
PC-202306242200\Administrator
2026-03-28 23:13:45 +08:00
commit 83623886d3
85 changed files with 137729 additions and 0 deletions

18
src/App.vue Normal file
View File

@@ -0,0 +1,18 @@
<script setup>
import autofit from 'autofit.js'
import Screen from '@/views/screen/index.vue'
autofit.init({
dh: 1080,
dw: 1920,
el: "body",
resize: true
})
</script>
<template>
<Screen></Screen>
</template>
<style scoped>
@import './style.css';
</style>

39
src/api/index.js Normal file
View File

@@ -0,0 +1,39 @@
// src/utils/request.js
import axios from 'axios';
import { ElMessage } from 'element-plus' // 引入Element Plus消息组件如果使用Element UI
// 创建 axios 实例
const service = axios.create({
baseURL: import.meta.env.VITE_BASE_API || '', // 后端 API 基础路径
timeout: 5000 // 请求超时时间
});
// 请求拦截器
service.interceptors.request.use(
(config) => {
// 在发送请求之前做一些操作,比如添加 token
const token = localStorage.getItem('token');
if (token) {
config.headers['Authorization'] = `Bearer ${token}`;
}
return config;
},
(error) => {
// 请求错误处理
return Promise.reject(error);
}
);
// 响应拦截器
service.interceptors.response.use(
(response) => {
const res = response.data;
return res;
},
(error) => {
// ElMessage.error(error.message || '请求失败');
return Promise.reject(error);
}
);
export default service;

BIN
src/assets/bei.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 674 KiB

29674
src/assets/china.json Normal file

File diff suppressed because it is too large Load Diff

103310
src/assets/chinaProvince.json Normal file

File diff suppressed because it is too large Load Diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

BIN
src/assets/img/-s-bg_.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

BIN
src/assets/img/1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 595 B

BIN
src/assets/img/2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 323 B

BIN
src/assets/img/order1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.4 KiB

BIN
src/assets/img/order2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

BIN
src/assets/img/order3.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

BIN
src/assets/img/pageBg.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 289 KiB

BIN
src/assets/img/ssssss.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

BIN
src/assets/img/sssssss.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

BIN
src/assets/img/top.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.8 KiB

BIN
src/assets/img/xieyou.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

BIN
src/assets/img/xiezuo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.1 KiB

BIN
src/assets/img/标题.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 155 KiB

BIN
src/assets/img/框@2x.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 289 KiB

BIN
src/assets/s.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 176 KiB

1
src/assets/vue.svg Normal file
View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="37.07" height="36" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 198"><path fill="#41B883" d="M204.8 0H256L128 220.8L0 0h97.92L128 51.2L157.44 0h47.36Z"></path><path fill="#41B883" d="m0 0l128 220.8L256 0h-51.2L128 132.48L50.56 0H0Z"></path><path fill="#35495E" d="M50.56 0L128 133.12L204.8 0h-47.36L128 51.2L97.92 0H50.56Z"></path></svg>

After

Width:  |  Height:  |  Size: 496 B

BIN
src/assets/标题.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 124 KiB

10
src/layout/index.vue Normal file
View File

@@ -0,0 +1,10 @@
<script setup>
</script>
<template>
</template>
<style scoped>
</style>

10
src/main.js Normal file
View File

@@ -0,0 +1,10 @@
import { createApp } from 'vue'
import './style.css'
import App from './App.vue'
import ElementPlus from 'element-plus';
import 'element-plus/dist/index.css'; // 引入 Element Plus 样式
const app = createApp(App);
app.use(ElementPlus); // 全局注册 Element Plus
app.mount('#app');

96
src/style.css Normal file
View File

@@ -0,0 +1,96 @@
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
html,
body,
#app {
margin: 0;
padding: 0;
height: 100%;
}
:root {
font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif;
line-height: 1.5;
font-weight: 400;
color-scheme: light dark;
color: rgba(255, 255, 255, 0.87);
background-color: #242424;
font-synthesis: none;
text-rendering: optimizeLegibility;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
a {
font-weight: 500;
color: #646cff;
text-decoration: inherit;
}
a:hover {
color: #535bf2;
}
body {
margin: 0;
padding: 0;
}
h1 {
font-size: 3.2em;
line-height: 1.1;
}
button {
border-radius: 8px;
border: 1px solid transparent;
padding: 0.6em 1.2em;
font-size: 1em;
font-weight: 500;
font-family: inherit;
background-color: #1a1a1a;
cursor: pointer;
transition: border-color 0.25s;
}
button:hover {
border-color: #646cff;
}
button:focus,
button:focus-visible {
outline: 4px auto -webkit-focus-ring-color;
}
.card {
padding: 2em;
}
#app {
}
@media (prefers-color-scheme: light) {
:root {
color: #213547;
background-color: #ffffff;
}
a:hover {
color: #747bff;
}
button {
background-color: #f9f9f9;
}
}
.flex {
display: flex;
align-items: center;
}

View File

@@ -0,0 +1,494 @@
<script setup>
import Api from '@/api/index';
import * as echarts from 'echarts';
import chinaJons from "@/assets/china.json"
import chinaProvinceJson from "@/assets/chinaProvince.json"
import { onMounted, reactive, ref } from 'vue'
import { ScrollBoard as DvScrollBoard, } from '@kjgl77/datav-vue3'
import TableHeader from './tableHeader.vue';
let list = reactive([])
const config = reactive({
header: ['城市', '充电站编号', '消费金额', '整体使用率', '综合排名'],
data: [],
headerBGC: "#062855",
oddRowBGC: "rgba(0,67,92,0.5)",
evenRowBGC: "#012A58",
index: false,
align: ['center', 'center', 'center', 'center', 'center', 'center'],
})
let count = ref({
yearAmount: [],
yearCount: []
})
onMounted(() => {
infoGet()
setInterval(() => {
infoGet()
}, 10000)
})
function infoGet() {
Api.get('/station/list').then((res) => {
res.sort((a, b) => b.amount - a.amount);
var data = []
res.map((item, index) => {
if (index < 5) {
data.push([item.cityName, item.stationNo, item.amount, `${item.useRate}%`, index + 1])
}
})
config.data = data
})
Api.get('/cityStats/list').then((res) => {
init(res)
})
Api('/orderStats/total').then((res) => {
res.yearAmount = String(res.yearAmount).split('')
res.yearCount = String(res.yearCount).split('')
// count.value = res
count.value = {
...count.value,
...res
}
// console.log(res, 'resresres');
})
Api('/deviceStats/total').then((res) => {
count.value = {
...count.value,
...res
}
})
}
function init(data) {
var mapName = 'china';
var option = null
function convertData(data) {
var res = [];
res = data.map((item, index) => {
return {
name: item.cityName,
value: item.latlng.split(',').concat(item.gunNum)
}
})
return res;
}
echarts.registerMap('china', chinaJons);
echarts.registerMap('chinaProvince', chinaProvinceJson);
option = {
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'shadow',
},
},
grid: {
// show: true,
right: '10%',
top: 5,
bottom: '10%',
left: '10%',
},
geo: [
{
map: mapName,
zlevel: -1,
zoom: 1.0,
silent: true,
layoutCenter: ['50%', '50%'],
layoutSize: '100%',
roam: false,
itemStyle: {
normal: {
borderColor: 'rgba(192,245,249,.8)',
borderWidth: 3,
shadowColor: '#6FFDFF',
shadowOffsetY: 0,
shadowBlur: 10,
areaColor: 'rgba(29,85,139,0)',
},
},
label: {
normal: {
//静态的时候展示样式
show: false, //是否显示地图省份得名称
textStyle: {
color: '#fff',
fontSize: 12,
fontFamily: 'Arial',
},
},
emphasis: {
//动态展示的样式
show: false,
color: '#fff',
},
},
},
{
show: true,
map: mapName,
zoom: 1.0,
layoutCenter: ['50%', '50%'],
layoutSize: '100%',
label: {
normal: {
//静态的时候展示样式
show: false, //是否显示地图省份得名称
textStyle: {
color: '#fff',
fontSize: 12,
fontFamily: 'Arial',
},
},
emphasis: {
//动态展示的样式
color: '#fff',
},
},
blur: {
label: { show: true, color: '#000' },
},
roam: false, // 是否开启鼠标滚轮缩放
itemStyle: {
normal: {
label: {
show: true,
color: '#fff',
},
color: '#fff',
borderColor: '#32CBE0',
borderWidth: 1.5,
areaColor: 'rgba(0,0,0,0)',
},
emphasis: {
label: {
show: true,
color: '#fff',
},
borderWidth: 3,
borderColor: 'rgba(255, 230, 175,0.8)',
shadowColor: 'rgba(255, 230, 175,0.5)',
shadowBlur: 30,
textStyle: {
color: '#fff',
fontSize: 12,
backgroundColor: 'transparent',
},
areaColor: new echarts.graphic.LinearGradient(
0,
0,
0,
1,
[
{
offset: 0,
color: '#1cfbfe',
},
{
offset: 1,
color: '#3348e7',
},
],
false
),
},
},
},
{
type: 'map',
map: mapName,
zlevel: -2,
zoom: 1.0,
layoutCenter: ['50%', '51.4%'],
layoutSize: '100%',
roam: false,
silent: true,
itemStyle: {
normal: {
borderColor: 'rgba(35, 161, 184,0.5)',
shadowColor: 'rgba(35, 161, 184,0.8)',
shadowOffsetY: 5,
shadowBlur: 15,
areaColor: 'rgba(0,0,0,0)',
},
},
},
{
type: 'map',
map: mapName,
zlevel: -3,
zoom: 1.0,
layoutCenter: ['50%', '52.4%'],
layoutSize: '100%',
roam: false,
silent: true,
itemStyle: {
normal: {
borderColor: 'rgba(7, 65, 117,0.5)',
shadowColor: 'rgba(7, 65, 117,0.8)',
shadowOffsetY: 15,
shadowBlur: 8,
areaColor: 'rgba(0,0,0,0)',
},
},
},
],
series: [
{
type: 'map',
layoutCenter: ['50%', '50%'],
layoutSize: '100%',
roam: false,
label: {
normal: {
//静态的时候展示样式
show: false, //是否显示地图省份得名称
textStyle: {
color: '#fff',
fontSize: 12,
},
},
emphasis: {
//动态展示的样式
color: '#fff',
},
},
// geoIndex: 0,
map: 'chinaProvince',
itemStyle: {
normal: {
label: {
show: true,
color: '#fff',
},
color: '#fff',
borderColor: '#98D1DE',
borderWidth: 1.5,
"areaColor": "rgba(0,0,0,0)"
},
emphasis: {
label: {
show: true,
color: '#fff',
},
borderWidth: 3,
borderColor: 'rgba(255, 230, 175,0.8)',
shadowColor: 'rgba(255, 230, 175,0.5)',
shadowBlur: 30,
textStyle: {
color: '#fff',
fontSize: 12,
backgroundColor: 'transparent',
},
areaColor: new echarts.graphic.LinearGradient(
0,
0,
0,
1,
[
{
offset: 0,
color: '#1cfbfe',
},
{
offset: 1,
color: '#3348e7',
},
],
false
),
},
},
data: data,
},
{
name: '散点',
type: 'effectScatter',
coordinateSystem: 'geo',
data: convertData(data),
symbolSize: 10,
symbol: 'circle',
label: {
normal: {
show: false
},
emphasis: {
show: false
}
},
showEffectOn: 'render',
itemStyle: {
normal: {
color: {
type: 'radial',
x: 0.5,
y: 0.5,
r: 0.5,
colorStops: [{
offset: 0,
color: 'rgba(14,245,209,0.2)'
}, {
offset: 0.8,
color: 'rgba(14,245,209,0.2)'
}, {
offset: 1,
color: 'rgba(14,245,209,1)'
}],
global: false // 缺省为 false
},
}
},
}
],
};
var chart = echarts.init(document.getElementById('chart-panel'));
chart.setOption(option);
}
</script>
<template>
<div class="center_note">
<div class="center_note_count">
<div class="center_note_count_view">
<div class="center_note_count_view_top">
<div v-for="i in (10 - count.yearAmount.length > 0 ? 12 - count.yearAmount.length : 0)" :key="i">0
</div>
<div v-for="(item, index) in count.yearAmount" :key="index">{{ item }}</div>
</div>
<div class="center_note_count_view_bottom">
2026年即途充电站消费总金额
</div>
</div>
<div class="center_note_count_view">
<div class="center_note_count_view_top">
<div v-for="i in (8 - count.yearCount.length > 0 ? 8 - count.yearCount.length : 0)" :key="i">0</div>
<div v-for="(item, index) in count.yearCount" :key="index">{{ item }}</div>
</div>
<div class="center_note_count_view_bottom center_note_count_view_bgc">
2026年即途充电站消费订单数
</div>
</div>
</div>
<div id="chart-panel"></div>
<div></div>
<img src="/src/assets/img/-h-五公里内必有即途.png" style="position: absolute;bottom: 300px;right: 5%;" alt="">
<!-- <div style="color: #C8F1F9;position: absolute;bottom: 430px;right: 5%;">
<div class="flex">
<div>两轮桩</div>
<div>{{count.deviceTwoTotal}}</div>
</div>
<div class="flex">
<div>四轮桩</div>
<div>{{count.deviceFourTotal}}</div>
</div>
</div> -->
<div class="center_note_view">
<TableHeader title="充电桩收入排行" />
<div style="height: 15px;"></div>
<dv-scroll-board :config="config" style="width:100%;height:220px" />
</div>
</div>
</template>
<style scoped lang="scss">
.center_note {
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
align-items: center;
justify-content: space-between;
position: relative;
&_count {
width: 100%;
padding: 0 5%;
position: absolute;
top: 0;
left: 0;
display: flex;
align-items: center;
justify-content: space-between;
z-index: 999;
&_view {
&_top {
display: flex;
align-items: center;
div {
width: 31px;
height: 47px;
background: rgba(3, 12, 55, 0.5);
box-shadow: 0px 4px 30px 0px #00383F;
border: 1px solid #0D73A3;
margin-right: 10px;
font-weight: normal;
font-size: 26px;
color: #C8F1F9;
display: flex;
align-items: center;
justify-content: center;
}
}
&_bottom {
margin-top: 10px;
width: 100%;
height: 30px;
background: url("@/assets/img/ssssss.png") no-repeat;
background-size: 100% 30px;
display: flex;
align-items: center;
justify-content: center;
font-size: 15px;
color: #C8F1F9;
}
&_bgc {
background: url("@/assets/img/sssssss.png") no-repeat;
background-size: 100% 30px;
}
}
}
#chart-panel {
width: 90%;
height: 90%;
position: absolute;
top: 10%;
left: 0;
}
&_view {
width: 90%;
background-color: rgba(4, 26, 66, 0.55);
}
}
</style>

View File

@@ -0,0 +1,196 @@
<script setup>
import * as echarts from 'echarts';
import { onMounted, reactive } from 'vue'
import Api from '@/api/index';
var option = (title, data) => {
return {
color: ["#EAEA26", "#906BF9", "#FE5656", "#01E17E", "#3DD1F9", "#FFAD05"],
grid: {
left: -100,
top: 50,
bottom: 10,
right: 10,
containLabel: true
},
tooltip: {
trigger: 'item',
formatter: "{b} : {c} ({d}%)"
},
legend: {
type: "scroll",
orient: "vartical",
top: "center",
right: "15",
itemWidth: 16,
itemHeight: 8,
itemGap: 16,
textStyle: {
color: '#A3E2F4',
fontSize: 12,
fontWeight: 0
},
data: title
},
polar: {},
angleAxis: {
interval: 1,
type: 'category',
data: [],
z: 10,
axisLine: {
show: false,
lineStyle: {
color: "#0B4A6B",
width: 1,
type: "solid"
},
},
axisLabel: {
interval: 0,
show: true,
color: "#0B4A6B",
margin: 8,
fontSize: 16
},
},
radiusAxis: {
min: 40,
max: 120,
interval: 20,
axisLine: {
show: false,
lineStyle: {
color: "#0B3E5E",
width: 1,
type: "solid"
},
},
axisLabel: {
formatter: '{value} %',
show: false,
padding: [0, 0, 20, 0],
color: "#0B3E5E",
fontSize: 16
},
splitLine: {
lineStyle: {
color: "#0B3E5E",
width: 2,
type: "solid"
}
}
},
calculable: true,
series: [{
type: 'pie',
radius: ["5%", "10%"],
hoverAnimation: false,
labelLine: {
normal: {
show: false,
length: 30,
length2: 55
},
emphasis: {
show: false
}
},
data: [{
name: '',
value: 0,
itemStyle: {
normal: {
color: "#0B4A6B"
}
}
}]
}, {
type: 'pie',
radius: ["90%", "95%"],
hoverAnimation: false,
labelLine: {
normal: {
show: false,
length: 30,
length2: 55
},
emphasis: {
show: false
}
},
name: "",
data: [{
name: '',
value: 0,
itemStyle: {
normal: {
color: "#0B4A6B"
}
}
}]
}, {
stack: 'a',
type: 'pie',
radius: ['20%', '80%'],
roseType: 'area',
zlevel: 10,
label: {
normal: {
show: true,
formatter: "{c}",
textStyle: {
fontSize: 12,
},
position: 'outside'
},
emphasis: {
show: true
}
},
labelLine: {
normal: {
show: true,
length: 20,
length2: 55
},
emphasis: {
show: false
}
},
data: data
},]
}
}
onMounted(() => {
init()
setInterval(() => {
init()
}, 10000)
})
function init() {
Api.get('/cityStats/rechargeRatio').then((res) => {
var title = res.map((val) => val.cityName)
var data = res.map((val) => {
return {
name: val.cityName,
value: val.amountRatio
}
})
var chart = echarts.init(document.getElementById('chart-circleChat'));
chart.setOption(option(title, data));
})
}
</script>
<template>
<div id="chart-circleChat" style="width: 100%;height: 100%;">
</div>
</template>
<style scoped lang="scss"></style>

View File

@@ -0,0 +1,10 @@
<script setup>
</script>
<template>
<div style="display: flex;align-items: center;justify-content: center;">
<img src="/src/assets/标题.png" style="width: 1880px;height: 91px;" alt="">
</div>
</template>
<style scoped lang="scss"></style>

View File

@@ -0,0 +1,203 @@
<script setup>
import TableHeader from './tableHeader.vue';
import Line from './line.vue';
import { BorderBox8 as DvBorderBox8, } from '@kjgl77/datav-vue3'
import { onMounted, reactive, ref } from 'vue'
import Api from '@/api/index';
let count = ref({})
onMounted(() => {
init()
setInterval(() => {
init()
}, 10000)
})
function init() {
Api('/orderStats/total').then((res) => {
count.value = {
...count.value,
...res
}
})
Api('/deviceStats/total').then((res) => {
count.value = {
...count.value,
...res
}
})
}
</script>
<template>
<div class="left">
<TableHeader title="电桩信息" />
<div class="left_dzinfo">
<div class="left_dzinfo_view">
<div>{{ count.deviceTotal || 0 }}</div>
<div>总电桩数</div>
</div>
<div class="left_dzinfo_view">
<div>{{ count.gunTotal || 0 }}</div>
<div>总端口数</div>
</div>
<div class="left_dzinfo_view">
<div>{{ count.alertTotal || 0 }}</div>
<div>总报警数</div>
</div>
<div class="left_dzinfo_view">
<div>{{ count.onlineDeviceTotal || 0 }}</div>
<div>在线电桩数</div>
</div>
<div class="left_dzinfo_view">
<div>{{ count.onlineGunTotal || 0 }}</div>
<div>在线端口数</div>
</div>
<div class="left_dzinfo_view">
<div>{{ count.useTotal || 0 }}</div>
<div>使用中</div>
</div>
</div>
<div class="left_lv">
<div class="left_lv_view">
<img style="width: 33px;height: 40px;" src="/src/assets/img/1.png" alt="">
<div class="left_lv_view_info">
<div style="color: #fff;font-size: 14px;">使用率%</div>
<div style="color: #5EFFFC;font-size: 13px;">{{ count.useRate || 0 }}%</div>
</div>
</div>
<div class="left_lv_view">
<img style="width: 42px;height: 42px;" src="/src/assets/img/2.png" alt="">
<div class="left_lv_view_info">
<div style="color: #fff;font-size: 14px;">使用时长</div>
<div style="color: #5EFFFC;font-size: 13px;">{{ count.useTime || 0 }}min</div>
</div>
</div class="left_lv_view">
</div>
<TableHeader title="订单数据" />
<div class="left_order">
<div class="left_order_view">
<img src="/src/assets/img/-s-icon-巡防队.png" alt="">
<div>日订单数</div>
<div style="color: #2CFFB1">{{ count.dayCount || 0 }}</div>
</div>
<div class="left_order_view">
<img src="/src/assets/img/-s-icon-保安队.png" alt="">
<div>月订单数</div>
<div style="color: #1CFBFF">{{ count.monthCount || 0 }}</div>
</div>
<div class="left_order_view">
<img src="/src/assets/img/-s-icon-城管员.png" alt="">
<div>季订单数</div>
<div style="color: #FCCE4A">{{ count.jiCount || 0 }}</div>
</div>
</div>
<TableHeader title="订单数据趋势" />
<div style="width: 100%;height: 300px;">
<Line />
</div>
</div>
</template>
<style scoped lang="scss">
.left {
padding: 0 20px;
&_dzinfo {
display: flex;
flex-wrap: wrap;
justify-content: space-between;
margin-top: 15px;
&_view {
width: 111px;
height: 85px;
background: url("@/assets/img/框@2x.png") no-repeat center;
background-size: cover;
color: #fff;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
margin-bottom: 12px;
div:nth-child(1) {
font-size: 17px;
color: #53DFEC;
margin-bottom: 10px;
}
div:nth-child(2) {
font-size: 13px;
}
}
}
&_lv {
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 15px;
&_view {
width: 173px;
height: 84px;
background: rgba(6, 57, 108, 0.4);
border-radius: 4px;
display: flex;
align-items: center;
justify-content: center;
background-color: rgba(6, 57, 108, 0.4);
img {
margin-right: 15px;
}
}
}
&_order {
display: flex;
align-items: center;
justify-content: space-between;
margin-top: 30px;
margin-bottom: 20px;
&_view:nth-child(1) {
background: url("@/assets/img/order1.png") no-repeat center;
width: 125px;
height: 184px;
background-size: cover;
}
&_view:nth-child(2) {
background: url("@/assets/img/order2.png") no-repeat center;
width: 125px;
height: 184px;
background-size: cover;
}
&_view:nth-child(3) {
background: url("@/assets/img/order3.png") no-repeat center;
width: 125px;
height: 184px;
background-size: cover;
}
&_view {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
color: #fff;
img {
width: 92px;
height: 99px;
}
}
}
}
</style>

View File

@@ -0,0 +1,128 @@
<script setup>
import * as echarts from 'echarts';
import Api from '@/api/index';
import { onMounted, reactive } from 'vue'
var charts = {
unit: '消费金额/订单数',
names: ['消费金额', '订单数'],
lineX: ['1月', '2月', '3月', '4月', '5月', '6月'],
value: []
}
var color = ['rgba(23, 255, 243', 'rgba(255,100,97']
var lineY = []
var initList = () => {
lineY = []
for (var i = 0; i < charts.names.length; i++) {
var x = i
if (x > color.length - 1) {
x = color.length - 1
}
var data = {
name: charts.names[i],
type: 'line',
symbol: "none",
color: color[x] + ')',
smooth: true,
areaStyle: {
normal: {
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{
offset: 0,
color: color[x] + ', 0.3)'
}, {
offset: 0.8,
color: color[x] + ', 0)'
}], false),
shadowColor: 'rgba(0, 0, 0, 0.1)',
shadowBlur: 10
}
},
data: charts.value[i],
}
lineY.push(data)
}
}
var option = () => {
return {
tooltip: {
trigger: 'axis'
},
grid: {
width: "90%"
},
xAxis: {
type: 'category',
data: charts.lineX,
nameTextStyle: {
color: '#fff'
},
axisLabel: {
show: true,
textStyle: {
color: '#fff', //更改坐标轴文字颜色
fontSize: 14 //更改坐标轴文字大小
}
}
},
yAxis: {
name: charts.unit,
type: 'value',
nameTextStyle: {
padding: [0, 0, 0, 30] // 上右下左与原位置距离
},
axisLabel: {
formatter: '{value}',
textStyle: {
color: 'rgb(0,253,255,0.6)'
}
},
splitLine: {
lineStyle: {
color: 'rgb(23,255,243,0.3)'
}
},
axisLine: {
lineStyle: {
color: 'rgb(0,253,255,0.6)'
}
}
},
series: lineY
}
}
onMounted(() => {
init()
setInterval(() => {
init()
}, 10000)
})
function init() {
Api.get('/orderStats/month').then((res) => {
res.pop()
charts.lineX = res.map((val) => val.month)
charts.value[0] = res.map((val) => val.amount)
charts.value[1] = res.map((val) => val.count)
initList()
var chart = echarts.init(document.getElementById('chart-line'));
chart.setOption(option());
})
}
</script>
<template>
<div id="chart-line" style="width: 100%;height: 100%;">
</div>
</template>
<style scoped lang="scss"></style>

View File

@@ -0,0 +1,120 @@
<script setup>
import Api from '@/api/index';
import * as echarts from 'echarts';
import { onMounted, reactive } from 'vue'
var charts = {
unit: '时间/人',
names: ['人数'],
lineX: [],
value: []
}
var color = ['rgba(23, 255, 243', 'rgba(255,100,97']
var lineY = []
var initList = () => {
lineY = []
for (var i = 0; i < charts.names.length; i++) {
var x = i
if (x > color.length - 1) {
x = color.length - 1
}
var data = {
name: charts.names[i],
type: 'line',
symbol: "none",
color: color[x] + ')',
smooth: true,
areaStyle: {
normal: {
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{
offset: 0,
color: color[x] + ', 0.3)'
}, {
offset: 0.8,
color: color[x] + ', 0)'
}], false),
shadowColor: 'rgba(0, 0, 0, 0.1)',
shadowBlur: 10
}
},
data: charts.value[i],
}
lineY.push(data)
}
}
var option = () => {
return {
tooltip: {
trigger: 'axis'
},
grid: {
width: "90%"
},
xAxis: {
type: 'category',
data: charts.lineX,
nameTextStyle: {
color: '#fff'
},
axisLabel: {
show: true,
textStyle: {
color: '#fff', //更改坐标轴文字颜色
fontSize: 14 //更改坐标轴文字大小
}
}
},
yAxis: {
name: charts.unit,
type: 'value',
nameTextStyle: {
padding: [0, 0, 0, 30] // 上右下左与原位置距离
},
axisLabel: {
formatter: '{value}',
textStyle: {
color: 'rgb(0,253,255,0.6)'
}
},
splitLine: {
lineStyle: {
color: 'rgb(23,255,243,0.3)'
}
},
axisLine: {
lineStyle: {
color: 'rgb(0,253,255,0.6)'
}
}
},
series: lineY
}
}
onMounted(() => {
init()
setInterval(() => {
init()
}, 10000)
})
function init() {
Api.get('/userStats/total').then((res) => {
// res.month.pop()
charts.lineX = res.month.map((val) => val.dateStr)
charts.value[0] = res.month.map((val) => val.count)
initList()
var chart = echarts.init(document.getElementById('chart-member'));
chart.setOption(option());
})
}
</script>
<template>
<div id="chart-member" style="width: 100%;height: 100%;">
</div>
</template>
<style scoped lang="scss"></style>

View File

@@ -0,0 +1,118 @@
<script setup>
import TableHeader from './tableHeader.vue';
import MemberChat from './memberChat.vue';
import CircleChat from './circleChat.vue';
import RightBottom from './rightBottom.vue';
import Line from './line.vue';
import { BorderBox8 as DvBorderBox8, } from '@kjgl77/datav-vue3'
</script>
<template>
<div class="right">
<TableHeader title="会员新增情况" />
<div class="right_title">
<div class="right_title_left">
<div class="right_title_left_line"></div>
<div>
重点人群新增
</div>
</div>
<!-- <div class="right_title_right">
<div>月度</div>
<div>季度</div>
<div>年度</div>
</div> -->
</div>
<div class="right_topChat">
<MemberChat />
</div>
<div class="right_title">
<div class="right_title_left">
<div class="right_title_left_line"></div>
<div>
充值市场比例
</div>
</div>
</div>
<div class="right_yuanChat">
<CircleChat />
</div>
<div class="right_title" style="margin-bottom: 15px;">
<div class="right_title_left">
<div class="right_title_left_line"></div>
<div>
实时消费记录
</div>
</div>
</div>
<div>
<RightBottom />
</div>
</div>
</template>
<style scoped lang="scss">
.right {
padding: 0 20px;
&_title {
display: flex;
align-items: center;
justify-content: space-between;
margin-top: 15px;
&_left {
display: flex;
align-items: center;
font-family: Source Han Sans CN;
font-weight: 400;
font-size: 15px;
color: #00CCFF;
&_line {
width: 4px;
height: 15px;
background: #00CCFF;
margin-right: 10px;
}
}
&_right {
display: flex;
align-items: center;
div {
display: flex;
align-items: center;
justify-content: center;
width: 46px;
height: 22px;
background: rgba(0, 67, 92, 0.6);
box-shadow: 0px 1px 0px 0px rgba(51, 214, 255, 0.3);
border-radius: 9px;
margin-right: 10px;
color: #fff;
font-size: 12px;
}
}
}
&_topChat {
width: 100%;
height: 250px;
}
&_yuanChat {
padding: 10px 0;
width: 100%;
height: 250px;
background: url("@/assets/img/chatKuang.png") no-repeat;
background-size: 100% 250px;
margin-top: 10px;
}
}
</style>

View File

@@ -0,0 +1,111 @@
<script setup>
import { vue3ScrollSeamless } from "vue3-scroll-seamless";
import Api from '@/api/index';
import { onMounted, reactive, ref } from 'vue'
let list = ref([]);
const classOptions = {
limitMoveNum: 6,
};
onMounted(() => {
init()
setInterval(() => {
init()
}, 10000)
})
function init() {
Api('/orderStats/realTimeData').then((res) => {
list.value = res
})
}
</script>
<template>
<div class="demo">
<!-- <vue3ScrollSeamless class="scroll-wrap" :classOptions="classOptions" :dataList="list"> -->
<ul class="ui-wrap">
<li class="li-item" v-for="(item, i) in (list.length > 6 ? list.splice(6, 4) : list)" :key="i">
<div class="li-item-top">
<div class="li-item-top-yuan"></div>
{{ item.createTime }}
</div>
<div class="li-item-bottom">
<!-- <div>
{{ item.stationName }}
</div> -->
<div>
{{ item.phone }}
</div>
<div>
{{ item.amount }}
</div>
</div>
</li>
</ul>
<!-- </vue3ScrollSeamless> -->
</div>
</template>
<style lang="scss">
.demo {
display: flex;
align-items: center;
justify-content: center;
}
.scroll-wrap {
height: 260px;
width: 100%;
margin: 0 auto;
overflow: hidden;
padding: 0 15px;
}
.ui-wrap {
width: 100%;
height: 260px;
list-style: none;
padding: 0;
margin: 0 auto;
overflow: hidden;
}
.li-item {
width: 100%;
margin-bottom: 3px;
.li-item-top {
display: flex;
align-items: center;
color: #fff;
font-size: 14px;
.li-item-top-yuan {
margin-right: 10px;
width: 10px;
height: 10px;
border: 1px solid #00FFFF;
border-radius: 50%;
}
}
.li-item-bottom {
display: flex;
align-items: center;
justify-content: space-between;
color: #84D1FF;
font-size: 13px;
padding-left: 20px;
div:nth-child(2) {
color: #1CFFAC;
}
}
}
</style>

View File

@@ -0,0 +1,27 @@
<script setup>
const data = defineProps({
title: {
type: String,
}
});
</script>
<template>
<div class="tableHeader">
{{ title }}
</div>
</template>
<style scoped>
.tableHeader {
color: #fff;
background: url("@/assets/img/-s-bg_.png") no-repeat left;
padding: 10px;
padding-left: 55px;
font-weight: bold;
font-size: 15px;
}
</style>

View File

@@ -0,0 +1,73 @@
<script setup>
import Header from "@/views/screen/components/header.vue";
import Left from "@/views/screen/components/left.vue";
import Center from "@/views/screen/components/center.vue";
import Right from "@/views/screen/components/right.vue";
import { BorderBox1 as DvBorderBox1, BorderBox11 as BorderBox11, BorderBox12 as DvBorderBox12 } from '@kjgl77/datav-vue3'
</script>
<template>
<div class="container">
<div class="container_header">
<Header />
</div>
<div class="container_content">
<div class="container_content_left">
<Left />
</div>
<div class="container_content_center">
<Center />
</div>
<div class="container_content_right">
<Right />
</div>
</div>
</div>
</template>
<style scoped lang="scss">
.container {
display: flex;
flex-direction: column;
width: 100%;
height: 100%;
background-color: #000C40;
padding: 0 30px 30px;
background: url("@/assets/bei.jpg") no-repeat center;
background-size: cover;
&_header{
height: 10%;
}
&_content {
width: 100%;
height: 90%;
display: flex;
align-items: center;
justify-content: space-between;
&_left {
width: 400px;
height: 100%;
background: rgba(4,29,66,0.5);
}
&_center {
width: 65%;
height: 100%;
}
&_right {
width: 400px;
height: 100%;
background: rgba(4,29,66,0.5);
}
}
}
</style>