Commit 2d84963a authored by 沈翠玲's avatar 沈翠玲

数据大屏

parent 6decb858
......@@ -6,4 +6,8 @@ export const getMapByTenant = (params) => {
// 保存客户
// export const saveCustomer = (data) => {
// return request.post('/customer/save', data);
// };
\ No newline at end of file
// };
// 产品回款率
export const getReturnRateByPlatform = (params) => {
return request.get('/Loan/getReturnRateByPlatform', params);
};
\ No newline at end of file
import request from '@/utils/http/index';
export const saveDepartment = (data) => {
return request.post('/department/save', data);
};
export const getdepartmentTree = (params) => {
return request.get('/department/departmentTree', params);
};
export const batchDeleteByIds = (ids) => {
return request.get('/department/batchDeleteByIds', { ids });
};
......@@ -52,7 +52,7 @@ const option: ECOption = {
series: [
{
zlevel: 1,
name: "案人年龄比例",
name: "案人年龄比例",
type: "pie",
selectedMode: "single",
radius: [50, 90],
......
<template>
<!-- 年度使用 -->
<div class="echarts">
<ECharts :option="option" :resize="false" />
</div>
</template>
<script setup lang="ts">
<script setup>
import ECharts from "@/components/ECharts/index.vue";
import { ECOption } from "@/components/ECharts/config";
import { ranking1, ranking2, ranking3, ranking4 } from "../assets/ranking-icon";
import echarts from "@/components/ECharts/config";
import { getReturnRateByPlatform } from '@/api/dataScreen';
interface ChartProp {
label: string;
value: string[];
var salvProName =["西南调解中心","雄安调解中心","大同调解中心","成都调解中心"];
var salvProValue =[400000,39500, 5000, 4000, 3000];
var salvProMax =[];//背景按最大值
for (let i = 0; i < salvProValue.length; i++) {
salvProMax.push(salvProValue[0])
}
const gradientColors = ["rgba(254, 219, 101,0.1)", "rgba(0, 122, 254,0.1)", "rgba(255, 75, 122, 0.1)"];
const annualData = [
{
label: new Date().getFullYear() - 1 + "年",
value: ["20000", "19954", "19858", "21010", "20240", "20340", "20148", "20180", "20170", "19850", "20240", "20189"]
},
{
label: new Date().getFullYear() + "年",
value: ["25140", "24190"]
}
];
const colors = ["#1089E7", "#F57474", "#56D0E3", "#F8B448", "#8B78F6"];
const data = {
data: annualData,
unit: annualData.map(val => val.label),
columns: ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12"],
colors: ["#FFA600", "#007AFE", "#FF4B7A"]
};
const option: ECOption = {
tooltip: {
trigger: "axis",
axisPointer: {
type: "none"
const option = {
grid: {
left: '2%',
right: '2%',
bottom: '2%',
top: '2%',
containLabel: true
},
borderWidth: 0,
padding: 0,
backgroundColor: "transparent",
formatter: (params: any) => {
let str = "";
params.forEach((val: { color: string; seriesName: string; data: number }) => {
str += `
<div class="year-item">
<span class="year-dot" style="background-color: ${val.color};"></span>
<span class="year-name">${val.seriesName}</span>
<span class="year-value">${val.data >= 10000 ? (val.data / 10000).toFixed(2) + "w" : val.data}</span>
</div>
`;
});
const dom = `
<div class="annual-tooltip">
<span class="annual-month">${params[0].dataIndex + 1}月</span>
<div class="annual-list">
${str}
</div>
</div>
`;
return dom;
}
},
legend: {
right: "2%",
top: "0%",
itemWidth: 15,
itemHeight: 6,
align: "auto",
icon: "rect",
itemGap: 15,
textStyle: {
color: "#ebebf0"
}
},
grid: {
top: "20%",
left: "40",
right: "4%",
bottom: "15%"
},
xAxis: [
{
name: "(月份)",
type: "category",
boundaryGap: false,
axisLine: {
show: true,
lineStyle: {
color: "#233653"
}
},
axisLabel: {
color: "#7ec7ff",
padding: 0,
fontSize: 12,
formatter: function (data) {
return data;
}
},
splitLine: {
show: false,
lineStyle: {
color: "#192a44"
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'none'
},
formatter: function(params) {
return params[0].name + ' : ' + params[0].value
}
},
axisTick: {
show: false
},
data: data.columns
}
],
yAxis: {
name: "(案件)",
nameTextStyle: {
color: "#D6DFEA",
fontSize: 12,
padding: [0, 30, 0, 0]
},
minInterval: 1,
splitNumber: 5,
splitLine: {
show: false,
lineStyle: {
color: "#192a44"
}
},
axisLine: {
show: true,
lineStyle: {
color: "#233653"
}
},
axisLabel: {
show: true,
color: "#B9D6D6",
padding: 0
xAxis: {
show: false,
type: 'value'
},
axisTick: {
show: false
}
},
series: data.data.map((val: ChartProp, index: number) => {
return {
name: val.label,
type: "line",
symbol: "circle",
showSymbol: false,
smooth: true,
lineStyle: {
width: 1,
color: data.colors[index],
borderColor: data.colors[index]
},
itemStyle: {
color: data.colors[index],
borderColor: "#646ace",
borderWidth: 2
},
tooltip: {
show: true
},
areaStyle: {
color: {
type: "linear",
x: 0,
y: 0,
x2: 0,
y2: 1,
colorStops: [
{
offset: 0,
color: data.colors[index]
yAxis: [{
type: 'category',
inverse: true,
axisLabel: {
show: true,
textStyle: {
color: '#fff'
},
},
splitLine: {
show: false
},
axisTick: {
show: false
},
axisLine: {
show: false
},
data: salvProName
}, {
type: 'category',
inverse: true,
axisTick: 'none',
axisLine: 'none',
show: true,
axisLabel: {
textStyle: {
color: '#ffffff',
fontSize: '12'
},
{
offset: 1,
color: gradientColors[index]
}
],
global: false
},
shadowColor: "rgba(25,163,223, 0.3)",
shadowBlur: 20
},
data: val.value
};
})
data:salvProValue
}],
series: [{
name: '值',
type: 'bar',
zlevel: 1,
itemStyle: {
normal: {
barBorderRadius: 30,
color: new echarts.graphic.LinearGradient(0, 0, 1, 0, [{
offset: 0,
color: 'rgb(57,89,255,1)'
}, {
offset: 1,
color: 'rgb(46,200,207,1)'
}]),
},
},
barWidth: 20,
data: salvProValue
},
{
name: '背景',
type: 'bar',
barWidth: 20,
barGap: '-100%',
data: salvProMax,
itemStyle: {
normal: {
color: 'rgba(24,31,68,1)',
barBorderRadius: 30,
}
},
},
]
};
</script>
<style lang="scss" scoped>
.echarts {
width: 100%;
height: 100%;
height: calc(100% - 56px);
}
:deep(.annual-tooltip) {
.echarts-header {
box-sizing: border-box;
width: 206px;
height: 103px;
padding: 5px 20px;
background: url("../images/contrast-bg.png") no-repeat;
display: flex;
height: 36px;
margin: 10px 10px 0;
line-height: 36px;
background: url("../images/rankingChart-bg.png") no-repeat;
background-size: 100% 100%;
transform: scale(1.5);
.annual-month {
display: inline-block;
margin-bottom: 2px;
font-size: 10px;
color: #03b8e2;
//
}
.annual-list {
display: flex;
flex-direction: column;
width: 100%;
.year-item {
display: flex;
align-items: center;
width: 100%;
height: 22px;
.year-dot {
width: 5px;
height: 5px;
margin: 0 2px;
border-radius: 50%;
}
.year-name,
.year-value {
font-size: 10px;
color: #03b8e2;
}
.year-name {
margin: 0 2px;
}
.year-value {
display: inline-block;
width: 25%;
}
span {
width: 18%;
margin-left: 4px;
font-size: 14px;
font-weight: bold;
color: #fdbc52;
text-align: center;
&:nth-child(2) {
margin-left: 4px;
}
&:last-child {
width: 20%;
margin-left: 60px;
}
}
}
......
......@@ -102,7 +102,7 @@ const option = computed(() => {
params.data.tenants.forEach(ele => {
html = html + '<br /><br />' + ele.tenantName + '<br />案件金额:' + ele.commissionAmount
html = html + '<br />' + '案件数:' + ele.caseNum
html = html + '<br />' + '案人数:' + ele.borrowNum
html = html + '<br />' + '案人数:' + ele.borrowNum
})
}
return html
......
<template>
<!-- 热门板块 -->
<div class="echarts-header">
<span>排名</span>
<span>调解中心</span>
<span>案件情况</span>
</div>
<div class="echarts">
<ECharts :option="option" :resize="false" />
</div>
</template>
<script setup lang="ts">
<script setup>
import ECharts from "@/components/ECharts/index.vue";
import { ECOption } from "@/components/ECharts/config";
import { ranking1, ranking2, ranking3, ranking4 } from "../assets/ranking-icon";
import echarts from "@/components/ECharts/config";
import { getReturnRateByPlatform } from '@/api/dataScreen';
interface ChartProp {
name: string;
value: number;
percentage: string;
maxValue: number;
var salvProName =["还呗","360借条"];
var salvProValue =[70,65];
var salvProMax =[];//背景按最大值
for (let i = 0; i < salvProValue.length; i++) {
salvProMax.push(salvProValue[0])
}
const data = [
{
value: 7587,
name: "哈尔滨",
percentage: "78%",
maxValue: 10000
},
{
value: 5231,
name: "青岛",
percentage: "69%",
maxValue: 10000
},
{
value: 4212,
name: "成都",
percentage: "81%",
maxValue: 10000
},
{
value: 3923,
name: "石家庄",
percentage: "65%",
maxValue: 10000
},
{
value: 3409,
name: "西安",
percentage: "59%",
maxValue: 10000
}
];
const colors = ["#1089E7", "#F57474", "#56D0E3", "#F8B448", "#8B78F6"];
const option: ECOption = {
grid: {
top: "5%",
left: "7%",
right: "4%",
bottom: "1%",
containLabel: true
},
xAxis: {
type: "value",
axisLine: {
show: false,
lineStyle: {
color: "white"
}
},
nameGap: 1,
splitLine: {
show: false
const option = {
grid: {
left: '2%',
right: '2%',
bottom: '2%',
top: '2%',
containLabel: true
},
axisTick: {
show: false
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'none'
},
formatter: function(params) {
return params[0].name + ' : ' + params[0].value
}
},
axisLabel: {
show: false,
fontSize: 16
xAxis: {
show: false,
type: 'value'
},
triggerEvent: false
},
yAxis: [
{
show: true,
data: data.map((val: ChartProp) => val.name),
inverse: true,
axisLine: {
show: false
},
splitLine: {
show: false
},
axisTick: {
show: false
},
axisLabel: {
color: "#fff",
formatter: (value: string) => {
let str = value.length > 6 ? value.slice(0, 6) + "..." : value;
let index = data.map((item: ChartProp) => item.name).indexOf(value) + 1;
return ["{" + (index > 3 ? "lg" : "lg" + index) + "|NO." + index + "}", "{title|" + str + "}"].join(" ");
},
rich: {
lg1: {
width: 60,
backgroundColor: {
image: ranking1
yAxis: [{
type: 'category',
inverse: true,
axisLabel: {
show: true,
textStyle: {
color: '#fff'
},
color: "#fff",
align: "center",
height: 20,
fontSize: 13
},
lg2: {
width: 60,
backgroundColor: {
image: ranking2
},
splitLine: {
show: false
},
axisTick: {
show: false
},
axisLine: {
show: false
},
data: salvProName
}, {
type: 'category',
inverse: true,
axisTick: 'none',
axisLine: 'none',
show: true,
axisLabel: {
textStyle: {
color: '#ffffff',
fontSize: '12'
},
color: "#fff",
align: "center",
height: 20,
fontSize: 13
},
lg3: {
width: 60,
backgroundColor: {
image: ranking3
},
data:salvProValue
}],
series: [{
name: '值',
type: 'bar',
zlevel: 1,
itemStyle: {
normal: {
barBorderRadius: 30,
color: new echarts.graphic.LinearGradient(0, 0, 1, 0, [{
offset: 0,
color: 'rgb(57,89,255,1)'
}, {
offset: 1,
color: 'rgb(46,200,207,1)'
}]),
},
},
color: "#fff",
align: "center",
height: 20,
fontSize: 13
},
lg: {
width: 60,
backgroundColor: {
image: ranking4
barWidth: 20,
data: salvProValue
},
{
name: '背景',
type: 'bar',
barWidth: 20,
barGap: '-100%',
data: salvProMax,
itemStyle: {
normal: {
color: 'rgba(24,31,68,1)',
barBorderRadius: 30,
}
},
color: "#fff",
align: "center",
height: 20,
fontSize: 13
},
title: {
width: 60,
fontSize: 13,
align: "center",
padding: [0, 10, 0, 15]
}
}
},
triggerEvent: false
},
{
show: true,
inverse: true,
data,
axisLabel: {
fontSize: 14,
color: "#fff",
margin: 20,
formatter: (value: number) => {
return value >= 10000 ? (value / 10000).toFixed(2) + "w" : value + "";
}
},
axisLine: {
show: false
},
splitLine: {
show: false
},
axisTick: {
show: false
},
triggerEvent: false
}
],
series: [
{
name: "条",
type: "bar",
yAxisIndex: 0,
data,
barWidth: 12,
itemStyle: {
borderRadius: 30,
color: function (params) {
let num = colors.length;
return colors[params.dataIndex % num];
}
},
label: {
show: true,
position: [12, 0],
lineHeight: 14,
color: "#fff",
formatter: params => {
return (params.data as ChartProp).percentage;
}
}
},
{
name: "框",
type: "bar",
yAxisIndex: 1,
data: data.map((val: ChartProp) => {
if (!val.maxValue) return 5;
return val.maxValue;
}),
barWidth: 18,
itemStyle: {
color: "none",
borderColor: "#00c1de",
borderWidth: 1,
borderRadius: 15
},
silent: true
}
]
},
]
};
</script>
<style lang="scss" scoped>
......
<template>
<!-- 男女比例 -->
<div class="ratio-main">
<div class="ratio-header">
<div class="man">
<span>男士</span>
<img src="../images/man.png" alt="" />
</div>
<div class="woman">
<span>女士</span>
<img src="../images/woman.png" alt="" />
</div>
</div>
<!-- echarts -->
<div class="echarts">
<ECharts :option="option" :resize="false" />
</div>
<!-- 平台来源 -->
<div class="echarts">
<ECharts :option="option" :resize="false" />
</div>
</template>
<script setup lang="ts">
<script setup >
import ECharts from "@/components/ECharts/index.vue";
import { ECOption } from "@/components/ECharts/config";
import echarts from "@/components/ECharts/config";
interface ChartProp {
man: number;
woman: number;
}
/**
*
* 作者: GhostCat
* 博客: https://gcat.cc
* 描述: 双折线图
*
*/
let data: ChartProp = {
man: 0.6,
woman: 0.4
};
const option: ECOption = {
xAxis: {
type: "value",
show: false
},
grid: {
left: 0,
top: "30px",
bottom: 0,
right: 0
},
yAxis: [
{
type: "category",
position: "left",
data: ["男生"],
axisTick: {
show: false
},
axisLine: {
show: false
},
axisLabel: {
show: false
}
let xLabel = ['西南调解中心', '雄安调解中心', '成都调解中心', '大同调解中心']
let goToSchool = ["40", "60", "22", "85"]
let goOutSchool = ["20", "50", "12", "65"]
const option = {
tooltip: {
trigger: 'axis'
},
{
type: "category",
position: "right",
data: ["女士"],
axisTick: {
show: false
},
axisLine: {
legend: {
show: false
},
axisLabel: {
show: false,
padding: [0, 0, 40, -60],
fontSize: 12,
lineHeight: 60,
color: "rgba(255, 255, 255, 0.9)",
formatter: "{value}" + data.woman * 100 + "%",
rich: {
a: {
color: "transparent",
lineHeight: 30,
fontFamily: "digital",
fontSize: 12
}
}
}
}
],
series: [
{
type: "bar",
barWidth: 20,
data: [data.man],
z: 20,
itemStyle: {
borderRadius: 10,
color: "#007AFE"
},
label: {
show: true,
color: "#E7E8ED",
position: "insideLeft",
offset: [0, -20],
fontSize: 12,
formatter: () => {
return `男士 ${data.man * 100}%`;
}
}
},
{
type: "bar",
barWidth: 20,
data: [1],
barGap: "-100%",
itemStyle: {
borderRadius: 10,
color: "#FF4B7A"
},
label: {
show: true,
color: "#E7E8ED",
position: "insideRight",
offset: [0, -20],
fontSize: 12,
formatter: () => {
return `女士 ${data.woman * 100}%`;
}
}
}
]
grid: {
top: '20%',
left: '10%',
right: '10%',
bottom: '15%',
containLabel: true
},
xAxis: [{
type: 'category',
boundaryGap: false,
axisLine: { //坐标轴轴线相关设置。数学上的x轴
show: true,
lineStyle: {
color: '#233653'
},
},
axisLabel: { //坐标轴刻度标签的相关设置
textStyle: {
color: '#7ec7ff',
padding: 16,
fontSize: 14
},
formatter: function(data) {
return data
}
},
splitLine: {
show: true,
lineStyle: {
color: '#192a44'
},
},
axisTick: {
show: false,
},
data: xLabel
}],
yAxis: [{
name: '回款率',
nameTextStyle: {
color: "#7ec7ff",
fontSize: 16,
padding: 10
},
min: 0,
max: 100,
splitLine: {
show: true,
lineStyle: {
color: '#192a44'
},
},
axisLine: {
show: true,
lineStyle: {
color: "#233653"
}
},
axisLabel: {
show: true,
textStyle: {
color: '#7ec7ff',
padding: 16
},
formatter: function(value) {
if (value === 0) {
return value
}
return value
}
},
axisTick: {
show: false,
},
}],
series: [{
name: '回款率',
type: 'line',
symbol: 'circle', // 默认是空心圆(中间是白色的),改成实心圆
showAllSymbol: true,
symbolSize: 0,
smooth: true,
lineStyle: {
normal: {
width: 5,
color: "rgba(10,219,250,1)", // 线条颜色
},
borderColor: 'rgba(0,0,0,.4)',
},
itemStyle: {
color: "rgba(10,219,250,1)",
borderColor: "#646ace",
borderWidth: 2
},
tooltip: {
show: true
},
areaStyle: { //区域填充样式
normal: {
//线性渐变,前4个参数分别是x0,y0,x2,y2(范围0~1);相当于图形包围盒中的百分比。如果最后一个参数是‘true’,则该四个值是绝对像素位置。
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{
offset: 0,
color: "rgba(10,219,250,.3)"
},
{
offset: 1,
color: "rgba(10,219,250,0)"
}
], false),
shadowColor: 'rgba(10,219,250,.5)', //阴影颜色
shadowBlur: 20 //shadowBlur设图形阴影的模糊大小。配合shadowColor,shadowOffsetX/Y, 设置图形的阴影效果。
}
},
data: goToSchool
}]
};
</script>
<style lang="scss" scoped>
.ratio-main {
box-sizing: border-box;
.echarts {
width: 100%;
height: 100%;
padding: 40px 65px;
.ratio-header {
display: flex;
justify-content: space-between;
width: 100%;
height: 115px;
.man,
.woman {
display: flex;
flex-direction: column;
align-items: center;
width: 110px;
height: 115px;
background: url("../images/man-bg.png") no-repeat;
background-size: 100% 100%;
img {
width: 60px;
height: 60px;
margin-top: 20px;
}
span {
margin-top: 2px;
font-size: 13px;
color: #ffffff;
}
}
.woman {
background: url("../images/woman-bg.png") no-repeat;
}
}
.echarts {
width: 100%;
height: calc(100% - 115px);
}
}
</style>
......@@ -5,282 +5,151 @@
</div>
</template>
<script setup lang="ts">
<script setup >
import ECharts from "@/components/ECharts/index.vue";
import { ECOption } from "@/components/ECharts/config";
import echarts from "@/components/ECharts/config";
interface ChartProp {
name: string;
value: number;
percentage: string;
}
/**
*
* 作者: GhostCat
* 博客: https://gcat.cc
* 描述: 双折线图
*
*/
const data = [
{ value: 680, name: "东岸科技", percentage: "68%" },
{ value: 190, name: "淮南紫石", percentage: "19%" },
{ value: 100, name: "泰华合众", percentage: "10%" },
{ value: 30, name: "其他", percentage: "3%" }
];
const option: ECOption = {
grid: {
top: "0%",
left: "2%",
right: "2%",
bottom: "0%"
},
tooltip: {
trigger: "item",
formatter: "{b} : {c}件"
},
legend: {
show: true,
top: "middle",
left: "20px",
icon: "circle",
orient: "vertical",
align: "auto",
itemWidth: 10,
textStyle: {
color: "#fff"
},
itemGap: 20,
formatter: function (name: string) {
let text = "";
data.forEach((val: ChartProp) => {
if (val.name === name) {
text = name + " --- " + val.percentage;
}
});
return text;
let xLabel = ['西南调解中心', '雄安调解中心', '成都调解中心', '大同调解中心']
let goToSchool = ["40", "60", "22", "85"]
let goOutSchool = ["20", "50", "12", "65"]
const option = {
tooltip: {
trigger: 'axis'
},
data: data.map((val: ChartProp) => val.name)
},
series: [
{
type: "pie",
radius: ["60%", "85%"],
center: ["68%", "45%"],
color: ["#0E7CE2", "#FF8352", "#E271DE", "#F8456B", "#00FFFF", "#4AEAB0"],
itemStyle: {
borderColor: "#031845",
borderWidth: 10
},
data: data,
labelLine: {
show: false
},
label: {
legend: {
show: false
}
},
{
type: "pie",
radius: ["20%", "28%"],
center: ["68%", "45%"],
color: ["#ffffff", "red"],
startAngle: 105,
data: [
{
value: 30,
name: "",
itemStyle: {
color: "transparent"
}
},
{
value: 5,
name: "",
itemStyle: {
color: "transparent"
}
},
{
value: 65,
name: "ddd",
itemStyle: {
color: "#ffffff"
}
}
],
silent: true,
labelLine: {
show: false
},
label: {
show: false
}
grid: {
top: '20%',
left: '10%',
right: '10%',
bottom: '15%',
containLabel: true
},
{
type: "pie",
radius: [0, "30%"],
center: ["68%", "45%"],
startAngle: 90,
data: [
{
value: 25,
name: "1",
itemStyle: {
color: "transparent",
borderWidth: 4,
borderColor: "#ffffff"
}
xAxis: [{
type: 'category',
boundaryGap: false,
axisLine: { //坐标轴轴线相关设置。数学上的x轴
show: true,
lineStyle: {
color: '#233653'
},
},
{
value: 75,
name: "2",
itemStyle: {
color: "transparent"
}
}
],
selectedOffset: 10,
silent: true,
labelLine: {
show: false
},
label: {
show: false
}
},
{
type: "pie",
radius: ["96%", "97%"],
center: ["68%", "45%"],
color: ["#007afe", "transparent", "#007afe", "transparent", "#007afe", "transparent"],
data: [
{ value: 17, name: "11" },
{ value: 17, name: "22" },
{ value: 17, name: "33" },
{ value: 17, name: "44" },
{ value: 17, name: "55" },
{ value: 17, name: "66" }
],
silent: true,
labelLine: { show: false },
label: { show: false }
},
{
type: "pie",
zlevel: 0,
silent: true,
radius: ["45%", "46%"],
center: ["68%", "45%"],
z: 10,
label: { show: false },
labelLine: { show: false },
data: new Array(150).fill("").map((_val: string, index: number) => {
if (index % 3 === 0) {
return {
name: (index + 1).toString(),
value: 10,
itemStyle: {
color: "#fff",
borderWidth: 0,
borderColor: "rgba(0,0,0,0)"
}
};
} else {
return {
name: (index + 1).toString(),
value: 25,
itemStyle: {
color: "rgba(0,0,0,0)",
borderWidth: 0,
borderColor: "rgba(0,0,0,0)"
}
};
}
})
},
{
type: "pie",
zlevel: 0,
silent: true,
radius: ["58%", "60%"],
center: ["68%", "45%"],
z: 10,
startAngle: 90,
label: { show: false },
color: ["red", "blue", "red", "blue"],
labelLine: { show: false },
data: [
{
name: "r1",
value: 25,
itemStyle: {
color: {
type: "linear",
x: 0,
y: 0,
x2: 0,
y2: 1,
colorStops: [
{ offset: 0, color: "rgba(51,149,191,0.5)" },
{ offset: 1, color: "rgba(51,149,191,0)" }
],
global: false
axisLabel: { //坐标轴刻度标签的相关设置
textStyle: {
color: '#7ec7ff',
padding: 16,
fontSize: 14
},
formatter: function(data) {
return data
}
}
},
{
name: "r2",
value: 25,
itemStyle: {
color: {
type: "linear",
x: 0,
y: 0,
x2: 0,
y2: 1,
colorStops: [
{ offset: 0, color: "rgba(0,0,0,0)" },
{ offset: 1, color: "rgba(51,149,191,0.5)" }
],
global: false
splitLine: {
show: true,
lineStyle: {
color: '#192a44'
},
},
axisTick: {
show: false,
},
data: xLabel
}],
yAxis: [{
name: '回款率',
nameTextStyle: {
color: "#7ec7ff",
fontSize: 16,
padding: 10
},
min: 0,
max: 100,
splitLine: {
show: true,
lineStyle: {
color: '#192a44'
},
},
axisLine: {
show: true,
lineStyle: {
color: "#233653"
}
}
},
{
name: "r3",
value: 25,
itemStyle: {
color: {
type: "linear",
x: 0,
y: 0,
x2: 0,
y2: 1,
colorStops: [
{ offset: 0, color: "rgba(51,149,191,0)" },
{ offset: 1, color: "rgba(51,149,191,0.5)" }
],
global: false
axisLabel: {
show: true,
textStyle: {
color: '#7ec7ff',
padding: 16
},
formatter: function(value) {
if (value === 0) {
return value
}
return value
}
}
},
{
name: "r4",
value: 25,
itemStyle: {
color: {
type: "linear",
x: 0,
y: 0,
x2: 0,
y2: 1,
colorStops: [
{ offset: 0, color: "rgba(51,149,191,0.5)" },
{ offset: 1, color: "rgba(0,0,0,0)" }
],
global: false
axisTick: {
show: false,
},
}],
series: [{
name: '回款率',
type: 'line',
symbol: 'circle', // 默认是空心圆(中间是白色的),改成实心圆
showAllSymbol: true,
symbolSize: 0,
smooth: true,
lineStyle: {
normal: {
width: 5,
color: "rgba(25,163,223,1)", // 线条颜色
},
borderColor: 'rgba(0,0,0,.4)',
},
itemStyle: {
color: "rgba(25,163,223,1)",
borderColor: "#646ace",
borderWidth: 2
},
tooltip: {
show: true
},
areaStyle: { //区域填充样式
normal: {
//线性渐变,前4个参数分别是x0,y0,x2,y2(范围0~1);相当于图形包围盒中的百分比。如果最后一个参数是‘true’,则该四个值是绝对像素位置。
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{
offset: 0,
color: "rgba(25,163,223,.3)"
},
{
offset: 1,
color: "rgba(25,163,223, 0)"
}
], false),
shadowColor: 'rgba(25,163,223, 0.5)', //阴影颜色
shadowBlur: 20 //shadowBlur设图形阴影的模糊大小。配合shadowColor,shadowOffsetX/Y, 设置图形的阴影效果。
}
}
}
]
}
]
},
data: goToSchool
}]
};
</script>
<style lang="scss" scoped>
.echarts {
......
<template>
<!-- 实时访问 -->
<div class="actual-total">
<div class="expect-total">历史案人总数<i>389876</i></div>
<div class="actual-total">
<div v-for="(item, index) in actualTotal.split('')" :key="index" class="actual-item">
{{ item }}
</div>
<div class="actual-item"></div>
</div>
</div>
<div class="echarts">
<ECharts :option="option" :resize="false" />
</div>
</template>
<script setup lang="ts">
<script setup>
import { ref } from "vue";
import { ECOption } from "@/components/ECharts/config";
import ECharts from "@/components/ECharts/index.vue";
import echarts from "@/components/ECharts/config";
const actualTotal = ref("216908");
const option = {
title: [
{
text: (0.5 * 100).toFixed(0) + "%",
left: "49%",
top: "35%",
textAlign: "center",
textStyle: {
fontSize: "16",
fontWeight: "normal",
color: "#ffffff",
align: "center",
textBorderColor: "rgba(0, 0, 0, 0)",
textShadowColor: "#000",
textShadowBlur: 0,
textShadowOffsetX: 0,
textShadowOffsetY: 1
}
},
{
text: "清收比例",
left: "49%",
top: "25%",
textAlign: "center",
textStyle: {
fontSize: "15",
fontWeight: "normal",
color: "#ffffff",
align: "center",
textBorderColor: "rgba(0, 0, 0, 0)",
textShadowColor: "#000",
textShadowBlur: 0,
textShadowOffsetX: 0,
textShadowOffsetY: 1
}
}
],
grid: {
top: "0",
left: "0px",
right: "0px",
bottom: "0",
containLabel: true
},
polar: {
radius: ["75%", "85%"],
center: ["50%", "50%"]
},
angleAxis: {
max: 120,
clockwise: false,
axisLine: {
show: false
},
axisTick: {
show: false
},
axisLabel: {
show: false
},
splitLine: {
show: false
},
startAngle: 188
},
radiusAxis: {
type: "category",
show: true,
axisLabel: {
show: false
},
axisLine: {
show: false
},
axisTick: {
show: false
}
},
series: [
{
type: "liquidFill",
radius: "70%",
z: 2,
center: ["50%", "50%"],
data: [0.4, 0.4, 0.4],
itemStyle: {
color: {
type: "linear",
x: 0,
y: 0,
x2: 0,
y2: 1,
colorStops: [
{ offset: 0, color: "#35FAB6" },
{ offset: 1, color: "rgba(40, 209, 247,0.3)" }
],
global: false
}
},
outline: {
borderDistance: 0,
itemStyle: {
borderWidth: 2,
borderColor: "#31d8d5",
shadowBlur: 20,
shadowColor: "#50c1a7"
}
},
label: {
show: false
},
backgroundStyle: {
borderWidth: 1,
color: {
type: "radial",
x: 0.5,
y: 0.5,
r: 0.5,
colorStops: [
{ offset: 0, color: "#0D2648" },
{ offset: 0.8, color: "#0D2648" },
{ offset: 1, color: "#228E7D" }
],
global: false
tooltip: { //提示框组件
trigger: 'axis',
formatter: '{b}<br />{a0}: {c0}<br />{a1}: {c1}',
axisPointer: {
type: 'shadow',
label: {
backgroundColor: '#6a7985'
}
},
textStyle: {
color: '#fff',
fontStyle: 'normal',
fontFamily: '微软雅黑',
fontSize: 12,
}
},
grid: {
left: '1%',
right: '1%',
bottom: '1%',
top:'13%',
// padding:'0 0 10 0',
containLabel: true,
},
legend: {//图例组件,颜色和名字
right:'1%',
top:'5%',
itemGap: 16,
itemWidth: 18,
itemHeight: 10,
data:[{
name:'作业量(日)',
//icon:'image://../wwwroot/js/url2.png', //路径
},
{
name:'作业量(月)',
}],
textStyle: {
color: '#a8aab0',
fontStyle: 'normal',
fontFamily: '微软雅黑',
fontSize: 12,
}
}
},
{
type: "pie",
radius: ["80%", "80%"],
center: ["50%", "50%"],
z: 1,
label: { show: false },
silent: true,
itemStyle: {
borderWidth: 2,
borderType: [8, 10],
borderDashOffset: 15,
borderColor: "#31d8d5",
color: "#11144e",
borderCap: "round"
},
data: [100]
},
{
type: "bar",
data: [55],
z: 10,
coordinateSystem: "polar",
roundCap: true,
color: "#31d8d5"
}
]
} as ECOption;
xAxis: [
{
type: 'category',
// boundaryGap: true,//坐标轴两边留白
data: ['成都调解中心', '石家庄调解中心', '测试调解中心'],
axisLabel: { //坐标轴刻度标签的相关设置。
// interval: 0,//设置为 1,表示『隔一个标签显示一个标签』
// margin:15,
textStyle: {
color: '#078ceb',
fontStyle: 'normal',
fontFamily: '微软雅黑',
fontSize: 12,
},
rotate:50,
},
axisTick:{//坐标轴刻度相关设置。
show: false,
},
axisLine:{//坐标轴轴线相关设置
lineStyle:{
color:'#fff',
opacity:0.2
}
},
splitLine: { //坐标轴在 grid 区域中的分隔线。
show: false,
}
}
],
yAxis: [
{
type: 'value',
splitNumber: 5,
axisLabel: {
textStyle: {
color: '#a8aab0',
fontStyle: 'normal',
fontFamily: '微软雅黑',
fontSize: 12,
}
},
axisLine:{
show: false
},
axisTick:{
show: false
},
splitLine: {
show: true,
lineStyle: {
color: ['#fff'],
opacity:0.06
}
}
}
],
series : [
{
name:'作业量(日)',
type:'bar',
data:[10,15, 30],
barWidth: 10,
barGap:0,//柱间距离
// label: {//图形上的文本标签
// normal: {
// show: true,
// position: 'top',
// textStyle: {
// color: '#a8aab0',
// fontStyle: 'normal',
// fontFamily: '微软雅黑',
// fontSize: 12,
// },
// },
// },
itemStyle: {
normal: {
show: true,
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{
offset: 0,
color: '#5768EF'
}, {
offset: 1,
color: '#5768EF'
}]),
barBorderRadius: 50,
borderWidth: 0,
}
},
},
{
name:'作业量(月)',
type:'bar',
data:[8,5, 25],
barWidth: 10,
barGap:0,//柱间距离
// label: {//图形上的文本标签
// normal: {
// show: true,
// position: 'top',
// textStyle: {
// color: '#a8aab0',
// fontStyle: 'normal',
// fontFamily: '微软雅黑',
// fontSize: 12,
// },
// },
// },
itemStyle: {
normal: {
show: true,
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{
offset: 0,
color: '#69CBF2'
}, {
offset: 1,
color: '#69CBF2'
}]),
barBorderRadius: 50,
borderWidth: 0,
}
},
}
]
};
</script>
<style lang="scss" scoped>
.echarts {
width: 100%;
height: calc(100% - 50px);
height: calc(100%);
}
.actual-total {
position: relative;
......
......@@ -18,23 +18,23 @@
<div class="dataScreen-lf">
<div class="dataScreen-top">
<div class="dataScreen-main-title">
实时在案案人统计
调解中心作业量
</div>
<div class="dataScreen-main-chart">
<!-- <RealTimeAccessChart /> -->
<RealTimeAccessChart />
</div>
</div>
<div class="dataScreen-center">
<div class="dataScreen-main-title">
案人性别比例
调解中心在案回款率
</div>
<div class="dataScreen-main-chart">
<!-- <MaleFemaleRatioChart /> -->
<MaleFemaleRatioChart />
</div>
</div>
<div class="dataScreen-bottom">
<div class="dataScreen-main-title">
案人年龄比例
人年龄比例
</div>
<div class="dataScreen-main-chart">
<AgeRatioChart />
......@@ -42,11 +42,27 @@
</div>
</div>
<div class="dataScreen-ct">
<div class="dataScreen-Number">
<div class="dataScreen-Number flex justify-between">
<div class="number-box">
<p class="number-title text-lg pt-3">案人总数</p>
<p class="number-title text-lg pt-3">案件人数</p>
<p class=" text-xl text-white pt-2">1222 <span class=" text-base text-gray-400"></span></p>
</div>
<div class="number-box ml-2">
<p class="number-title text-lg pt-3">案件总数</p>
<p class=" text-xl text-white pt-2">1222 <span class=" text-base text-gray-400"></span></p>
</div>
<div class="number-box ml-2">
<p class="number-title text-lg pt-3">案件总额</p>
<p class=" text-xl text-white pt-2">122002 <span class=" text-base text-gray-400"></span></p>
</div>
<div class="number-box ml-2">
<p class="number-title text-lg pt-3">回款金额</p>
<p class=" text-xl text-white pt-2">422002 <span class=" text-base text-gray-400"></span></p>
</div>
<div class="number-box ml-2">
<p class="number-title text-lg pt-3">回款率</p>
<p class=" text-xl text-white pt-2">78 <span class=" text-base text-gray-400">%</span></p>
</div>
</div>
<div class="dataScreen-map">
<div class="dataScreen-map-title">调解中心分布点</div>
......@@ -78,7 +94,7 @@
<div class="dataScreen-rg">
<div class="dataScreen-top">
<div class="dataScreen-main-title">
调解中心案件量排名
产品回款率排名
</div>
<div class="dataScreen-main-chart">
<HotPlateChart />
......@@ -86,7 +102,7 @@
</div>
<div class="dataScreen-center">
<div class="dataScreen-main-title">
年度案件量对比
调解中心回款金额
</div>
<div class="dataScreen-main-chart">
<AnnualUseChart />
......@@ -94,7 +110,7 @@
</div>
<div class="dataScreen-bottom">
<div class="dataScreen-main-title">
案源数据统计
调解中心累计回款率
</div>
<div class="dataScreen-main-chart">
<PlatformSourceChart />
......
<template>
<vxe-modal
resize
v-model="showModal"
:title="modalTitle"
@hide="onHide"
width="400px"
show-footer
esc-closable
>
<el-form ref="formRef" inline :model="form" :rules="rules" label-width="80px">
<el-row :gutter="10">
<el-col :span="24">
<el-form-item class="w-full" label="部门名称" prop="name">
<el-input v-model="form.name" placeholder="请输入部门名称" />
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item class="w-full" label="部门编码" prop="code">
<el-input v-model="form.code" placeholder="请输入部门编码" />
</el-form-item>
</el-col>
</el-row>
</el-form>
<template #footer>
<el-button type="default" @click="showModal = false">取消</el-button>
<el-button type="primary" @click="submitForm">提交</el-button>
</template>
</vxe-modal>
</template>
<script setup>
import { computed } from 'vue';
import { ref } from 'vue';
import { saveDepartment } from '@/api/departmentManage';
import { ElMessage } from 'element-plus';
const emits = defineEmits(['success']);
const formRef = ref();
const showModal = ref(false);
const loading = ref(false);
const form = ref({
code: '',
name: '',
parent: {}
});
const rules = ref({
code: { required: true, message: '请输入部门编码', trigger: 'blur' },
name: [
{ required: true, message: '请输入部门名称', trigger: 'blur' }
],
});
const currentdepartment = ref(null);
const isEdit = computed(() => !!currentdepartment.value);
const modalTitle = computed(() => (isEdit.value ? '编辑部门' : '新增部门'));
const submitForm = async () => {
try {
await formRef.value.validate();
loading.value = true;
await saveDepartment(form.value);
ElMessage({
type: 'success',
message: isEdit.value ? '修改成功!' : '添加成功!',
plain: true,
});
emits('success');
showModal.value = false;
} catch {}
loading.value = false;
};
const onHide = () => {
form.value = {
code: '',
name: '',
parent: {}
};
formRef.value.clearValidate();
currentdepartment.value = null;
showModal.value = false;
};
const openModal = (type, department) => {
if (type === 'add') {
department && (form.value.parent = department);
!department && (form.value.parent = {});
currentdepartment.value = null;
} else {
department && (form.value = department);
currentdepartment.value = department;
}
showModal.value = true;
};
defineExpose({
openModal,
});
</script>
<style lang="scss" scoped></style>
\ No newline at end of file
<template>
<div class="card content-box">
<span class="text"> 部门管理(待完善) 🍓🍇🍈🍉</span>
<div>
<ProTable ref="proTable" :config="config" :api="getdepartmentTree" :paramCallback="paramCallback">
<template #left_buttons>
<!-- v-permission="'risk_member_add'" -->
<el-button
type="primary"
:icon="Plus"
@click="addDeparment"
>新增</el-button
>
<!-- <el-button v-permission="'risk_member_del'" type="danger" :icon="Delete" @click="handleDelete"
>删除</el-button
> -->
</template>
</ProTable>
<DepartmentFormModal ref="DepartmentFormModalRef" @success="query" />
</div>
</template>
<script setup name="departmentManage"></script>
<script setup name="departmentManage" lang="jsx">
import DepartmentFormModal from './components/DepartmentFormModal.vue';
import { Delete, Edit, Plus } from '@element-plus/icons-vue';
import { ref,reactive } from 'vue';
import { onMounted } from 'vue';
import { saveDepartment, getdepartmentTree, batchDeleteByIds } from '@/api/departmentManage';
const proTable = ref();
const DepartmentFormModalRef = ref();
const current = ref();
const query = () => proTable.value?.search();
const paramCallback = (param) => {
const obj = JSON.parse(JSON.stringify(param));
obj['staffRole'] = 'risk_control_commissioner'
return obj;
};
const onRadioChange = ({newValue}) => {
current.value = newValue
}
const addDeparment = () => {
DepartmentFormModalRef.value?.openModal('add', current.value)
}
const editDepartment = (row) => {
DepartmentFormModalRef.value?.openModal('edit', row)
}
const handleDelete = () => {
}
const config = reactive({
onRadioChange: onRadioChange,
treeConfig: {
rowField: 'id',
childrenField: 'children'
},
columns: [
{ type: 'radio', width: 60, fixed: 'left' },
{ field: 'name', title: '部门名称', search: { el: 'input', labelWidth: 85 } },
{ field: 'code', title: '部门编码', search: { el: 'input', labelWidth: 85 } },
{
field: 'action',
title: '操作',
fixed: 'right',
slots: {
default: ({ row }) => {
return (
<>
<ElButton link type="primary" icon={Edit} onClick={() => editDepartment(row)}>
编辑
</ElButton>
<ElButton link type="primary" icon={Delete} onClick={() => handleDelete(row)}>
删除
</ElButton>
</>
);
},
},
},
],
});
// 添加
function append(data) {
const newChild = { id: id++, label: 'testtest', children: [] };
if (!data.children) {
data.children = []
}
data.children.push(newChild);
}
// 删除
function remove(node, data) {
const parent = node.parent;
const children = parent.data.children || parent.data;
const index = children.findIndex(d => d.id === data.id);
children.splice(index, 1);
}
// 编辑
function edit(data) {
ElMessageBox.prompt('请输入标题', '编辑', {
confirmButtonText: '确定',
cancelButtonText: '取消',
}).then(({ value }) => {
if (value != null) {
data.label = value;
}
}).catch(() => { });
}
onMounted(() => {
query();
});
</script>
\ No newline at end of file
......@@ -55,8 +55,8 @@ export default defineConfig(({ command, mode }) => {
port: VITE_PORT,
proxy: {
'/api': {
// target: 'http://192.168.31.189:8080',
target: 'http://192.168.31.128:8080',
target: 'http://192.168.31.189:8080',
// target: 'http://192.168.31.128:8080',
// target: 'http://8.152.205.9:8080',
changeOrigin: true,
rewrite: (path) => path.replace(/^\/api/, ''),
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment