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

数据大屏

parent 6decb858
...@@ -6,4 +6,8 @@ export const getMapByTenant = (params) => { ...@@ -6,4 +6,8 @@ export const getMapByTenant = (params) => {
// 保存客户 // 保存客户
// export const saveCustomer = (data) => { // export const saveCustomer = (data) => {
// return request.post('/customer/save', 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 = { ...@@ -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 = {
tooltip: { grid: {
trigger: "axis", left: '2%',
axisPointer: { right: '2%',
type: "none" bottom: '2%',
top: '2%',
containLabel: true
}, },
borderWidth: 0, tooltip: {
padding: 0, trigger: 'axis',
backgroundColor: "transparent", axisPointer: {
formatter: (params: any) => { type: 'none'
let str = ""; },
params.forEach((val: { color: string; seriesName: string; data: number }) => { formatter: function(params) {
str += ` return params[0].name + ' : ' + params[0].value
<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"
} }
},
axisTick: {
show: false
},
data: data.columns
}
],
yAxis: {
name: "(案件)",
nameTextStyle: {
color: "#D6DFEA",
fontSize: 12,
padding: [0, 30, 0, 0]
}, },
minInterval: 1, xAxis: {
splitNumber: 5, show: false,
splitLine: { type: 'value'
show: false,
lineStyle: {
color: "#192a44"
}
},
axisLine: {
show: true,
lineStyle: {
color: "#233653"
}
},
axisLabel: {
show: true,
color: "#B9D6D6",
padding: 0
}, },
axisTick: { yAxis: [{
show: false type: 'category',
} inverse: true,
}, axisLabel: {
series: data.data.map((val: ChartProp, index: number) => { show: true,
return { textStyle: {
name: val.label, color: '#fff'
type: "line", },
symbol: "circle", },
showSymbol: false, splitLine: {
smooth: true, show: false
lineStyle: { },
width: 1, axisTick: {
color: data.colors[index], show: false
borderColor: data.colors[index] },
}, axisLine: {
itemStyle: { show: false
color: data.colors[index], },
borderColor: "#646ace", data: salvProName
borderWidth: 2 }, {
}, type: 'category',
tooltip: { inverse: true,
show: true axisTick: 'none',
}, axisLine: 'none',
areaStyle: { show: true,
color: { axisLabel: {
type: "linear", textStyle: {
x: 0, color: '#ffffff',
y: 0, fontSize: '12'
x2: 0,
y2: 1,
colorStops: [
{
offset: 0,
color: data.colors[index]
}, },
{
offset: 1,
color: gradientColors[index]
}
],
global: false
}, },
shadowColor: "rgba(25,163,223, 0.3)", data:salvProValue
shadowBlur: 20 }],
}, series: [{
data: val.value 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> </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; display: flex;
height: 103px; height: 36px;
padding: 5px 20px; margin: 10px 10px 0;
background: url("../images/contrast-bg.png") no-repeat; line-height: 36px;
background: url("../images/rankingChart-bg.png") no-repeat;
background-size: 100% 100%; background-size: 100% 100%;
transform: scale(1.5); span {
.annual-month { width: 18%;
display: inline-block; margin-left: 4px;
margin-bottom: 2px; font-size: 14px;
font-size: 10px; font-weight: bold;
color: #03b8e2; color: #fdbc52;
// text-align: center;
} &:nth-child(2) {
.annual-list { margin-left: 4px;
display: flex; }
flex-direction: column; &:last-child {
width: 100%; width: 20%;
.year-item { margin-left: 60px;
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%;
}
} }
} }
} }
......
...@@ -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 = {
grid: { const option = {
top: "5%", grid: {
left: "7%", left: '2%',
right: "4%", right: '2%',
bottom: "1%", bottom: '2%',
containLabel: true top: '2%',
}, containLabel: true
xAxis: {
type: "value",
axisLine: {
show: false,
lineStyle: {
color: "white"
}
},
nameGap: 1,
splitLine: {
show: false
}, },
axisTick: { tooltip: {
show: false trigger: 'axis',
axisPointer: {
type: 'none'
},
formatter: function(params) {
return params[0].name + ' : ' + params[0].value
}
}, },
axisLabel: { xAxis: {
show: false, show: false,
fontSize: 16 type: 'value'
}, },
triggerEvent: false yAxis: [{
}, type: 'category',
yAxis: [ inverse: true,
{ axisLabel: {
show: true, show: true,
data: data.map((val: ChartProp) => val.name), textStyle: {
inverse: true, color: '#fff'
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
}, },
color: "#fff", },
align: "center", splitLine: {
height: 20, show: false
fontSize: 13 },
}, axisTick: {
lg2: { show: false
width: 60, },
backgroundColor: { axisLine: {
image: ranking2 show: false
},
data: salvProName
}, {
type: 'category',
inverse: true,
axisTick: 'none',
axisLine: 'none',
show: true,
axisLabel: {
textStyle: {
color: '#ffffff',
fontSize: '12'
}, },
color: "#fff", },
align: "center", data:salvProValue
height: 20, }],
fontSize: 13 series: [{
}, name: '值',
lg3: { type: 'bar',
width: 60, zlevel: 1,
backgroundColor: { itemStyle: {
image: ranking3 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", barWidth: 20,
align: "center", data: salvProValue
height: 20, },
fontSize: 13 {
}, name: '背景',
lg: { type: 'bar',
width: 60, barWidth: 20,
backgroundColor: { barGap: '-100%',
image: ranking4 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> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
......
<template> <template>
<!-- 男女比例 --> <!-- 平台来源 -->
<div class="ratio-main"> <div class="echarts">
<div class="ratio-header"> <ECharts :option="option" :resize="false" />
<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> </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"]
show: false
}, const option = {
grid: { tooltip: {
left: 0, trigger: 'axis'
top: "30px",
bottom: 0,
right: 0
},
yAxis: [
{
type: "category",
position: "left",
data: ["男生"],
axisTick: {
show: false
},
axisLine: {
show: false
},
axisLabel: {
show: false
}
}, },
{ legend: {
type: "category",
position: "right",
data: ["女士"],
axisTick: {
show: false
},
axisLine: {
show: false 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}%`;
}
}
}, },
{ grid: {
type: "bar", top: '20%',
barWidth: 20, left: '10%',
data: [1], right: '10%',
barGap: "-100%", bottom: '15%',
itemStyle: { containLabel: true
borderRadius: 10, },
color: "#FF4B7A" xAxis: [{
}, type: 'category',
label: { boundaryGap: false,
show: true, axisLine: { //坐标轴轴线相关设置。数学上的x轴
color: "#E7E8ED", show: true,
position: "insideRight", lineStyle: {
offset: [0, -20], color: '#233653'
fontSize: 12, },
formatter: () => { },
return `女士 ${data.woman * 100}%`; 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> </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: {
}, trigger: 'axis'
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;
}, },
data: data.map((val: ChartProp) => val.name) legend: {
},
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: {
show: false show: false
}
}, },
{ grid: {
type: "pie", top: '20%',
radius: ["20%", "28%"], left: '10%',
center: ["68%", "45%"], right: '10%',
color: ["#ffffff", "red"], bottom: '15%',
startAngle: 105, containLabel: true
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
}
}, },
{ xAxis: [{
type: "pie", type: 'category',
radius: [0, "30%"], boundaryGap: false,
center: ["68%", "45%"], axisLine: { //坐标轴轴线相关设置。数学上的x轴
startAngle: 90, show: true,
data: [ lineStyle: {
{ color: '#233653'
value: 25, },
name: "1",
itemStyle: {
color: "transparent",
borderWidth: 4,
borderColor: "#ffffff"
}
}, },
{ axisLabel: { //坐标轴刻度标签的相关设置
value: 75, textStyle: {
name: "2", color: '#7ec7ff',
itemStyle: { padding: 16,
color: "transparent" fontSize: 14
} },
} formatter: function(data) {
], return data
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
} }
}
}, },
{ splitLine: {
name: "r2", show: true,
value: 25, lineStyle: {
itemStyle: { color: '#192a44'
color: { },
type: "linear", },
x: 0, axisTick: {
y: 0, show: false,
x2: 0, },
y2: 1, data: xLabel
colorStops: [ }],
{ offset: 0, color: "rgba(0,0,0,0)" }, yAxis: [{
{ offset: 1, color: "rgba(51,149,191,0.5)" } name: '回款率',
], nameTextStyle: {
global: false color: "#7ec7ff",
fontSize: 16,
padding: 10
},
min: 0,
max: 100,
splitLine: {
show: true,
lineStyle: {
color: '#192a44'
},
},
axisLine: {
show: true,
lineStyle: {
color: "#233653"
} }
}
}, },
{ axisLabel: {
name: "r3", show: true,
value: 25, textStyle: {
itemStyle: { color: '#7ec7ff',
color: { padding: 16
type: "linear", },
x: 0, formatter: function(value) {
y: 0, if (value === 0) {
x2: 0, return value
y2: 1, }
colorStops: [ return value
{ offset: 0, color: "rgba(51,149,191,0)" },
{ offset: 1, color: "rgba(51,149,191,0.5)" }
],
global: false
} }
}
}, },
{ axisTick: {
name: "r4", show: false,
value: 25, },
itemStyle: { }],
color: { series: [{
type: "linear", name: '回款率',
x: 0, type: 'line',
y: 0, symbol: 'circle', // 默认是空心圆(中间是白色的),改成实心圆
x2: 0, showAllSymbol: true,
y2: 1, symbolSize: 0,
colorStops: [ smooth: true,
{ offset: 0, color: "rgba(51,149,191,0.5)" }, lineStyle: {
{ offset: 1, color: "rgba(0,0,0,0)" } normal: {
], width: 5,
global: false 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> </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", textStyle: {
align: "center", color: '#fff',
textBorderColor: "rgba(0, 0, 0, 0)", fontStyle: 'normal',
textShadowColor: "#000", fontFamily: '微软雅黑',
textShadowBlur: 0, fontSize: 12,
textShadowOffsetX: 0, }
textShadowOffsetY: 1 },
} grid: {
}, left: '1%',
{ right: '1%',
text: "清收比例", bottom: '1%',
left: "49%", top:'13%',
top: "25%", // padding:'0 0 10 0',
textAlign: "center", containLabel: true,
textStyle: { },
fontSize: "15", legend: {//图例组件,颜色和名字
fontWeight: "normal", right:'1%',
color: "#ffffff", top:'5%',
align: "center", itemGap: 16,
textBorderColor: "rgba(0, 0, 0, 0)", itemWidth: 18,
textShadowColor: "#000", itemHeight: 10,
textShadowBlur: 0, data:[{
textShadowOffsetX: 0, name:'作业量(日)',
textShadowOffsetY: 1 //icon:'image://../wwwroot/js/url2.png', //路径
} },
} {
], name:'作业量(月)',
grid: { }],
top: "0", textStyle: {
left: "0px", color: '#a8aab0',
right: "0px", fontStyle: 'normal',
bottom: "0", fontFamily: '微软雅黑',
containLabel: true fontSize: 12,
},
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
} }
}
}, },
{ xAxis: [
type: "pie", {
radius: ["80%", "80%"], type: 'category',
center: ["50%", "50%"], // boundaryGap: true,//坐标轴两边留白
z: 1, data: ['成都调解中心', '石家庄调解中心', '测试调解中心'],
label: { show: false }, axisLabel: { //坐标轴刻度标签的相关设置。
silent: true, // interval: 0,//设置为 1,表示『隔一个标签显示一个标签』
itemStyle: { // margin:15,
borderWidth: 2, textStyle: {
borderType: [8, 10], color: '#078ceb',
borderDashOffset: 15, fontStyle: 'normal',
borderColor: "#31d8d5", fontFamily: '微软雅黑',
color: "#11144e", fontSize: 12,
borderCap: "round" },
}, rotate:50,
data: [100] },
}, axisTick:{//坐标轴刻度相关设置。
{ show: false,
type: "bar", },
data: [55], axisLine:{//坐标轴轴线相关设置
z: 10, lineStyle:{
coordinateSystem: "polar", color:'#fff',
roundCap: true, opacity:0.2
color: "#31d8d5" }
} },
] splitLine: { //坐标轴在 grid 区域中的分隔线。
} as ECOption; 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> </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