This commit is contained in:
xbx 2024-04-09 14:24:57 +08:00
parent ddeeebabf4
commit 91c7f38dce
32 changed files with 1418 additions and 210 deletions

74
package-lock.json generated
View File

@ -20,6 +20,8 @@
"cron-parser": "^2.10.0",
"dayjs": "^1.8.0",
"dom-align": "1.12.0",
"echarts": "^5.5.0",
"echarts-wordcloud": "^2.1.0",
"enquire.js": "^2.1.6",
"js-cookie": "^2.2.0",
"lodash.get": "^4.4.2",
@ -9690,6 +9692,28 @@
"safer-buffer": "^2.1.0"
}
},
"node_modules/echarts": {
"version": "5.5.0",
"resolved": "https://registry.npmmirror.com/echarts/-/echarts-5.5.0.tgz",
"integrity": "sha512-rNYnNCzqDAPCr4m/fqyUFv7fD9qIsd50S6GDFgO1DxZhncCsNsG7IfUlAlvZe5oSEQxtsjnHiUuppzccry93Xw==",
"dependencies": {
"tslib": "2.3.0",
"zrender": "5.5.0"
}
},
"node_modules/echarts-wordcloud": {
"version": "2.1.0",
"resolved": "https://registry.npmmirror.com/echarts-wordcloud/-/echarts-wordcloud-2.1.0.tgz",
"integrity": "sha512-Kt1JmbcROgb+3IMI48KZECK2AP5lG6bSsOEs+AsuwaWJxQom31RTNd6NFYI01E/YaI1PFZeueaupjlmzSQasjQ==",
"peerDependencies": {
"echarts": "^5.0.1"
}
},
"node_modules/echarts/node_modules/tslib": {
"version": "2.3.0",
"resolved": "https://registry.npmmirror.com/tslib/-/tslib-2.3.0.tgz",
"integrity": "sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg=="
},
"node_modules/ee-first": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
@ -22094,6 +22118,19 @@
"engines": {
"node": ">=4"
}
},
"node_modules/zrender": {
"version": "5.5.0",
"resolved": "https://registry.npmmirror.com/zrender/-/zrender-5.5.0.tgz",
"integrity": "sha512-O3MilSi/9mwoovx77m6ROZM7sXShR/O/JIanvzTwjN3FORfLSr81PsUGd7jlaYOeds9d8tw82oP44+3YucVo+w==",
"dependencies": {
"tslib": "2.3.0"
}
},
"node_modules/zrender/node_modules/tslib": {
"version": "2.3.0",
"resolved": "https://registry.npmmirror.com/tslib/-/tslib-2.3.0.tgz",
"integrity": "sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg=="
}
},
"dependencies": {
@ -30310,6 +30347,28 @@
"safer-buffer": "^2.1.0"
}
},
"echarts": {
"version": "5.5.0",
"resolved": "https://registry.npmmirror.com/echarts/-/echarts-5.5.0.tgz",
"integrity": "sha512-rNYnNCzqDAPCr4m/fqyUFv7fD9qIsd50S6GDFgO1DxZhncCsNsG7IfUlAlvZe5oSEQxtsjnHiUuppzccry93Xw==",
"requires": {
"tslib": "2.3.0",
"zrender": "5.5.0"
},
"dependencies": {
"tslib": {
"version": "2.3.0",
"resolved": "https://registry.npmmirror.com/tslib/-/tslib-2.3.0.tgz",
"integrity": "sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg=="
}
}
},
"echarts-wordcloud": {
"version": "2.1.0",
"resolved": "https://registry.npmmirror.com/echarts-wordcloud/-/echarts-wordcloud-2.1.0.tgz",
"integrity": "sha512-Kt1JmbcROgb+3IMI48KZECK2AP5lG6bSsOEs+AsuwaWJxQom31RTNd6NFYI01E/YaI1PFZeueaupjlmzSQasjQ==",
"requires": {}
},
"ee-first": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
@ -40464,6 +40523,21 @@
"dev": true
}
}
},
"zrender": {
"version": "5.5.0",
"resolved": "https://registry.npmmirror.com/zrender/-/zrender-5.5.0.tgz",
"integrity": "sha512-O3MilSi/9mwoovx77m6ROZM7sXShR/O/JIanvzTwjN3FORfLSr81PsUGd7jlaYOeds9d8tw82oP44+3YucVo+w==",
"requires": {
"tslib": "2.3.0"
},
"dependencies": {
"tslib": {
"version": "2.3.0",
"resolved": "https://registry.npmmirror.com/tslib/-/tslib-2.3.0.tgz",
"integrity": "sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg=="
}
}
}
}
}

View File

@ -10,42 +10,44 @@
"lint": "vue-cli-service lint"
},
"dependencies": {
"@jeecg/antd-online-mini": "3.4.3-beta2",
"ant-design-vue": "^1.7.2",
"@antv/data-set": "^0.11.4",
"viser-vue": "^2.4.8",
"@jeecg/antd-online-mini": "3.4.3-beta2",
"@tinymce/tinymce-vue": "2.1.0",
"@toast-ui/editor": "^2.1.2",
"ant-design-vue": "^1.7.2",
"axios": "^0.18.0",
"china-area-data": "^5.0.1",
"clipboard": "^2.0.4",
"codemirror": "^5.46.0",
"cron-parser": "^2.10.0",
"dayjs": "^1.8.0",
"dom-align": "1.12.0",
"echarts": "^5.5.0",
"echarts-wordcloud": "^2.1.0",
"enquire.js": "^2.1.6",
"js-cookie": "^2.2.0",
"lodash.get": "^4.4.2",
"lodash.pick": "^4.4.0",
"md5": "^2.2.1",
"nprogress": "^0.2.0",
"qiankun": "^2.5.1",
"tinymce": "5.4.1",
"viser-vue": "^2.4.8",
"vue": "^2.6.10",
"vue-area-linkage": "^5.1.0",
"vue-cropper": "^0.5.4",
"vue-i18n": "^8.7.0",
"vue-loader": "^15.7.0",
"vue-ls": "^3.2.0",
"vue-router": "^3.0.1",
"vuex": "^3.1.0",
"vue-print-nb-jeecg": "^1.0.12",
"clipboard": "^2.0.4",
"vue-photo-preview": "^1.1.3",
"vue-print-nb-jeecg": "^1.0.12",
"vue-router": "^3.0.1",
"vue-splitpane": "^1.0.4",
"vuedraggable": "^2.20.0",
"codemirror": "^5.46.0",
"@tinymce/tinymce-vue": "2.1.0",
"tinymce": "5.4.1",
"@toast-ui/editor": "^2.1.2",
"vue-area-linkage": "^5.1.0",
"china-area-data": "^5.0.1",
"dom-align": "1.12.0",
"xe-utils": "2.4.8",
"vuex": "^3.1.0",
"vxe-table": "2.9.13",
"vxe-table-plugin-antd": "1.8.10",
"cron-parser": "^2.10.0",
"qiankun": "^2.5.1",
"xe-utils": "2.4.8",
"xss": "^1.0.13"
},
"devDependencies": {
@ -55,13 +57,13 @@
"@vue/cli-service": "^3.3.0",
"@vue/eslint-config-standard": "^4.0.0",
"babel-eslint": "7.2.3",
"compression-webpack-plugin": "^3.1.0",
"eslint": "^5.16.0",
"eslint-plugin-vue": "^5.1.0",
"html-webpack-plugin": "^4.2.0",
"less": "^3.9.0",
"less-loader": "^4.1.0",
"vue-template-compiler": "^2.6.10",
"html-webpack-plugin": "^4.2.0",
"compression-webpack-plugin": "^3.1.0"
"vue-template-compiler": "^2.6.10"
},
"eslintConfig": {
"root": true,
@ -99,7 +101,10 @@
"vue/html-closing-bracket-newline": 0,
"vue/no-parsing-error": 0,
"no-tabs": 0,
"indent": ["off", 2],
"indent": [
"off",
2
],
"no-console": 0,
"space-before-function-paren": 0
}

4
public/color.less vendored
View File

@ -1,4 +1,4 @@
@primary-color: #1890ff;
@primary-color: #13c2c2;
/* stylelint-disable at-rule-empty-line-before,at-rule-name-space-after,at-rule-no-unknown */
/* stylelint-disable no-duplicate-selectors */
/* stylelint-disable */
@ -1375,7 +1375,7 @@ this.tinycolor = tinycolor;
@blue-3: color(~`colorPalette("@{blue-6}", 3)`);
@blue-4: color(~`colorPalette("@{blue-6}", 4)`);
@blue-5: color(~`colorPalette("@{blue-6}", 5)`);
@blue-6: #1890ff;
@blue-6: #13c2c2;
@blue-7: color(~`colorPalette("@{blue-6}", 7)`);
@blue-8: color(~`colorPalette("@{blue-6}", 8)`);
@blue-9: color(~`colorPalette("@{blue-6}", 9)`);

2
public/index.html vendored
View File

@ -5,7 +5,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">
<title>XXX平台</title>
<title>国足数据分析平台</title>
<link rel="icon" href="<%= BASE_URL %>logo.png">
<script src="<%= BASE_URL %>cdn/babel-polyfill/polyfill_7_2_5.js"></script>
<style>

BIN
src/assets/BG.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 298 KiB

27
src/assets/china.js Normal file

File diff suppressed because one or more lines are too long

Binary file not shown.

Before

Width:  |  Height:  |  Size: 62 KiB

After

Width:  |  Height:  |  Size: 63 KiB

View File

@ -17,7 +17,7 @@
gemo="point"
position="value*1"
shape="pointer"
color="#1890FF"
color="#13c2c2"
:active="false"
></v-series>
<v-guide
@ -171,7 +171,7 @@
},
arcGuide2Start: [0, 0.945],
arcGuide2Style: {
stroke: '#1890FF',
stroke: '#13c2c2',
lineWidth: 18,
},
htmlGuidePosition: ['50%', '100%'],

View File

@ -66,7 +66,7 @@
.progress {
transition: all .4s cubic-bezier(.08, .82, .17, 1) 0s;
border-radius: 1px 0 0 1px;
background-color: #1890ff;
background-color: #13c2c2;
width: 0;
height: 100%;
}

View File

@ -183,7 +183,7 @@
* @param title 要修改的新标题
*/
changeTitle(title) {
let projectTitle = "XXX平台"
let projectTitle = "国足数据分析平台"
//
if (this.$route.path === indexKey) {
document.title = projectTitle

View File

@ -43,7 +43,7 @@
width: 100%;
min-height: 100%;
// background: #f0f2f5 url(~@/assets/lol.jpeg) no-repeat ;
background: #5b9dff ;
background: #13c2c2 ;
background-size: 100%;
padding: 110px 0 144px;
position: relative;

View File

@ -349,7 +349,7 @@
.avatar {
margin: 20px 10px 20px 0;
color: #1890ff;
color: #13c2c2;
background: hsla(0, 0%, 100%, .85);
vertical-align: middle;
}

View File

@ -273,7 +273,7 @@
padding-top: 15px;
padding-left: 24px;
height: 100%;
color: #1890ff;
color: #13c2c2;
font-size: 14px;
font-weight: 700;
}
@ -301,7 +301,7 @@
.setting-drawer-index-handle {
position: absolute;
top: 240px;
background: #1890ff;
background: #13c2c2;
width: 48px;
height: 48px;
right: 300px;

View File

@ -20,7 +20,7 @@ export default {
props: {
title: {
type: String,
default: 'XXX平台',
default: '国足数据分析平台',
required: false
},
showTitle: {

View File

@ -1,9 +1,9 @@
<template>
<div class="user-wrapper" :class="theme">
<a-dropdown>
<span class="action action-full ant-dropdown-link user-dropdown-menu">
<!-- <span class="action action-full ant-dropdown-link user-dropdown-menu">
<a-avatar class="avatar" size="small" :src="getAvatar()"/>
</span>
</span> -->
<a-menu slot="overlay" class="user-dropdown-menu-wrapper">
<a-menu-item key="3" @click="systemSetting">
<a-icon type="tool"/>

View File

@ -14,13 +14,13 @@ const colorList = [
key: '日暮', color: '#FAAD14',
},
{
key: '明青', color: '#13C2C2',
key: '明青(默认)', color: '#13C2C2',
},
{
key: '极光绿', color: '#52C41A',
},
{
key: '拂晓蓝(默认)', color: '#1890FF',
key: '拂晓蓝', color: '#1890FF',
},
{
key: '极客蓝', color: '#2F54EB',
@ -39,7 +39,7 @@ const updateTheme = primaryColor => {
if (!primaryColor) {
return;
}
const hideMessage = message.loading('正在编译主题!', 0);
// const hideMessage = message.loading('正在编译主题!', 0);
console.info(`正在编译主题!`)
function buildIt() {
// 正确的判定less是否已经加载less.modifyVars可用
@ -54,8 +54,8 @@ const updateTheme = primaryColor => {
hideMessage();
})
.catch(() => {
message.error('Failed to update theme');
hideMessage();
// message.error('Failed to update theme');
// hideMessage();
});
}
if (!lessNodesAppended) {

View File

@ -14,7 +14,7 @@
*/
export default {
primaryColor: '#1890FF', // primary color of ant design
primaryColor: '#13c2c2', // primary color of ant design
navTheme: 'light', // theme for nav menu
layout: 'sidemenu', // nav menu position: sidemenu or topmenu
contentWidth: 'Fixed', // layout of content: Fluid or Fixed, only works when layout is topmenu

View File

@ -268,7 +268,7 @@
}
&:hover {
span {
color: #1890ff;
color: #13c2c2;
}
}
}

View File

@ -1,8 +1,279 @@
<template>
<div>
这是首页
<a-row :gutter="12">
<a-col :xl="12" :style="{ marginBottom: '12px' }">
<div class="container">
<div id="age" style="width: 660px; height: 300px"></div>
</div>
</a-col>
<a-col :xl="12" :style="{ marginBottom: '12px' }">
<div class="container">
<div id="map" style="width: 660px; height: 300px"></div>
</div>
</a-col>
</a-row>
<a-row :gutter="12">
<a-col :xl="12" :style="{ marginBottom: '12px' }">
<div class="container">
<div id="history" style="width: 600px; height: 300px"></div>
</div>
</a-col>
<a-col :xl="12" :style="{ marginBottom: '12px' }">
<div class="container">
<div id="contrast" style="width: 600px; height: 300px"></div>
</div>
</a-col>
</a-row>
</div>
</template>
<script>
</script>
import * as echarts from 'echarts';
import "@/assets/china.js";
export default {
methods: {
ageChart() {
// domecharts main
let myChart = echarts.init(document.getElementById("age"));
//
let option = {
title: {
text: "球员年龄分布分析",
},
tooltip: {},
legend: {
data: ["人数"],
},
xAxis: {
data: [19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33],
axisLabel: {
interval: 0,
// rotate: 30
}
},
yAxis: {},
series: [
{
name: "人数",
type: "bar",
data: [42, 52, 55, 66, 78, 79, 90, 120, 98, 80, 78, 60, 65, 50, 45],
label: {
normal: {
show: true,
position: 'top'
},
formatter: '{@value}'
}
},
],
};
// 使
myChart.setOption(option);
},
mapChart() {
// echarts
var myEcharts = echarts.init(document.getElementById("map"));
var option = {
title: { //
text: '全国足球俱乐部省份分布',
x: "center",
textStyle: {
fontSize: 15,
color: "black"
},
},
tooltip: { //
trigger: 'item', //
// backgroundColor: "red", //
//(): {a}{b}{c},{d}
formatter: '地区:{b}<br/>模拟数据:{c}'
},
visualMap: {//
top: 'center',
left: 'left',
min: 0,
max: 10,
text: ['High', 'Low'],
realtime: false, //
calculable: true, //
inRange: {
color: ['lightskyblue', 'yellow', 'orangered']
}
},
series: [
{
name: '模拟数据',
type: 'map',
mapType: 'china',
roam: false,//
itemStyle: {//
normal: {//
label: {
show: true,//
textStyle: {
color: "black"
}
}
},
zoom: 1.5, //,1
emphasis: {//,
label: { show: true }
}
},
top: "3%",//
data: [
{ name: '北京', value: 4 },
{ name: '天津', value: 2 },
{ name: '上海', value: 6 },
{ name: '重庆', value: 3 },
{ name: '河北', value: 4 },
{ name: '河南', value: 3 },
{ name: '云南', value: 1 },
{ name: '辽宁', value: 7 },
{ name: '黑龙江', value: 1 },
{ name: '湖南', value: 1 },
{ name: '安徽', value: 2 },
{ name: '山东', value: 9 },
{ name: '新疆', value: 1 },
{ name: '江苏', value: 10 },
{ name: '浙江', value: 6 },
{ name: '江西', value: 1 },
{ name: '湖北', value: 6 },
{ name: '广西', value: 3 },
{ name: '甘肃', value: 2 },
{ name: '山西', value: 3 },
{ name: '内蒙古', value: 5 },
{ name: '陕西', value: 5 },
{ name: '吉林', value: 4 },
{ name: '福建', value: 5 },
{ name: '贵州', value: 1 },
{ name: '广东', value: 11 },
{ name: '青海', value: 0 },
{ name: '西藏', value: 1 },
{ name: '四川', value: 5 },
{ name: '宁夏', value: 1 },
{ name: '海南', value: 4 },
{ name: '台湾', value: 0 },
{ name: '香港', value: 0 },
{ name: '澳门', value: 0 }
]
}
]
};
// 使
myEcharts.setOption(option);
},
historyChart() {
var myChart = echarts.init(document.getElementById('history'));
let option = {
title: {
text: '国足的历史排名情况'
},
tooltip: {
trigger: 'axis'
},
legend: {
data: ['国际排名', '亚洲排名']
},
grid: {
left: '3%',
right: '4%',
bottom: '3%',
containLabel: true
},
xAxis: {
type: 'category',
boundaryGap: false,
data: [1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020, 2021, 2022],
axisLabel: {
interval: 3
}
},
yAxis: {
type: 'value',
},
series: [
{
name: '国际排名',
type: 'line',
data: [53, 40, 66, 76, 55, 37, 88, 75, 54, 63, 86, 54, 72, 84, 81, 100, 93, 87, 71, 88, 92, 97, 84, 82, 71, 76, 76, 75, 74, 78]
},
{
name: '亚洲排名',
type: 'line',
data: [6, 4, 5, 9, 9, 6, 10, 10, 6, 8, 16, 9, 10, 11, 8, 11, 13, 5, 5, 6, 10, 9, 8, 8, 6, 7, 9, 9, 8, 11]
}
]
}
myChart.setOption(option);
},
contrastChart() {
var myChart = echarts.init(document.getElementById('contrast'));
let option = {
title: {
text: "注册球员对比情况分析",
},
tooltip: {
trigger: 'item'
},
legend: {
top: '5%',
left: 'center'
},
series: [
{
name: '注册球员数(万人)',
type: 'pie',
radius: ['40%', '70%'],
avoidLabelOverlap: false,
label: {
show: false,
position: 'center'
},
emphasis: {
label: {
show: true,
fontSize: 40,
fontWeight: 'bold'
}
},
labelLine: {
show: false
},
data: [
{ value: 150, name: '俄罗斯' },
{ value: 55, name: '土耳其' },
{ value: 63, name: '德国' },
{ value: 6.7, name: '西班牙' },
{ value: 9.38, name: '克罗地亚' },
{ value: 105, name: '荷兰' },
{ value: 100, name: '日本' },
{ value: 0.7, name: '中国' }
]
}
]
}
myChart.setOption(option);
},
},
mounted() {
this.ageChart();
this.mapChart();
this.historyChart();
this.contrastChart();
}
}
</script>
<style lang="less" scoped>
.container {
display: flex;
background-color: #fff;
padding: 10px;
border-radius: 10px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.09);
}
</style>

View File

@ -84,7 +84,7 @@
display: inline-block;
width: 100%;
&:hover {
color: #1890ff;
color: #13c2c2;
}
}
}

View File

@ -0,0 +1,69 @@
<template>
<div>
<a-card title="中国足球战绩分析" :loading="loading" :bordered="false">
<template #extra>
<!-- 同步数据按钮 -->
<a-button type="primary" @click="syncData">同步数据</a-button>
</template>
<!-- <a-spin :spinning="loading"> 加载中的提示 -->
<a-table :columns="columns" :data-source="data" bordered></a-table>
<!-- </a-spin> -->
</a-card>
</div>
</template>
<script>
import { getAction } from '@api/manage'
const columns = [
{
title: '比赛性质',
dataIndex: 'nature',
},
{
title: '比赛日期',
dataIndex: 'date',
},
{
title: '比赛地点',
dataIndex: 'address',
},
{
title: '比赛对手及战果',
dataIndex: 'result',
},
{
title: '主教练',
dataIndex: 'coach',
},
];
const data = [];
export default {
data() {
return {
data,
columns,
loading: false,
};
},
methods: {
syncData() {
//
this.$message.loading('正在同步数据..');
this.loading = true;
getAction("/football/getMatch").then((res) => {
this.$message.success('数据同步成功');
this.data = res.result.data;
this.loading = false;
//
});
},
},
mounted() {
this.syncData();
}
}
</script>
<style></style>

View File

@ -0,0 +1,146 @@
<template>
<div>
<p class="title">中英足球联赛上座情况</p>
<a-row :gutter="24">
<a-col :xl="12" :style="{ marginBottom: '24px' }">
<div class="container">
<div id="map1" style="width: 660px; height: 400px"></div>
</div>
</a-col>
<a-col :xl="12" :style="{ marginBottom: '24px' }">
<div class="container">
<div id="map2" style="width: 660px; height: 400px"></div>
</div>
</a-col>
</a-row>
</div>
</template>
<script>
import * as echarts from 'echarts';
export default {
methods: {
map1Chart() {
// domecharts main
let myChart = echarts.init(document.getElementById("map1"));
//
let option = {
title: {
text: "总上座人数对比",
},
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'shadow'
}
},
legend: {
data: ["英国", "中国"],//
},
xAxis: {
data: ["一级", "二级", "三级", "四级"],
axisLabel: {
interval: 0,
// rotate: 30
}
},
yAxis: {
name: '总上座人数(万)',
},
series: [
{
name: "英国",
type: "bar",
data: [1450, 1100, 450, 300],
label: {
formatter: '{@value}'
}
},
{
name: "中国",
type: "bar",
data: [552, 180, 200, 0],
label: {
formatter: '{@value}'
}
},
],
};
// 使
myChart.setOption(option);
},
map2Chart() {
// domecharts main
let myChart = echarts.init(document.getElementById("map2"));
//
let option = {
title: {
text: "平均上座人数对比",
},
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'shadow'
}
},
legend: {
data: ["英国", "中国"],//
},
xAxis: {
data: ["一级", "二级", "三级", "四级"],
axisLabel: {
interval: 0,
// rotate: 30
}
},
yAxis: {
name: '平均上座人数(千)',
},
series: [
{
name: "英国",
type: "bar",
data: [38, 21, 8, 5],
label: {
formatter: '{@value}'
}
},
{
name: "中国",
type: "bar",
data: [23, 7, 2, 0],
label: {
formatter: '{@value}'
}
},
],
};
// 使
myChart.setOption(option);
},
},
mounted() {
this.map1Chart();
this.map2Chart();
}
}
</script>
<style lang="less" scoped>
.container {
display: flex;
background-color: #fff;
padding: 15px;
border-radius: 4px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.09);
}
.title {
font-size: 34px;
color: rgb(8, 8, 8);
font-weight: bold;
}
</style>

View File

@ -0,0 +1,138 @@
<template>
<div>
<a-card title="国足球员数据分析" :loading="loading" :bordered="false">
<template #extra>
<!-- 同步数据按钮 -->
<a-button type="primary" @click="getData()">同步数据</a-button>
</template>
<!-- <div v-for="dataset in datasets" :key="dataset"> -->
<a-table :columns="columns" :data-source="datasets" bordered>
<!-- 添加查看按钮 -->
<template v-slot:action="record">
<a-button type="primary" @click="radarChart(record)">查看</a-button>
</template>
</a-table>
<a-modal v-model="visible" title="球员综合能力分析" @ok="handleOk">
<div style="display: flex; justify-content: center; align-items: center; height: 100%;">
<div id="radar" style="width: 230px; height: 230px;"></div>
</div>
</a-modal>
<!-- </div> -->
</a-card>
</div>
</template>
<script>
import * as echarts from 'echarts';
import { getAction } from '../../api/manage';
const columns = [
{
title: '姓名',
dataIndex: 'name',
},
{
title: '位置',
dataIndex: 'position',
},
{
title: '年龄',
dataIndex: 'age',
},
{
title: '身高CM',
dataIndex: 'height',
},
{
title: '体重KG',
dataIndex: 'weight',
},
{
title: '综合能力',
dataIndex: 'sum',
},
{
title: '数据分析',
key: 'action',
scopedSlots: { customRender: 'action' },
},
];
export default {
data() {
return {
datasets: {},
chartData: [],
columns,
loading: false,
visible: false,
};
},
methods: {
getData() {
//
this.$message.loading('正在同步数据..');
this.loading = true;
getAction("/football/getPlayer").then((res) => {
this.$message.success('数据同步成功');
this.datasets = res.result.data;
this.loading = false;
});
},
radarChart(record) {
let chartData = JSON.parse(JSON.stringify(record.chart)); // __ob__: Observer
console.log(chartData);
this.visible = true;
this.option = {
title: {
},
legend: {
data: []
},
radar: {
indicator: [
{ name: '速度', max: 100 },
{ name: '射门', max: 100 },
{ name: '传球', max: 100 },
{ name: '盘带', max: 100 },
{ name: '防守', max: 100 },
{ name: '力量', max: 100 }
]
},
series: [
{
name: '',
type: 'radar',
data: [chartData],
label: {
show: true,
formatter: function (params) {
return params.value;
}
},
areaStyle: {
color: new echarts.graphic.RadialGradient(0.1, 0.6, 1, [
{
color: 'rgba(84, 112, 198)',
offset: 1
}
])
}
}
]
};
this.$nextTick(() => {
let myChart = echarts.init(document.getElementById("radar"));
myChart.setOption(this.option);
});
},
handleOk() {
this.visible = false;
}
},
mounted() {
this.getData();
}
}
</script>
<style></style>

View File

@ -0,0 +1,86 @@
<template>
<div>
<p class="title">各省市每千万人出产中超球员数量排名</p>
<a-row :gutter="24">
<a-col :xl="24" :style="{ marginBottom: '24px' }">
<div class="container">
<div id="map1" style="width: 1200px; height: 500px"></div>
</div>
</a-col>
</a-row>
</div>
</template>
<script>
import * as echarts from 'echarts';
export default {
methods: {
map1Chart() {
// domecharts main
let myChart = echarts.init(document.getElementById("map1"));
//
let option = {
title: {
},
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'shadow'
}
},
legend: {
},
xAxis: {
data: ["上海","辽宁", "天津", "北京", "湖北", "吉林", "山东", "新疆", "重庆", "广东", "江苏", "安徽", "贵州", "四川", "河南", "河北", "海南", "浙江", "广西", "湖南", "甘肃", "山西", "福建", "云南"],
axisLabel: {
interval: 0,
// rotate: 30
}
},
yAxis: {
name: '单位: 球员/千万人',
// name: ': /',
// data: ["","", "", "", "", "", "", "", "", "广", "", "", "", "", "", "", "", "", "广西", "", "", "西", "", ""].reverse(),
// axisLabel: {
// interval: 0,
// // rotate: 30
// }
},
series: [
{
type: "bar",
data: [21, 20, 19, 12,7,5,4.9,4.8,4,4.1,3.3,3,2.9,2.6,2.4,2.1,2.0,1.9,1.5,1.2,0.9,0.8,0.7,0.5],
label: {
formatter: '{@value}'
}
}
],
};
// 使
myChart.setOption(option);
},
},
mounted() {
this.map1Chart();
}
}
</script>
<style lang="less" scoped>
.container {
display: flex;
background-color: #fff;
padding: 15px;
border-radius: 4px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.09);
}
.title {
font-size: 24px;
color: rgb(8, 8, 8);
font-weight: bold;
}
</style>

View File

@ -0,0 +1,327 @@
<template>
<div>
<!-- <p class="title">国足词云</p> -->
<a-row :gutter="24">
<a-col :xl="12" :style="{ marginBottom: '24px' }">
<h2 class="title">中超中甲俱乐部词云</h2>
<div class="container">
<div id="map1" style="width: 600px; height: 500px"></div>
</div>
</a-col>
<a-col :xl="12" :style="{ marginBottom: '24px' }">
<h2 class="title">中国足球中长期发展规划词云图</h2>
<div class="container">
<div id="map2" style="width: 600px; height: 500px"></div>
</div>
</a-col>
</a-row>
</div>
</template>
<script>
import * as echarts from 'echarts';
import 'echarts-wordcloud';
export default {
data() {
return {
wordList: [
{
name: "广州恒大",
value: 15000
},
{
name: "北京中赫国安",
value: 10081
},
{
name: "山东鲁能",
value: 9386
},
{
name: "上海上港",
value: 7500
},
{
name: "河北华夏幸福",
value: 7500
},
{
name: "天津权健",
value: 6500
},
{
name: "江苏苏宁",
value: 6500
},
{
name: "上海申花",
value: 6000
},
{
name: "河南建业",
value: 4500
},
{
name: "贵州恒丰智诚",
value: 3800
},
{
name: "天津泰达",
value: 3000
},
{
name: "重庆力帆",
value: 2500
},
{
name: "北京人和",
value: 2300
},
{
name: "石家庄永昌",
value: 2000
},
{
name: "延边富德",
value: 1900
},
{
name: "深圳佳兆业",
value: 1800
},
{
name: "长春亚泰",
value: 1700
},
{
name: "武汉卓尔",
value: 1600
},
{
name: "杭州绿城",
value: 1500
},
{
name: "上海申鑫",
value: 1200
},
],
wordList2: [
{
name: "足球",
value: 15000
},
{
name: "发展",
value: 10081
},
{
name: "建设",
value: 9386
},
{
name: "足球运动",
value: 7500
},
{
name: "足球场",
value: 7500
},
{
name: "校园",
value: 6500
},
{
name: "产业",
value: 6500
},
{
name: "社会",
value: 6000
},
{
name: "活动",
value: 4500
},
{
name: "场地设施",
value: 3800
},
{
name: "企业",
value: 3000
},
{
name: "培训",
value: 2500
},
{
name: "参与",
value: 2300
},
{
name: "形成",
value: 2000
},
{
name: "规划",
value: 1900
},
{
name: "促进",
value: 1800
},
{
name: "体育",
value: 1700
},
{
name: "目标",
value: 1600
},
{
name: "基础",
value: 1500
},
{
name: "提高",
value: 1200
},
{
name: "推动",
value: 1100
},
{
name: "职业",
value: 1000
},
{
name: "相关",
value: 900
},
{
name: "实现",
value: 800
},
{
name: "持续",
value: 700
},
],
}
},
mounted() {
this.map1chart();
this.map2chart();
},
methods: {
map1chart() {
let myChart = echarts.init(document.getElementById("map1"));
myChart.setOption({
series: [
{
type: "wordCloud",
//
gridSize: 10,
//
// Text size range which the value in data will be mapped to.
// Default to have minimum 12px and maximum 60px size.
sizeRange: [14, 60],
// Text rotation range and step in degree. Text will be rotated randomly in range [-90, 90] by rotationStep 45
//[0,0]--
// rotationRange: [-45, 0, 45, 90],
// rotationRange: [ 0,90],
rotationRange: [0, 0],
//
// maskImage: maskImage,
textStyle: {
normal: {
color: function () {
return (
"rgb(" +
Math.round(Math.random() * 255) +
", " +
Math.round(Math.random() * 255) +
", " +
Math.round(Math.random() * 255) +
")"
);
}
}
},
//
// Folllowing left/top/width/height/right/bottom are used for positioning the word cloud
// Default to be put in the center and has 75% x 80% size.
left: "center",
top: "center",
right: null,
bottom: null,
width: "200%",
height: "200%",
//
data: this.wordList
}
]
})
},
map2chart() {
let myChart = echarts.init(document.getElementById("map2"));
myChart.setOption({
series: [
{
type: "wordCloud",
gridSize: 10,
sizeRange: [14, 60],
rotationRange: [0, 0],
textStyle: {
normal: {
color: function () {
return (
"rgb(" +
Math.round(Math.random() * 255) +
", " +
Math.round(Math.random() * 255) +
", " +
Math.round(Math.random() * 255) +
")"
);
}
}
},
left: "center",
top: "center",
right: null,
bottom: null,
width: "200%",
height: "200%",
data: this.wordList2
}
]
})
}
}
}
</script>
<style lang="less" scoped>
.container {
display: flex;
background-color: #fff;
padding: 15px;
border-radius: 4px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.09);
}
.wordcloud {
width: 100%;
height: 300px;
margin: auto;
}
.title {
font-size: 24px;
color: rgb(8, 8, 8);
font-weight: bold;
}
</style>

View File

@ -110,6 +110,6 @@
}
.clName .ant-tree li .ant-tree-node-content-wrapper.ant-tree-node-selected {
background-color: #1890FF !important;
background-color: #13c2c2 !important;
}
</style>

View File

@ -1,22 +1,32 @@
<template>
<div class="main">
<a-form-model class="user-layout-login" @keyup.enter.native="handleSubmit">
<!-- 登录修改 -->
<login-account ref="alogin" @validateFail="validateFail" @success="requestSuccess" @fail="requestFailed"></login-account>
<div class="container">
<div class="main">
<div class="header">
<img src="~@/assets/logo.png" alt="logo" class="logo">
<p class="title">国足数据分析平台</p>
</div>
<a-form-model-item>
<a-checkbox @change="handleRememberMeChange" default-checked>自动登录</a-checkbox>
</a-form-model-item>
<a-form-model class="user-layout-login" @keyup.enter.native="handleSubmit">
<!-- 登录修改 -->
<login-account ref="alogin" @validateFail="validateFail" @success="requestSuccess"
@fail="requestFailed"></login-account>
<a-form-item style="margin-top:24px">
<a-button size="large" type="primary" htmlType="submit" class="login-button" :loading="loginBtn" @click.stop.prevent="handleSubmit" :disabled="loginBtn">确定
</a-button>
</a-form-item>
<a-form-model-item>
<a-checkbox @change="handleRememberMeChange" default-checked>自动登录</a-checkbox>
</a-form-model-item>
</a-form-model>
<a-form-item style="margin-top:24px">
<a-button size="large" type="primary" htmlType="submit" class="login-button" :loading="loginBtn"
@click.stop.prevent="handleSubmit" :disabled="loginBtn">确定
</a-button>
</a-form-item>
<two-step-captcha v-if="requiredTwoStepCaptcha" :visible="stepCaptchaVisible" @success="stepCaptchaSuccess" @cancel="stepCaptchaCancel"></two-step-captcha>
<login-select-tenant ref="loginSelect" @success="loginSelectOk"></login-select-tenant>
</a-form-model>
<two-step-captcha v-if="requiredTwoStepCaptcha" :visible="stepCaptchaVisible" @success="stepCaptchaSuccess"
@cancel="stepCaptchaCancel"></two-step-captcha>
<login-select-tenant ref="loginSelect" @success="loginSelectOk"></login-select-tenant>
</div>
</div>
</template>
@ -33,170 +43,206 @@ import LoginAccount from './LoginAccount'
import LoginPhone from './LoginPhone'
export default {
components: {
LoginSelectTenant,
TwoStepCaptcha,
ThirdLogin,
LoginAccount,
LoginPhone
components: {
LoginSelectTenant,
TwoStepCaptcha,
ThirdLogin,
LoginAccount,
LoginPhone
},
data() {
return {
customActiveKey: 'tab1',
rememberMe: true,
loginBtn: false,
requiredTwoStepCaptcha: false,
stepCaptchaVisible: false,
encryptedString: {
key: "",
iv: "",
},
}
},
created() {
Vue.ls.remove(ACCESS_TOKEN)
this.getRouterData();
this.rememberMe = true
},
methods: {
handleTabClick(key) {
this.customActiveKey = key
},
data () {
return {
customActiveKey: 'tab1',
rememberMe: true,
loginBtn: false,
requiredTwoStepCaptcha: false,
stepCaptchaVisible: false,
encryptedString:{
key:"",
iv:"",
},
handleRememberMeChange(e) {
this.rememberMe = e.target.checked
},
/**跳转到登录页面的参数-账号获取*/
getRouterData() {
this.$nextTick(() => {
let temp = this.$route.params.username || this.$route.query.username || ''
if (temp) {
this.$refs.alogin.acceptUsername(temp)
}
})
},
//
handleSubmit() {
this.loginBtn = true;
if (this.customActiveKey === 'tab1') {
// 使
this.$refs.alogin.handleLogin(this.rememberMe)
} else {
//
this.$refs.plogin.handleLogin(this.rememberMe)
}
},
created() {
Vue.ls.remove(ACCESS_TOKEN)
this.getRouterData();
this.rememberMe = true
//
validateFail() {
this.loginBtn = false;
},
//
requestSuccess(loginResult) {
this.$refs.loginSelect.show(loginResult)
},
//
requestFailed(err) {
let description = ((err.response || {}).data || {}).message || err.message || "请求出现错误,请稍后再试"
this.$notification['error']({
message: '登录失败',
description: description,
duration: 4,
});
//
this.loginBtn = false;
},
loginSelectOk() {
this.loginSuccess()
},
//
loginSuccess() {
this.$router.push({ path: "/dashboard/analysis" }).catch(() => {
console.log('登录跳转首页出错,这个错误从哪里来的')
})
},
methods:{
handleTabClick(key){
this.customActiveKey = key
},
handleRememberMeChange(e){
this.rememberMe = e.target.checked
},
/**跳转到登录页面的参数-账号获取*/
getRouterData(){
this.$nextTick(() => {
let temp = this.$route.params.username || this.$route.query.username || ''
if (temp) {
this.$refs.alogin.acceptUsername(temp)
}
})
},
//
handleSubmit () {
this.loginBtn = true;
if (this.customActiveKey === 'tab1') {
// 使
this.$refs.alogin.handleLogin(this.rememberMe)
} else {
//
this.$refs.plogin.handleLogin(this.rememberMe)
}
},
//
validateFail(){
this.loginBtn = false;
},
//
requestSuccess(loginResult){
this.$refs.loginSelect.show(loginResult)
},
//
requestFailed (err) {
let description = ((err.response || {}).data || {}).message || err.message || "请求出现错误,请稍后再试"
this.$notification[ 'error' ]({
message: '登录失败',
description: description,
duration: 4,
stepCaptchaSuccess() {
this.loginSuccess()
},
stepCaptchaCancel() {
this.Logout().then(() => {
this.loginBtn = false
this.stepCaptchaVisible = false
})
},
//
getEncrypte() {
var encryptedString = Vue.ls.get(ENCRYPTED_STRING);
if (encryptedString == null) {
getEncryptedString().then((data) => {
this.encryptedString = data
});
//
if(this.customActiveKey === 'tab1' && description.indexOf('密码错误')>0){
this.$refs.alogin.handleChangeCheckCode()
}
this.loginBtn = false;
},
loginSelectOk(){
this.loginSuccess()
},
//
loginSuccess () {
this.$router.push({ path: "/dashboard/analysis" }).catch(()=>{
console.log('登录跳转首页出错,这个错误从哪里来的')
})
this.$notification.success({
message: '欢迎',
description: `${timeFix()},欢迎回来`,
});
},
stepCaptchaSuccess () {
this.loginSuccess()
},
stepCaptchaCancel () {
this.Logout().then(() => {
this.loginBtn = false
this.stepCaptchaVisible = false
})
},
//
getEncrypte(){
var encryptedString = Vue.ls.get(ENCRYPTED_STRING);
if(encryptedString == null){
getEncryptedString().then((data) => {
this.encryptedString = data
});
}else{
this.encryptedString = encryptedString;
}
} else {
this.encryptedString = encryptedString;
}
}
}
}
</script>
<style lang="less" scoped>
.user-layout-login {
background-color: aliceblue;
padding: 40px;
label {
font-size: 14px;
}
.container {
/* 居中显示 */
display: flex;
justify-content: center;
// align-items: center;
/* 设置背景图 */
background-image: url('~@/assets/BG.jpg'); //
background-size: cover; //
background-position: center; //
/* 确保容器占据整个视口 */
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
}
.header {
display: flex;
align-items: center;
justify-content: center;
margin-top: 20px;
}
.logo {
width: 60px;
height: 60px;
}
.title {
font-size: 44px;
margin-left: 10px; // 使
color: white;
margin-top: 43px;
font-weight: bold;
}
.user-layout-login {
// background-color: aliceblue;
background-color: rgba(255, 255, 255, 0.5);
padding: 40px;
label {
font-size: 14px;
}
.getCaptcha {
display: block;
width: 100%;
height: 40px;
}
display: block;
width: 100%;
height: 40px;
}
.forge-password {
font-size: 14px;
}
font-size: 14px;
}
button.login-button {
padding: 0 15px;
font-size: 16px;
height: 40px;
width: 100%;
}
button.login-button {
padding: 0 15px;
font-size: 16px;
height: 40px;
width: 100%;
}
.user-login-other {
text-align: left;
margin-top: 24px;
line-height: 22px;
text-align: left;
margin-top: 24px;
line-height: 22px;
.item-icon {
font-size: 24px;
color: rgba(0,0,0,.2);
margin-left: 16px;
vertical-align: middle;
cursor: pointer;
transition: color .3s;
font-size: 24px;
color: rgba(0, 0, 0, .2);
margin-left: 16px;
vertical-align: middle;
cursor: pointer;
transition: color .3s;
&:hover {
color: #1890ff;
}
}
.register {
float: right;
color: #13c2c2;
}
}
.register {
float: right;
}
}
}
</style>
<style>
.valid-error .ant-select-selection__placeholder{
color: #f5222d;
}
.valid-error .ant-select-selection__placeholder {
color: #f5222d;
}
</style>

View File

@ -2,13 +2,11 @@
<div>
<a-form-model ref="form" :model="model" :rules="validatorRules">
<a-form-model-item required prop="username">
<a-input v-model="model.username" size="large" placeholder="请输入帐户名 / admin">
<a-icon slot="prefix" type="user" :style="{ color: 'rgba(0,0,0,.25)' }"/>
<a-input v-model="model.username" size="large" placeholder="请输入帐户名">
</a-input>
</a-form-model-item>
<a-form-model-item required prop="password">
<a-input v-model="model.password" size="large" type="password" autocomplete="false" placeholder="请输入密码 / 123456">
<a-icon slot="prefix" type="lock" :style="{ color: 'rgba(0,0,0,.25)' }"/>
<a-input v-model="model.password" size="large" type="password" autocomplete="false" placeholder="请输入密码">
</a-input>
</a-form-model-item>
</a-form-model>

View File

@ -186,10 +186,6 @@ export const JeecgThirdLoginMixin = {
this.$router.push({ path: "/dashboard/analysis" }).catch(()=>{
console.log('登录跳转首页出错,这个错误从哪里来的')
})
this.$notification.success({
message: '欢迎',
description: `${timeFix()},欢迎回来`,
});
},
cmsFailed(err){
this.$notification[ 'error' ]({

View File

@ -108,7 +108,7 @@ export default {
transition: color .3s;
& :hover {
color: #1890ff;
color: #13c2c2;
}
}
.register {

View File

@ -76,8 +76,8 @@ module.exports = {
less: {
modifyVars: {
/* less 变量覆盖,用于自定义 ant design 主题 */
'primary-color': '#1890FF',
'link-color': '#1890FF',
'primary-color': '#13c2c2',
'link-color': '#13c2c2',
'border-radius-base': '4px',
},
javascriptEnabled: true,

View File

@ -4765,6 +4765,19 @@
"jsbn" "~0.1.0"
"safer-buffer" "^2.1.0"
"echarts-wordcloud@^2.1.0":
"integrity" "sha512-Kt1JmbcROgb+3IMI48KZECK2AP5lG6bSsOEs+AsuwaWJxQom31RTNd6NFYI01E/YaI1PFZeueaupjlmzSQasjQ=="
"resolved" "https://registry.npmmirror.com/echarts-wordcloud/-/echarts-wordcloud-2.1.0.tgz"
"version" "2.1.0"
"echarts@^5.0.1", "echarts@^5.5.0":
"integrity" "sha512-rNYnNCzqDAPCr4m/fqyUFv7fD9qIsd50S6GDFgO1DxZhncCsNsG7IfUlAlvZe5oSEQxtsjnHiUuppzccry93Xw=="
"resolved" "https://registry.npmmirror.com/echarts/-/echarts-5.5.0.tgz"
"version" "5.5.0"
dependencies:
"tslib" "2.3.0"
"zrender" "5.5.0"
"ee-first@1.1.1":
"integrity" "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0="
"resolved" "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz"
@ -11554,6 +11567,11 @@
"resolved" "https://registry.npmjs.org/tslib/-/tslib-1.13.0.tgz"
"version" "1.13.0"
"tslib@2.3.0":
"integrity" "sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg=="
"resolved" "https://registry.npmmirror.com/tslib/-/tslib-2.3.0.tgz"
"version" "2.3.0"
"tty-browserify@0.0.0":
"integrity" "sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY="
"resolved" "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz"
@ -12633,3 +12651,10 @@
"is-ci" "^1.0.10"
"normalize-path" "^1.0.0"
"strip-indent" "^2.0.0"
"zrender@5.5.0":
"integrity" "sha512-O3MilSi/9mwoovx77m6ROZM7sXShR/O/JIanvzTwjN3FORfLSr81PsUGd7jlaYOeds9d8tw82oP44+3YucVo+w=="
"resolved" "https://registry.npmmirror.com/zrender/-/zrender-5.5.0.tgz"
"version" "5.5.0"
dependencies:
"tslib" "2.3.0"