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

数据大屏

parent 6decb858
...@@ -7,3 +7,7 @@ export const getMapByTenant = (params) => { ...@@ -7,3 +7,7 @@ export const getMapByTenant = (params) => {
// export const saveCustomer = (data) => { // export const saveCustomer = (data) => {
// return request.post('/customer/save', data); // return request.post('/customer/save', data);
// }; // };
// 产品回款率
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 = { ...@@ -52,7 +52,7 @@ const option: ECOption = {
series: [ series: [
{ {
zlevel: 1, zlevel: 1,
name: "案人年龄比例", name: "案人年龄比例",
type: "pie", type: "pie",
selectedMode: "single", selectedMode: "single",
radius: [50, 90], radius: [50, 90],
......
<template> <template>
<!-- 年度使用 -->
<div class="echarts"> <div class="echarts">
<ECharts :option="option" :resize="false" /> <ECharts :option="option" :resize="false" />
</div> </div>
</template> </template>
<script setup lang="ts"> <script setup>
import ECharts from "@/components/ECharts/index.vue"; 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 { var salvProName =["西南调解中心","雄安调解中心","大同调解中心","成都调解中心"];
label: string; var salvProValue =[400000,39500, 5000, 4000, 3000];
value: string[]; 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 colors = ["#1089E7", "#F57474", "#56D0E3", "#F8B448", "#8B78F6"];
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 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 = { const option = {
grid: {
left: '2%',
right: '2%',
bottom: '2%',
top: '2%',
containLabel: true
},
tooltip: { tooltip: {
trigger: "axis", trigger: 'axis',
axisPointer: { axisPointer: {
type: "none" type: 'none'
},
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: { formatter: function(params) {
right: "2%", return params[0].name + ' : ' + params[0].value
top: "0%",
itemWidth: 15,
itemHeight: 6,
align: "auto",
icon: "rect",
itemGap: 15,
textStyle: {
color: "#ebebf0"
} }
}, },
grid: { xAxis: {
top: "20%", show: false,
left: "40", type: 'value'
right: "4%",
bottom: "15%"
}, },
xAxis: [ yAxis: [{
{ type: 'category',
name: "(月份)", inverse: true,
type: "category", axisLabel: {
boundaryGap: false,
axisLine: {
show: true, show: true,
lineStyle: { textStyle: {
color: "#233653" color: '#fff'
}
}, },
axisLabel: {
color: "#7ec7ff",
padding: 0,
fontSize: 12,
formatter: function (data) {
return data;
}
}, },
splitLine: { splitLine: {
show: false, show: false
lineStyle: {
color: "#192a44"
}
}, },
axisTick: { axisTick: {
show: false 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: { axisLine: {
show: true, show: false
lineStyle: {
color: "#233653"
}
}, },
axisLabel: { data: salvProName
}, {
type: 'category',
inverse: true,
axisTick: 'none',
axisLine: 'none',
show: true, show: true,
color: "#B9D6D6", axisLabel: {
padding: 0 textStyle: {
}, color: '#ffffff',
axisTick: { fontSize: '12'
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]
}, },
data:salvProValue
}],
series: [{
name: '值',
type: 'bar',
zlevel: 1,
itemStyle: { itemStyle: {
color: data.colors[index], normal: {
borderColor: "#646ace", barBorderRadius: 30,
borderWidth: 2 color: new echarts.graphic.LinearGradient(0, 0, 1, 0, [{
},
tooltip: {
show: true
},
areaStyle: {
color: {
type: "linear",
x: 0,
y: 0,
x2: 0,
y2: 1,
colorStops: [
{
offset: 0, offset: 0,
color: data.colors[index] color: 'rgb(57,89,255,1)'
}, {
offset: 1,
color: 'rgb(46,200,207,1)'
}]),
},
},
barWidth: 20,
data: salvProValue
}, },
{ {
offset: 1, name: '背景',
color: gradientColors[index] type: 'bar',
barWidth: 20,
barGap: '-100%',
data: salvProMax,
itemStyle: {
normal: {
color: 'rgba(24,31,68,1)',
barBorderRadius: 30,
} }
],
global: false
}, },
shadowColor: "rgba(25,163,223, 0.3)",
shadowBlur: 20
}, },
data: val.value ]
};
})
}; };
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.echarts { .echarts {
width: 100%; width: 100%;
height: 100%; height: calc(100% - 56px);
} }
:deep(.annual-tooltip) { .echarts-header {
box-sizing: border-box; box-sizing: border-box;
width: 206px;
height: 103px;
padding: 5px 20px;
background: url("../images/contrast-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; display: flex;
align-items: center; height: 36px;
width: 100%; margin: 10px 10px 0;
height: 22px; line-height: 36px;
.year-dot { background: url("../images/rankingChart-bg.png") no-repeat;
width: 5px; background-size: 100% 100%;
height: 5px; span {
margin: 0 2px; width: 18%;
border-radius: 50%; margin-left: 4px;
} font-size: 14px;
.year-name, font-weight: bold;
.year-value { color: #fdbc52;
font-size: 10px; text-align: center;
color: #03b8e2; &:nth-child(2) {
} margin-left: 4px;
.year-name { }
margin: 0 2px; &:last-child {
} width: 20%;
.year-value { margin-left: 60px;
display: inline-block;
width: 25%;
}
} }
} }
} }
......
...@@ -102,7 +102,7 @@ const option = computed(() => { ...@@ -102,7 +102,7 @@ const option = computed(() => {
params.data.tenants.forEach(ele => { params.data.tenants.forEach(ele => {
html = html + '<br /><br />' + ele.tenantName + '<br />案件金额:' + ele.commissionAmount html = html + '<br /><br />' + ele.tenantName + '<br />案件金额:' + ele.commissionAmount
html = html + '<br />' + '案件数:' + ele.caseNum html = html + '<br />' + '案件数:' + ele.caseNum
html = html + '<br />' + '案人数:' + ele.borrowNum html = html + '<br />' + '案人数:' + ele.borrowNum
}) })
} }
return html return html
......
<template> <template>
<!-- 热门板块 -->
<div class="echarts-header">
<span>排名</span>
<span>调解中心</span>
<span>案件情况</span>
</div>
<div class="echarts"> <div class="echarts">
<ECharts :option="option" :resize="false" /> <ECharts :option="option" :resize="false" />
</div> </div>
</template> </template>
<script setup lang="ts"> <script setup>
import ECharts from "@/components/ECharts/index.vue"; import ECharts from "@/components/ECharts/index.vue";
import { ECOption } from "@/components/ECharts/config";
import { ranking1, ranking2, ranking3, ranking4 } from "../assets/ranking-icon"; import { ranking1, ranking2, ranking3, ranking4 } from "../assets/ranking-icon";
import echarts from "@/components/ECharts/config";
import { getReturnRateByPlatform } from '@/api/dataScreen';
interface ChartProp { var salvProName =["还呗","360借条"];
name: string; var salvProValue =[70,65];
value: number; var salvProMax =[];//背景按最大值
percentage: string; for (let i = 0; i < salvProValue.length; i++) {
maxValue: number; 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 colors = ["#1089E7", "#F57474", "#56D0E3", "#F8B448", "#8B78F6"];
const option: ECOption = {
const option = {
grid: { grid: {
top: "5%", left: '2%',
left: "7%", right: '2%',
right: "4%", bottom: '2%',
bottom: "1%", top: '2%',
containLabel: true containLabel: true
}, },
xAxis: { tooltip: {
type: "value", trigger: 'axis',
axisLine: { axisPointer: {
show: false, type: 'none'
lineStyle: {
color: "white"
}
},
nameGap: 1,
splitLine: {
show: false
}, },
axisTick: { formatter: function(params) {
show: false return params[0].name + ' : ' + params[0].value
}
}, },
axisLabel: { xAxis: {
show: false, show: false,
fontSize: 16 type: 'value'
},
triggerEvent: false
}, },
yAxis: [ yAxis: [{
{ type: 'category',
show: true,
data: data.map((val: ChartProp) => val.name),
inverse: true, inverse: true,
axisLine: { axisLabel: {
show: false show: true,
textStyle: {
color: '#fff'
},
}, },
splitLine: { splitLine: {
show: false show: false
...@@ -100,129 +56,56 @@ const option: ECOption = { ...@@ -100,129 +56,56 @@ const option: ECOption = {
axisTick: { axisTick: {
show: false show: false
}, },
axisLabel: { axisLine: {
color: "#fff", show: false
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
},
color: "#fff",
align: "center",
height: 20,
fontSize: 13
},
lg2: {
width: 60,
backgroundColor: {
image: ranking2
},
color: "#fff",
align: "center",
height: 20,
fontSize: 13
},
lg3: {
width: 60,
backgroundColor: {
image: ranking3
},
color: "#fff",
align: "center",
height: 20,
fontSize: 13
},
lg: {
width: 60,
backgroundColor: {
image: ranking4
},
color: "#fff",
align: "center",
height: 20,
fontSize: 13
},
title: {
width: 60,
fontSize: 13,
align: "center",
padding: [0, 10, 0, 15]
}
}
},
triggerEvent: false
}, },
{ data: salvProName
show: true, }, {
type: 'category',
inverse: true, inverse: true,
data, axisTick: 'none',
axisLine: 'none',
show: true,
axisLabel: { axisLabel: {
fontSize: 14, textStyle: {
color: "#fff", color: '#ffffff',
margin: 20, fontSize: '12'
formatter: (value: number) => {
return value >= 10000 ? (value / 10000).toFixed(2) + "w" : value + "";
}
}, },
axisLine: {
show: false
}, },
splitLine: { data:salvProValue
show: false }],
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)'
}]),
}, },
axisTick: {
show: false
}, },
triggerEvent: false barWidth: 20,
} data: salvProValue
], },
series: [
{ {
name: "条", name: '背景',
type: "bar", type: 'bar',
yAxisIndex: 0, barWidth: 20,
data, barGap: '-100%',
barWidth: 12, data: salvProMax,
itemStyle: { itemStyle: {
borderRadius: 30, normal: {
color: function (params) { color: 'rgba(24,31,68,1)',
let num = colors.length; barBorderRadius: 30,
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> </script>
......
<template> <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"> <div class="echarts">
<ECharts :option="option" :resize="false" /> <ECharts :option="option" :resize="false" />
</div> </div>
</div>
</template> </template>
<script setup lang="ts"> <script setup >
import ECharts from "@/components/ECharts/index.vue"; 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 = { let xLabel = ['西南调解中心', '雄安调解中心', '成都调解中心', '大同调解中心']
xAxis: { let goToSchool = ["40", "60", "22", "85"]
type: "value", let goOutSchool = ["20", "50", "12", "65"]
const option = {
tooltip: {
trigger: 'axis'
},
legend: {
show: false show: false
}, },
grid: { grid: {
left: 0, top: '20%',
top: "30px", left: '10%',
bottom: 0, right: '10%',
right: 0 bottom: '15%',
containLabel: true
}, },
yAxis: [ xAxis: [{
{ type: 'category',
type: "category", boundaryGap: false,
position: "left", axisLine: { //坐标轴轴线相关设置。数学上的x轴
data: ["男生"], show: true,
axisTick: { lineStyle: {
show: false color: '#233653'
}, },
axisLine: {
show: false
}, },
axisLabel: { axisLabel: { //坐标轴刻度标签的相关设置
show: false textStyle: {
color: '#7ec7ff',
padding: 16,
fontSize: 14
},
formatter: function(data) {
return data
} }
}, },
{ splitLine: {
type: "category", show: true,
position: "right", lineStyle: {
data: ["女士"], color: '#192a44'
axisTick: {
show: false
}, },
axisLine: {
show: false
}, },
axisLabel: { axisTick: {
show: false, show: false,
padding: [0, 0, 40, -60], },
fontSize: 12, data: xLabel
lineHeight: 60, }],
color: "rgba(255, 255, 255, 0.9)", yAxis: [{
formatter: "{value}" + data.woman * 100 + "%", name: '回款率',
rich: { nameTextStyle: {
a: { color: "#7ec7ff",
color: "transparent", fontSize: 16,
lineHeight: 30, padding: 10
fontFamily: "digital", },
fontSize: 12 min: 0,
} max: 100,
} splitLine: {
} show: true,
lineStyle: {
color: '#192a44'
},
},
axisLine: {
show: true,
lineStyle: {
color: "#233653"
} }
],
series: [
{
type: "bar",
barWidth: 20,
data: [data.man],
z: 20,
itemStyle: {
borderRadius: 10,
color: "#007AFE"
}, },
label: { axisLabel: {
show: true, show: true,
color: "#E7E8ED", textStyle: {
position: "insideLeft", color: '#7ec7ff',
offset: [0, -20], padding: 16
fontSize: 12, },
formatter: () => { formatter: function(value) {
return `男士 ${data.man * 100}%`; if (value === 0) {
return value
} }
return value
} }
}, },
{ axisTick: {
type: "bar", show: false,
barWidth: 20, },
data: [1], }],
barGap: "-100%", 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: { itemStyle: {
borderRadius: 10, color: "rgba(10,219,250,1)",
color: "#FF4B7A" borderColor: "#646ace",
borderWidth: 2
}, },
label: { tooltip: {
show: true, show: true
color: "#E7E8ED", },
position: "insideRight", areaStyle: { //区域填充样式
offset: [0, -20], normal: {
fontSize: 12, //线性渐变,前4个参数分别是x0,y0,x2,y2(范围0~1);相当于图形包围盒中的百分比。如果最后一个参数是‘true’,则该四个值是绝对像素位置。
formatter: () => { color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{
return `女士 ${data.woman * 100}%`; 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> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.ratio-main { .echarts {
box-sizing: border-box;
width: 100%; width: 100%;
height: 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> </style>
...@@ -5,282 +5,151 @@ ...@@ -5,282 +5,151 @@
</div> </div>
</template> </template>
<script setup lang="ts"> <script setup >
import ECharts from "@/components/ECharts/index.vue"; 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; * 作者: GhostCat
percentage: string; * 博客: 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 = { let xLabel = ['西南调解中心', '雄安调解中心', '成都调解中心', '大同调解中心']
grid: { let goToSchool = ["40", "60", "22", "85"]
top: "0%", let goOutSchool = ["20", "50", "12", "65"]
left: "2%",
right: "2%", const option = {
bottom: "0%"
},
tooltip: { tooltip: {
trigger: "item", trigger: 'axis'
formatter: "{b} : {c}件"
}, },
legend: { legend: {
show: false
},
grid: {
top: '20%',
left: '10%',
right: '10%',
bottom: '15%',
containLabel: true
},
xAxis: [{
type: 'category',
boundaryGap: false,
axisLine: { //坐标轴轴线相关设置。数学上的x轴
show: true, show: true,
top: "middle", lineStyle: {
left: "20px", color: '#233653'
icon: "circle", },
orient: "vertical", },
align: "auto", axisLabel: { //坐标轴刻度标签的相关设置
itemWidth: 10,
textStyle: { textStyle: {
color: "#fff" color: '#7ec7ff',
padding: 16,
fontSize: 14
}, },
itemGap: 20, formatter: function(data) {
formatter: function (name: string) { return data
let text = "";
data.forEach((val: ChartProp) => {
if (val.name === name) {
text = name + " --- " + val.percentage;
} }
});
return text;
}, },
data: data.map((val: ChartProp) => val.name) splitLine: {
show: true,
lineStyle: {
color: '#192a44'
}, },
series: [
{
type: "pie",
radius: ["60%", "85%"],
center: ["68%", "45%"],
color: ["#0E7CE2", "#FF8352", "#E271DE", "#F8456B", "#00FFFF", "#4AEAB0"],
itemStyle: {
borderColor: "#031845",
borderWidth: 10
}, },
data: data, axisTick: {
labelLine: { show: false,
show: false
}, },
label: { data: xLabel
show: false }],
} yAxis: [{
name: '回款率',
nameTextStyle: {
color: "#7ec7ff",
fontSize: 16,
padding: 10
}, },
{ min: 0,
type: "pie", max: 100,
radius: ["20%", "28%"], splitLine: {
center: ["68%", "45%"], show: true,
color: ["#ffffff", "red"], lineStyle: {
startAngle: 105, color: '#192a44'
data: [
{
value: 30,
name: "",
itemStyle: {
color: "transparent"
}
}, },
{
value: 5,
name: "",
itemStyle: {
color: "transparent"
}
}, },
{ axisLine: {
value: 65, show: true,
name: "ddd", lineStyle: {
itemStyle: { color: "#233653"
color: "#ffffff"
}
}
],
silent: true,
labelLine: {
show: false
},
label: {
show: false
} }
}, },
{ axisLabel: {
type: "pie", show: true,
radius: [0, "30%"], textStyle: {
center: ["68%", "45%"], color: '#7ec7ff',
startAngle: 90, padding: 16
data: [
{
value: 25,
name: "1",
itemStyle: {
color: "transparent",
borderWidth: 4,
borderColor: "#ffffff"
}
}, },
{ formatter: function(value) {
value: 75, if (value === 0) {
name: "2", return value
itemStyle: {
color: "transparent"
} }
return value
} }
],
selectedOffset: 10,
silent: true,
labelLine: {
show: false
}, },
label: { axisTick: {
show: false show: false,
}
}, },
{ }],
type: "pie", series: [{
radius: ["96%", "97%"], name: '回款率',
center: ["68%", "45%"], type: 'line',
color: ["#007afe", "transparent", "#007afe", "transparent", "#007afe", "transparent"], symbol: 'circle', // 默认是空心圆(中间是白色的),改成实心圆
data: [ showAllSymbol: true,
{ value: 17, name: "11" }, symbolSize: 0,
{ value: 17, name: "22" }, smooth: true,
{ value: 17, name: "33" }, lineStyle: {
{ value: 17, name: "44" }, normal: {
{ value: 17, name: "55" }, width: 5,
{ value: 17, name: "66" } color: "rgba(25,163,223,1)", // 线条颜色
],
silent: true,
labelLine: { show: false },
label: { show: false }
}, },
{ borderColor: 'rgba(0,0,0,.4)',
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: { itemStyle: {
color: { color: "rgba(25,163,223,1)",
type: "linear", borderColor: "#646ace",
x: 0, borderWidth: 2
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
}
}
}, },
{ tooltip: {
name: "r2", show: true
value: 25, },
itemStyle: { areaStyle: { //区域填充样式
color: { normal: {
type: "linear", //线性渐变,前4个参数分别是x0,y0,x2,y2(范围0~1);相当于图形包围盒中的百分比。如果最后一个参数是‘true’,则该四个值是绝对像素位置。
x: 0, color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{
y: 0, offset: 0,
x2: 0, color: "rgba(25,163,223,.3)"
y2: 1,
colorStops: [
{ offset: 0, color: "rgba(0,0,0,0)" },
{ offset: 1, color: "rgba(51,149,191,0.5)" }
],
global: false
}
}
}, },
{ {
name: "r3", offset: 1,
value: 25, color: "rgba(25,163,223, 0)"
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
} }
], false),
shadowColor: 'rgba(25,163,223, 0.5)', //阴影颜色
shadowBlur: 20 //shadowBlur设图形阴影的模糊大小。配合shadowColor,shadowOffsetX/Y, 设置图形的阴影效果。
} }
}, },
{ data: goToSchool
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
}
}
}
]
}
]
}; };
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.echarts { .echarts {
......
<template> <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"> <div class="echarts">
<ECharts :option="option" :resize="false" /> <ECharts :option="option" :resize="false" />
</div> </div>
</template> </template>
<script setup lang="ts"> <script setup>
import { ref } from "vue"; import { ref } from "vue";
import { ECOption } from "@/components/ECharts/config";
import ECharts from "@/components/ECharts/index.vue"; import ECharts from "@/components/ECharts/index.vue";
import echarts from "@/components/ECharts/config";
const actualTotal = ref("216908"); const actualTotal = ref("216908");
const option = { const option = {
title: [ tooltip: { //提示框组件
{ trigger: 'axis',
text: (0.5 * 100).toFixed(0) + "%", formatter: '{b}<br />{a0}: {c0}<br />{a1}: {c1}',
left: "49%", axisPointer: {
top: "35%", type: 'shadow',
textAlign: "center", label: {
textStyle: { backgroundColor: '#6a7985'
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: { textStyle: {
fontSize: "15", color: '#fff',
fontWeight: "normal", fontStyle: 'normal',
color: "#ffffff", fontFamily: '微软雅黑',
align: "center", fontSize: 12,
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: { grid: {
max: 120, left: '1%',
clockwise: false, right: '1%',
axisLine: { bottom: '1%',
show: false top:'13%',
}, // padding:'0 0 10 0',
axisTick: { containLabel: true,
show: false },
}, legend: {//图例组件,颜色和名字
axisLabel: { right:'1%',
show: false top:'5%',
itemGap: 16,
itemWidth: 18,
itemHeight: 10,
data:[{
name:'作业量(日)',
//icon:'image://../wwwroot/js/url2.png', //路径
}, },
splitLine: { {
show: false name:'作业量(月)',
}],
textStyle: {
color: '#a8aab0',
fontStyle: 'normal',
fontFamily: '微软雅黑',
fontSize: 12,
}
}, },
startAngle: 188 xAxis: [
{
type: 'category',
// boundaryGap: true,//坐标轴两边留白
data: ['成都调解中心', '石家庄调解中心', '测试调解中心'],
axisLabel: { //坐标轴刻度标签的相关设置。
// interval: 0,//设置为 1,表示『隔一个标签显示一个标签』
// margin:15,
textStyle: {
color: '#078ceb',
fontStyle: 'normal',
fontFamily: '微软雅黑',
fontSize: 12,
}, },
radiusAxis: { rotate:50,
type: "category",
show: true,
axisLabel: {
show: false
}, },
axisLine: { axisTick:{//坐标轴刻度相关设置。
show: false show: false,
}, },
axisTick: { axisLine:{//坐标轴轴线相关设置
show: false lineStyle:{
color:'#fff',
opacity:0.2
} }
}, },
series: [ splitLine: { //坐标轴在 grid 区域中的分隔线。
{ show: false,
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 yAxis: [
{
type: 'value',
splitNumber: 5,
axisLabel: {
textStyle: {
color: '#a8aab0',
fontStyle: 'normal',
fontFamily: '微软雅黑',
fontSize: 12,
} }
}, },
outline: { axisLine:{
borderDistance: 0, show: false
itemStyle: {
borderWidth: 2,
borderColor: "#31d8d5",
shadowBlur: 20,
shadowColor: "#50c1a7"
}
}, },
label: { axisTick:{
show: false show: false
}, },
backgroundStyle: { splitLine: {
borderWidth: 1, show: true,
color: { lineStyle: {
type: "radial", color: ['#fff'],
x: 0.5, opacity:0.06
y: 0.5,
r: 0.5,
colorStops: [
{ offset: 0, color: "#0D2648" },
{ offset: 0.8, color: "#0D2648" },
{ offset: 1, color: "#228E7D" }
],
global: false
} }
} }
},
}
],
series : [
{ {
type: "pie", name:'作业量(日)',
radius: ["80%", "80%"], type:'bar',
center: ["50%", "50%"], data:[10,15, 30],
z: 1, barWidth: 10,
label: { show: false }, barGap:0,//柱间距离
silent: true, // label: {//图形上的文本标签
// normal: {
// show: true,
// position: 'top',
// textStyle: {
// color: '#a8aab0',
// fontStyle: 'normal',
// fontFamily: '微软雅黑',
// fontSize: 12,
// },
// },
// },
itemStyle: { itemStyle: {
borderWidth: 2, normal: {
borderType: [8, 10], show: true,
borderDashOffset: 15, color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{
borderColor: "#31d8d5", offset: 0,
color: "#11144e", color: '#5768EF'
borderCap: "round" }, {
offset: 1,
color: '#5768EF'
}]),
barBorderRadius: 50,
borderWidth: 0,
}
}, },
data: [100]
}, },
{ {
type: "bar", name:'作业量(月)',
data: [55], type:'bar',
z: 10, data:[8,5, 25],
coordinateSystem: "polar", barWidth: 10,
roundCap: true, barGap:0,//柱间距离
color: "#31d8d5" // 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,
}
},
} }
] ]
} as ECOption; };
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.echarts { .echarts {
width: 100%; width: 100%;
height: calc(100% - 50px); height: calc(100%);
} }
.actual-total { .actual-total {
position: relative; position: relative;
......
...@@ -18,23 +18,23 @@ ...@@ -18,23 +18,23 @@
<div class="dataScreen-lf"> <div class="dataScreen-lf">
<div class="dataScreen-top"> <div class="dataScreen-top">
<div class="dataScreen-main-title"> <div class="dataScreen-main-title">
实时在案案人统计 调解中心作业量
</div> </div>
<div class="dataScreen-main-chart"> <div class="dataScreen-main-chart">
<!-- <RealTimeAccessChart /> --> <RealTimeAccessChart />
</div> </div>
</div> </div>
<div class="dataScreen-center"> <div class="dataScreen-center">
<div class="dataScreen-main-title"> <div class="dataScreen-main-title">
案人性别比例 调解中心在案回款率
</div> </div>
<div class="dataScreen-main-chart"> <div class="dataScreen-main-chart">
<!-- <MaleFemaleRatioChart /> --> <MaleFemaleRatioChart />
</div> </div>
</div> </div>
<div class="dataScreen-bottom"> <div class="dataScreen-bottom">
<div class="dataScreen-main-title"> <div class="dataScreen-main-title">
案人年龄比例 人年龄比例
</div> </div>
<div class="dataScreen-main-chart"> <div class="dataScreen-main-chart">
<AgeRatioChart /> <AgeRatioChart />
...@@ -42,11 +42,27 @@ ...@@ -42,11 +42,27 @@
</div> </div>
</div> </div>
<div class="dataScreen-ct"> <div class="dataScreen-ct">
<div class="dataScreen-Number"> <div class="dataScreen-Number flex justify-between">
<div class="number-box"> <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> <p class=" text-xl text-white pt-2">1222 <span class=" text-base text-gray-400"></span></p>
</div> </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>
<div class="dataScreen-map"> <div class="dataScreen-map">
<div class="dataScreen-map-title">调解中心分布点</div> <div class="dataScreen-map-title">调解中心分布点</div>
...@@ -78,7 +94,7 @@ ...@@ -78,7 +94,7 @@
<div class="dataScreen-rg"> <div class="dataScreen-rg">
<div class="dataScreen-top"> <div class="dataScreen-top">
<div class="dataScreen-main-title"> <div class="dataScreen-main-title">
调解中心案件量排名 产品回款率排名
</div> </div>
<div class="dataScreen-main-chart"> <div class="dataScreen-main-chart">
<HotPlateChart /> <HotPlateChart />
...@@ -86,7 +102,7 @@ ...@@ -86,7 +102,7 @@
</div> </div>
<div class="dataScreen-center"> <div class="dataScreen-center">
<div class="dataScreen-main-title"> <div class="dataScreen-main-title">
年度案件量对比 调解中心回款金额
</div> </div>
<div class="dataScreen-main-chart"> <div class="dataScreen-main-chart">
<AnnualUseChart /> <AnnualUseChart />
...@@ -94,7 +110,7 @@ ...@@ -94,7 +110,7 @@
</div> </div>
<div class="dataScreen-bottom"> <div class="dataScreen-bottom">
<div class="dataScreen-main-title"> <div class="dataScreen-main-title">
案源数据统计 调解中心累计回款率
</div> </div>
<div class="dataScreen-main-chart"> <div class="dataScreen-main-chart">
<PlatformSourceChart /> <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> <template>
<div class="card content-box"> <div>
<span class="text"> 部门管理(待完善) 🍓🍇🍈🍉</span> <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> </div>
</template> </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 }) => { ...@@ -55,8 +55,8 @@ export default defineConfig(({ command, mode }) => {
port: VITE_PORT, port: VITE_PORT,
proxy: { proxy: {
'/api': { '/api': {
// target: 'http://192.168.31.189:8080', target: 'http://192.168.31.189:8080',
target: 'http://192.168.31.128:8080', // target: 'http://192.168.31.128:8080',
// target: 'http://8.152.205.9:8080', // target: 'http://8.152.205.9:8080',
changeOrigin: true, changeOrigin: true,
rewrite: (path) => path.replace(/^\/api/, ''), 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