信息统计
This commit is contained in:
parent
1d9eef5236
commit
92d770655d
34
src/api/statistics.ts
Normal file
34
src/api/statistics.ts
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
import request from '@/utils/request'
|
||||||
|
|
||||||
|
// 客户统计
|
||||||
|
export function apistatisticscustoms(params: any) {
|
||||||
|
return request.get({ url: '/statistics.statistics/customs', params })
|
||||||
|
}
|
||||||
|
// 项目付款统计
|
||||||
|
export function apistatisticsprojectInitiation(params: any) {
|
||||||
|
return request.get({ url: '/statistics.statistics/projectInitiation', params })
|
||||||
|
}
|
||||||
|
// 投标统计
|
||||||
|
export function apistatisticsbidding(params: any) {
|
||||||
|
return request.get({ url: '/statistics.statistics/bidding', params })
|
||||||
|
}
|
||||||
|
// 项目合同统计
|
||||||
|
export function apistatisticscontracts(params: any) {
|
||||||
|
return request.get({ url: '/statistics.statistics/contracts', params })
|
||||||
|
}
|
||||||
|
// 项目回款统计
|
||||||
|
export function apistatisticsprojectRefund(params: any) {
|
||||||
|
return request.get({ url: '/statistics.statistics/projectRefund', params })
|
||||||
|
}
|
||||||
|
// 采购合同统计
|
||||||
|
export function apistatisticsprocurementContract(params: any) {
|
||||||
|
return request.get({ url: '/statistics.statistics/procurementContract', params })
|
||||||
|
}
|
||||||
|
// 分包合同统计
|
||||||
|
export function apistatisticssubcontractingContract(params: any) {
|
||||||
|
return request.get({ url: '/statistics.statistics/subcontractingContract', params })
|
||||||
|
}
|
||||||
|
// 项目付款统计
|
||||||
|
export function apistatisticsprojectPayment(params: any) {
|
||||||
|
return request.get({ url: '/statistics.statistics/projectPayment', params })
|
||||||
|
}
|
109
src/views/astatistics/components/Custom.vue
Normal file
109
src/views/astatistics/components/Custom.vue
Normal file
@ -0,0 +1,109 @@
|
|||||||
|
<template>
|
||||||
|
<el-card style="width: 49.9%;">
|
||||||
|
<template #header>
|
||||||
|
<div class="card-header">
|
||||||
|
<span>我的客户</span>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<div style="display: flex;justify-content: space-around;">
|
||||||
|
<div v-for=" item in customList" :key="item" style="text-align: center;">
|
||||||
|
<div>{{ item.value }}</div>
|
||||||
|
<div>{{ item.name }}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div id="customNum" class="chart"></div>
|
||||||
|
</el-card>
|
||||||
|
</template>
|
||||||
|
<script setup>
|
||||||
|
import * as echarts from 'echarts';
|
||||||
|
import { apistatisticscustoms } from '@/api/statistics'
|
||||||
|
|
||||||
|
const customList = reactive([
|
||||||
|
{
|
||||||
|
name: "客户总数",
|
||||||
|
value: 3
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "今年增加",
|
||||||
|
value: 3
|
||||||
|
}
|
||||||
|
])
|
||||||
|
|
||||||
|
const labelOption = {
|
||||||
|
show: true,
|
||||||
|
rich: {
|
||||||
|
name: {}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const initChart = (id, opt) => {
|
||||||
|
var chartDom = document.getElementById(id);
|
||||||
|
var myChart = echarts.init(chartDom);
|
||||||
|
myChart.setOption(opt);
|
||||||
|
}
|
||||||
|
|
||||||
|
const setHistogramOption = (legend, xAxisData, series) => {
|
||||||
|
return {
|
||||||
|
tooltip: {
|
||||||
|
trigger: 'axis',
|
||||||
|
axisPointer: {
|
||||||
|
type: 'shadow'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
legend,
|
||||||
|
toolbox: {
|
||||||
|
show: true,
|
||||||
|
orient: 'vertical',
|
||||||
|
left: 'right',
|
||||||
|
top: 'center',
|
||||||
|
},
|
||||||
|
xAxis: [
|
||||||
|
{
|
||||||
|
type: 'category',
|
||||||
|
axisTick: { show: false },
|
||||||
|
data: xAxisData
|
||||||
|
}
|
||||||
|
],
|
||||||
|
yAxis: [
|
||||||
|
{
|
||||||
|
type: 'value'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
series
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
const getCustom = async () => {
|
||||||
|
let res = await apistatisticscustoms()
|
||||||
|
initChart("customNum", setHistogramOption({ data: [res.series.name] }, res.column
|
||||||
|
, [{
|
||||||
|
name: res.series.name,
|
||||||
|
type: 'bar',
|
||||||
|
barGap: 0,
|
||||||
|
label: labelOption,
|
||||||
|
emphasis: {
|
||||||
|
focus: 'series'
|
||||||
|
},
|
||||||
|
data: res.series.data
|
||||||
|
},]))
|
||||||
|
customList[0].value = res.custom_total
|
||||||
|
customList[1].value = res.this_year_add
|
||||||
|
}
|
||||||
|
|
||||||
|
getCustom()
|
||||||
|
</script>
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
#main,
|
||||||
|
#main2,
|
||||||
|
#main3 {
|
||||||
|
width: 100%;
|
||||||
|
height: 300px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.chart {
|
||||||
|
width: 100%;
|
||||||
|
height: 300px;
|
||||||
|
}
|
||||||
|
</style>
|
106
src/views/astatistics/components/Project.vue
Normal file
106
src/views/astatistics/components/Project.vue
Normal file
@ -0,0 +1,106 @@
|
|||||||
|
<template>
|
||||||
|
<el-card style="width: 49.9%;">
|
||||||
|
<template #header>
|
||||||
|
<div class="card-header">
|
||||||
|
<span>我的立项</span>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<div style="display: flex;justify-content: space-around;">
|
||||||
|
<div v-for=" item in customList" :key="item" style="text-align: center;">
|
||||||
|
<div>{{ item.value }}</div>
|
||||||
|
<div>{{ item.name }}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div id="projectApproved" class="chart"></div>
|
||||||
|
</el-card>
|
||||||
|
</template>
|
||||||
|
<script setup>
|
||||||
|
import * as echarts from 'echarts';
|
||||||
|
import { apistatisticsprojectInitiation } from '@/api/statistics'
|
||||||
|
|
||||||
|
const customList = reactive([
|
||||||
|
{
|
||||||
|
name: "客户总数",
|
||||||
|
value: 3
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "今年增加",
|
||||||
|
value: 3
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "今年增加",
|
||||||
|
value: 3
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "今年增加",
|
||||||
|
value: 3
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "今年增加",
|
||||||
|
value: 3
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "今年增加",
|
||||||
|
value: 3
|
||||||
|
},
|
||||||
|
])
|
||||||
|
|
||||||
|
const initChart = (id, opt) => {
|
||||||
|
var chartDom = document.getElementById(id);
|
||||||
|
var myChart = echarts.init(chartDom);
|
||||||
|
myChart.setOption(opt);
|
||||||
|
}
|
||||||
|
|
||||||
|
const getData = async () => {
|
||||||
|
let res = await apistatisticsprojectInitiation()
|
||||||
|
customList[0].value = res.project_total
|
||||||
|
customList[1].value = res.follow_total
|
||||||
|
customList[2].value = res.demand_total
|
||||||
|
customList[3].value = res.solution_total
|
||||||
|
customList[4].value = res.estimate_total
|
||||||
|
customList[5].value = res.competitor_total
|
||||||
|
let option2 = {
|
||||||
|
title: {
|
||||||
|
text: '',
|
||||||
|
subtext: '',
|
||||||
|
left: 'center'
|
||||||
|
},
|
||||||
|
tooltip: {
|
||||||
|
trigger: 'item'
|
||||||
|
},
|
||||||
|
|
||||||
|
series: [
|
||||||
|
{
|
||||||
|
name: '我的立项',
|
||||||
|
type: 'pie',
|
||||||
|
radius: '50%',
|
||||||
|
data: res.data,
|
||||||
|
emphasis: {
|
||||||
|
itemStyle: {
|
||||||
|
shadowBlur: 10,
|
||||||
|
shadowOffsetX: 0,
|
||||||
|
shadowColor: 'rgba(0, 0, 0, 0.5)'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
};
|
||||||
|
initChart("projectApproved", option2)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
getData()
|
||||||
|
</script>
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
#main,
|
||||||
|
#main2,
|
||||||
|
#main3 {
|
||||||
|
width: 100%;
|
||||||
|
height: 300px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.chart {
|
||||||
|
width: 100%;
|
||||||
|
height: 300px;
|
||||||
|
}
|
||||||
|
</style>
|
148
src/views/astatistics/components/ProjectPayment.vue
Normal file
148
src/views/astatistics/components/ProjectPayment.vue
Normal file
@ -0,0 +1,148 @@
|
|||||||
|
<template>
|
||||||
|
<el-card style="width: 49.9%;">
|
||||||
|
<template #header>
|
||||||
|
<div class="card-header">
|
||||||
|
<span>项目回款</span>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<div style="display: flex;justify-content: space-around;">
|
||||||
|
<div v-for=" item in customList" :key="item" style="text-align: center;">
|
||||||
|
<div>{{ item.value }}</div>
|
||||||
|
<div>{{ item.name }}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div id="ProjectPayment" class="chart"></div>
|
||||||
|
</el-card>
|
||||||
|
</template>
|
||||||
|
<script setup>
|
||||||
|
import * as echarts from 'echarts';
|
||||||
|
import { apistatisticsprojectRefund } from '@/api/statistics'
|
||||||
|
|
||||||
|
const customList = reactive([
|
||||||
|
{
|
||||||
|
name: "客户总数",
|
||||||
|
value: 3
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "今年增加",
|
||||||
|
value: 3
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "今年增加",
|
||||||
|
value: 3
|
||||||
|
},
|
||||||
|
|
||||||
|
])
|
||||||
|
|
||||||
|
const labelOption = {
|
||||||
|
show: true,
|
||||||
|
rich: {
|
||||||
|
name: {}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const initChart = (id, opt) => {
|
||||||
|
var chartDom = document.getElementById(id);
|
||||||
|
var myChart = echarts.init(chartDom);
|
||||||
|
myChart.setOption(opt);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const getCustom = async () => {
|
||||||
|
let res = await apistatisticsprojectRefund()
|
||||||
|
|
||||||
|
var option4 = {
|
||||||
|
tooltip: {
|
||||||
|
trigger: 'axis',
|
||||||
|
axisPointer: {
|
||||||
|
type: 'shadow'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
legend: {
|
||||||
|
data: [res.invoice_series.name, res.refund_plan_series.name, res.refund_series
|
||||||
|
.name,]
|
||||||
|
},
|
||||||
|
toolbox: {
|
||||||
|
show: true,
|
||||||
|
orient: 'vertical',
|
||||||
|
left: 'right',
|
||||||
|
top: 'center',
|
||||||
|
|
||||||
|
},
|
||||||
|
xAxis: [
|
||||||
|
{
|
||||||
|
type: 'category',
|
||||||
|
axisTick: { show: false },
|
||||||
|
data: res.column
|
||||||
|
}
|
||||||
|
],
|
||||||
|
yAxis: [
|
||||||
|
{
|
||||||
|
type: 'value'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
series: [
|
||||||
|
{
|
||||||
|
name: res.invoice_series.name,
|
||||||
|
type: 'bar',
|
||||||
|
barGap: 0,
|
||||||
|
label: labelOption,
|
||||||
|
emphasis: {
|
||||||
|
focus: 'series'
|
||||||
|
},
|
||||||
|
data: res.invoice_series.name.data,
|
||||||
|
itemStyle: {
|
||||||
|
normal: {
|
||||||
|
label: {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: res.refund_plan_series.name,
|
||||||
|
type: 'bar',
|
||||||
|
label: labelOption,
|
||||||
|
emphasis: {
|
||||||
|
focus: 'series'
|
||||||
|
},
|
||||||
|
data: res.refund_plan_series.data,
|
||||||
|
itemStyle: {
|
||||||
|
normal: {
|
||||||
|
label: {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: res.refund_series.name,
|
||||||
|
type: 'bar',
|
||||||
|
label: labelOption,
|
||||||
|
emphasis: {
|
||||||
|
focus: 'series'
|
||||||
|
},
|
||||||
|
data: res.refund_series.data,
|
||||||
|
itemStyle: {
|
||||||
|
normal: {
|
||||||
|
label: {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
]
|
||||||
|
};
|
||||||
|
|
||||||
|
initChart("ProjectPayment", option4)
|
||||||
|
customList[0].value = res.year_invoicing_amount
|
||||||
|
customList[1].value = res.year_refund_amount
|
||||||
|
customList[2].value = res.year_refund_plan_amount
|
||||||
|
}
|
||||||
|
|
||||||
|
getCustom()
|
||||||
|
</script>
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.chart {
|
||||||
|
width: 100%;
|
||||||
|
height: 300px;
|
||||||
|
}
|
||||||
|
</style>
|
148
src/views/astatistics/components/ProjectWithdraw.vue
Normal file
148
src/views/astatistics/components/ProjectWithdraw.vue
Normal file
@ -0,0 +1,148 @@
|
|||||||
|
<template>
|
||||||
|
<el-card style="width: 49.9%;">
|
||||||
|
<template #header>
|
||||||
|
<div class="card-header">
|
||||||
|
<span>项目付款统计</span>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<div style="display: flex;justify-content: space-around;">
|
||||||
|
<div v-for=" item in customList" :key="item" style="text-align: center;">
|
||||||
|
<div>{{ item.value }}</div>
|
||||||
|
<div>{{ item.name }}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div id="ProjectWithdraw" class="chart"></div>
|
||||||
|
</el-card>
|
||||||
|
</template>
|
||||||
|
<script setup>
|
||||||
|
import * as echarts from 'echarts';
|
||||||
|
import { apistatisticsprojectPayment } from '@/api/statistics'
|
||||||
|
|
||||||
|
const customList = reactive([
|
||||||
|
{
|
||||||
|
name: "客户总数",
|
||||||
|
value: 3
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "今年增加",
|
||||||
|
value: 3
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "今年增加",
|
||||||
|
value: 3
|
||||||
|
},
|
||||||
|
|
||||||
|
])
|
||||||
|
|
||||||
|
const labelOption = {
|
||||||
|
show: true,
|
||||||
|
rich: {
|
||||||
|
name: {}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const initChart = (id, opt) => {
|
||||||
|
var chartDom = document.getElementById(id);
|
||||||
|
var myChart = echarts.init(chartDom);
|
||||||
|
myChart.setOption(opt);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const getCustom = async () => {
|
||||||
|
let res = await apistatisticsprojectPayment()
|
||||||
|
console.log(res)
|
||||||
|
|
||||||
|
var option4 = {
|
||||||
|
tooltip: {
|
||||||
|
trigger: 'axis',
|
||||||
|
axisPointer: {
|
||||||
|
type: 'shadow'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
legend: {
|
||||||
|
data: [res.invoice_series.name, res.payment_plan_series.name, res.payment_series.name,]
|
||||||
|
},
|
||||||
|
toolbox: {
|
||||||
|
show: true,
|
||||||
|
orient: 'vertical',
|
||||||
|
left: 'right',
|
||||||
|
top: 'center',
|
||||||
|
|
||||||
|
},
|
||||||
|
xAxis: [
|
||||||
|
{
|
||||||
|
type: 'category',
|
||||||
|
axisTick: { show: false },
|
||||||
|
data: res.column
|
||||||
|
}
|
||||||
|
],
|
||||||
|
yAxis: [
|
||||||
|
{
|
||||||
|
type: 'value'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
series: [
|
||||||
|
{
|
||||||
|
name: res.invoice_series.name,
|
||||||
|
type: 'bar',
|
||||||
|
barGap: 0,
|
||||||
|
label: labelOption,
|
||||||
|
emphasis: {
|
||||||
|
focus: 'series'
|
||||||
|
},
|
||||||
|
data: res.invoice_series.name.data,
|
||||||
|
itemStyle: {
|
||||||
|
normal: {
|
||||||
|
label: {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: res.payment_plan_series.name,
|
||||||
|
type: 'bar',
|
||||||
|
label: labelOption,
|
||||||
|
emphasis: {
|
||||||
|
focus: 'series'
|
||||||
|
},
|
||||||
|
data: res.payment_plan_series.data,
|
||||||
|
itemStyle: {
|
||||||
|
normal: {
|
||||||
|
label: {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: res.payment_series.name,
|
||||||
|
type: 'bar',
|
||||||
|
label: labelOption,
|
||||||
|
emphasis: {
|
||||||
|
focus: 'series'
|
||||||
|
},
|
||||||
|
data: res.payment_series.data,
|
||||||
|
itemStyle: {
|
||||||
|
normal: {
|
||||||
|
label: {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
]
|
||||||
|
};
|
||||||
|
|
||||||
|
initChart("ProjectWithdraw", option4)
|
||||||
|
customList[0].value = res.year_invoicing_amount
|
||||||
|
customList[1].value = res.year_payment_amount
|
||||||
|
customList[2].value = res.year_payment_plan_amount
|
||||||
|
}
|
||||||
|
|
||||||
|
getCustom()
|
||||||
|
</script>
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.chart {
|
||||||
|
width: 100%;
|
||||||
|
height: 300px;
|
||||||
|
}
|
||||||
|
</style>
|
113
src/views/astatistics/components/PurchaseContracts.vue
Normal file
113
src/views/astatistics/components/PurchaseContracts.vue
Normal file
@ -0,0 +1,113 @@
|
|||||||
|
<template>
|
||||||
|
<el-card style="width: 49.9%;">
|
||||||
|
<template #header>
|
||||||
|
<div class="card-header">
|
||||||
|
<span>采购合同</span>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<div style="display: flex;justify-content: space-around;">
|
||||||
|
<div v-for=" item in customList" :key="item" style="text-align: center;">
|
||||||
|
<div>{{ item.value }}</div>
|
||||||
|
<div>{{ item.name }}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div id="PurchaseContracts" class="chart"></div>
|
||||||
|
</el-card>
|
||||||
|
</template>
|
||||||
|
<script setup>
|
||||||
|
import * as echarts from 'echarts';
|
||||||
|
import { apistatisticsprocurementContract } from '@/api/statistics'
|
||||||
|
|
||||||
|
const customList = reactive([
|
||||||
|
{
|
||||||
|
name: "客户总数",
|
||||||
|
value: 3
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "今年增加",
|
||||||
|
value: 3
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "今年增加",
|
||||||
|
value: 3
|
||||||
|
}
|
||||||
|
])
|
||||||
|
|
||||||
|
const labelOption = {
|
||||||
|
show: true,
|
||||||
|
rich: {
|
||||||
|
name: {}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const initChart = (id, opt) => {
|
||||||
|
var chartDom = document.getElementById(id);
|
||||||
|
var myChart = echarts.init(chartDom);
|
||||||
|
myChart.setOption(opt);
|
||||||
|
}
|
||||||
|
|
||||||
|
const setHistogramOption = (legend, xAxisData, series) => {
|
||||||
|
return {
|
||||||
|
tooltip: {
|
||||||
|
trigger: 'axis',
|
||||||
|
axisPointer: {
|
||||||
|
type: 'shadow'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
legend,
|
||||||
|
toolbox: {
|
||||||
|
show: true,
|
||||||
|
orient: 'vertical',
|
||||||
|
left: 'right',
|
||||||
|
top: 'center',
|
||||||
|
},
|
||||||
|
xAxis: [
|
||||||
|
{
|
||||||
|
type: 'category',
|
||||||
|
axisTick: { show: false },
|
||||||
|
data: xAxisData
|
||||||
|
}
|
||||||
|
],
|
||||||
|
yAxis: [
|
||||||
|
{
|
||||||
|
type: 'value'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
series
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
const getCustom = async () => {
|
||||||
|
let res = await apistatisticsprocurementContract()
|
||||||
|
initChart("PurchaseContracts", setHistogramOption({ data: [res.series.name] }, res.column
|
||||||
|
, [{
|
||||||
|
name: res.series.name,
|
||||||
|
type: 'bar',
|
||||||
|
barGap: 0,
|
||||||
|
label: labelOption,
|
||||||
|
emphasis: {
|
||||||
|
focus: 'series'
|
||||||
|
},
|
||||||
|
data: res.series.data
|
||||||
|
},]))
|
||||||
|
customList[0].value = res.custom_total
|
||||||
|
customList[1].value = res.this_year_add
|
||||||
|
}
|
||||||
|
|
||||||
|
getCustom()
|
||||||
|
</script>
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
#main,
|
||||||
|
#main2,
|
||||||
|
#main3 {
|
||||||
|
width: 100%;
|
||||||
|
height: 300px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.chart {
|
||||||
|
width: 100%;
|
||||||
|
height: 300px;
|
||||||
|
}
|
||||||
|
</style>
|
118
src/views/astatistics/components/Subcontract.vue
Normal file
118
src/views/astatistics/components/Subcontract.vue
Normal file
@ -0,0 +1,118 @@
|
|||||||
|
<template>
|
||||||
|
<el-card style="width: 49.9%;">
|
||||||
|
<template #header>
|
||||||
|
<div class="card-header">
|
||||||
|
<span>分包合同</span>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<div style="display: flex;justify-content: space-around;">
|
||||||
|
<div v-for=" item in customList" :key="item" style="text-align: center;">
|
||||||
|
<div>{{ item.value }}</div>
|
||||||
|
<div>{{ item.name }}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div id="Subcontract" class="chart"></div>
|
||||||
|
</el-card>
|
||||||
|
</template>
|
||||||
|
<script setup>
|
||||||
|
import * as echarts from 'echarts';
|
||||||
|
import { apistatisticssubcontractingContract } from '@/api/statistics'
|
||||||
|
|
||||||
|
const customList = reactive([
|
||||||
|
{
|
||||||
|
name: "客户总数",
|
||||||
|
value: 3
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "今年增加",
|
||||||
|
value: 3
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "今年增加",
|
||||||
|
value: 3
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "今年增加",
|
||||||
|
value: 3
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "今年增加",
|
||||||
|
value: 3
|
||||||
|
}
|
||||||
|
])
|
||||||
|
|
||||||
|
const labelOption = {
|
||||||
|
show: true,
|
||||||
|
rich: {
|
||||||
|
name: {}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const initChart = (id, opt) => {
|
||||||
|
var chartDom = document.getElementById(id);
|
||||||
|
var myChart = echarts.init(chartDom);
|
||||||
|
myChart.setOption(opt);
|
||||||
|
}
|
||||||
|
|
||||||
|
const setHistogramOption = (legend, xAxisData, series) => {
|
||||||
|
return {
|
||||||
|
tooltip: {
|
||||||
|
trigger: 'axis',
|
||||||
|
axisPointer: {
|
||||||
|
type: 'shadow'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
legend,
|
||||||
|
toolbox: {
|
||||||
|
show: true,
|
||||||
|
orient: 'vertical',
|
||||||
|
left: 'right',
|
||||||
|
top: 'center',
|
||||||
|
},
|
||||||
|
xAxis: [
|
||||||
|
{
|
||||||
|
type: 'category',
|
||||||
|
axisTick: { show: false },
|
||||||
|
data: xAxisData
|
||||||
|
}
|
||||||
|
],
|
||||||
|
yAxis: [
|
||||||
|
{
|
||||||
|
type: 'value'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
series
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
const getCustom = async () => {
|
||||||
|
let res = await apistatisticssubcontractingContract()
|
||||||
|
initChart("Subcontract", setHistogramOption({ data: [res.series.name] }, res.column
|
||||||
|
, [{
|
||||||
|
name: res.series.name,
|
||||||
|
type: 'bar',
|
||||||
|
barGap: 0,
|
||||||
|
label: labelOption,
|
||||||
|
emphasis: {
|
||||||
|
focus: 'series'
|
||||||
|
},
|
||||||
|
data: res.series.data
|
||||||
|
},]))
|
||||||
|
customList[0].value = res.total_amount
|
||||||
|
customList[1].value = res.total_negotiation_amount
|
||||||
|
customList[2].value = res.total_num
|
||||||
|
customList[3].value = res.year_total_amount
|
||||||
|
customList[4].value = res.year_total_num
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
getCustom()
|
||||||
|
</script>
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.chart {
|
||||||
|
width: 100%;
|
||||||
|
height: 300px;
|
||||||
|
}
|
||||||
|
</style>
|
185
src/views/astatistics/components/Tender.vue
Normal file
185
src/views/astatistics/components/Tender.vue
Normal file
@ -0,0 +1,185 @@
|
|||||||
|
<template>
|
||||||
|
<el-card style="width: 49.9%;">
|
||||||
|
<template #header>
|
||||||
|
<div class="card-header">
|
||||||
|
<span>我的投标</span>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<div style="display: flex;justify-content: space-around;">
|
||||||
|
<div v-for=" item in customList" :key="item" style="text-align: center;">
|
||||||
|
<div>{{ item.value }}</div>
|
||||||
|
<div>{{ item.name }}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div id="main"></div>
|
||||||
|
</el-card>
|
||||||
|
</template>
|
||||||
|
<script setup>
|
||||||
|
import * as echarts from 'echarts';
|
||||||
|
import { apistatisticsbidding } from '@/api/statistics'
|
||||||
|
|
||||||
|
const customList = reactive([
|
||||||
|
{
|
||||||
|
name: "客户总数",
|
||||||
|
value: 3
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "今年增加",
|
||||||
|
value: 3
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "今年增加",
|
||||||
|
value: 3
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "今年增加",
|
||||||
|
value: 3
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "今年增加",
|
||||||
|
value: 3
|
||||||
|
}
|
||||||
|
|
||||||
|
])
|
||||||
|
|
||||||
|
|
||||||
|
const initChart = (id, opt) => {
|
||||||
|
var chartDom = document.getElementById(id);
|
||||||
|
var myChart = echarts.init(chartDom);
|
||||||
|
myChart.setOption(opt);
|
||||||
|
}
|
||||||
|
|
||||||
|
const getData = async () => {
|
||||||
|
let res = await apistatisticsbidding()
|
||||||
|
let value = +res.bidding_rate * 100
|
||||||
|
let option3 = {
|
||||||
|
title: {
|
||||||
|
text: '{a|' + value + '}{c|%}',
|
||||||
|
x: 'center',
|
||||||
|
y: 'center',
|
||||||
|
textStyle: {
|
||||||
|
rich: {
|
||||||
|
a: {
|
||||||
|
fontSize: 20,
|
||||||
|
color: 'black',
|
||||||
|
fontWeight: 'bold'
|
||||||
|
},
|
||||||
|
c: {
|
||||||
|
fontSize: 20,
|
||||||
|
color: 'black',
|
||||||
|
fontWeight: 'normal'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
series: [
|
||||||
|
//外环
|
||||||
|
{
|
||||||
|
name: "外环",
|
||||||
|
type: 'pie',
|
||||||
|
silent: true,
|
||||||
|
clockwise: true,
|
||||||
|
radius: ['70%', '75%'],
|
||||||
|
label: {
|
||||||
|
show: false,
|
||||||
|
},
|
||||||
|
labelLine: {
|
||||||
|
show: false
|
||||||
|
},
|
||||||
|
itemStyle: {
|
||||||
|
color: 'white',
|
||||||
|
},
|
||||||
|
data: [0]
|
||||||
|
},
|
||||||
|
//内环
|
||||||
|
{
|
||||||
|
name: "内环",
|
||||||
|
type: 'pie',
|
||||||
|
silent: true,
|
||||||
|
clockwise: true,
|
||||||
|
radius: ['45%', '46%'],
|
||||||
|
label: {
|
||||||
|
show: false,
|
||||||
|
},
|
||||||
|
labelLine: {
|
||||||
|
show: false
|
||||||
|
},
|
||||||
|
itemStyle: {
|
||||||
|
color: '#414f63',
|
||||||
|
},
|
||||||
|
data: [0]
|
||||||
|
},
|
||||||
|
//外环
|
||||||
|
{
|
||||||
|
name: '',
|
||||||
|
type: 'pie',
|
||||||
|
radius: ['55%', '65%'],
|
||||||
|
silent: true,
|
||||||
|
clockwise: true,
|
||||||
|
startAngle: 90,
|
||||||
|
label: {
|
||||||
|
show: false,
|
||||||
|
},
|
||||||
|
data: [
|
||||||
|
{
|
||||||
|
value: value,
|
||||||
|
itemStyle: {
|
||||||
|
normal: {
|
||||||
|
//外环发光
|
||||||
|
borderWidth: 0.5,
|
||||||
|
shadowBlur: 20,
|
||||||
|
borderColor: '#4bf3f9',
|
||||||
|
shadowColor: '#9bfeff',
|
||||||
|
color: { // 圆环的颜色
|
||||||
|
colorStops: [{
|
||||||
|
offset: 0,
|
||||||
|
color: '#15caff', // 0% 处的颜色
|
||||||
|
}, {
|
||||||
|
offset: 1,
|
||||||
|
color: '#159bfe', // 100% 处的颜色
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: 100 - value,
|
||||||
|
label: {
|
||||||
|
normal: {
|
||||||
|
show: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
itemStyle: {
|
||||||
|
normal: {
|
||||||
|
color: "#364662"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
]
|
||||||
|
};
|
||||||
|
initChart("main", option3)
|
||||||
|
customList[0].value = res.decision
|
||||||
|
customList[1].value = res.document
|
||||||
|
customList[2].value = res.examination
|
||||||
|
customList[3].value = res.not_return_margin_amount
|
||||||
|
customList[4].value = res.successful
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
getData()
|
||||||
|
</script>
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
#main,
|
||||||
|
#main2,
|
||||||
|
#main3 {
|
||||||
|
width: 100%;
|
||||||
|
height: 300px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.chart {
|
||||||
|
width: 100%;
|
||||||
|
height: 300px;
|
||||||
|
}
|
||||||
|
</style>
|
117
src/views/astatistics/components/projectContracts.vue
Normal file
117
src/views/astatistics/components/projectContracts.vue
Normal file
@ -0,0 +1,117 @@
|
|||||||
|
<template>
|
||||||
|
<el-card style="width: 49.9%;">
|
||||||
|
<template #header>
|
||||||
|
<div class="card-header">
|
||||||
|
<span>我的客户</span>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<div style="display: flex;justify-content: space-around;">
|
||||||
|
<div v-for=" item in customList" :key="item" style="text-align: center;">
|
||||||
|
<div>{{ item.value }}</div>
|
||||||
|
<div>{{ item.name }}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div id="main3" class="chart"></div>
|
||||||
|
</el-card>
|
||||||
|
</template>
|
||||||
|
<script setup>
|
||||||
|
import * as echarts from 'echarts';
|
||||||
|
import { apistatisticscontracts } from '@/api/statistics'
|
||||||
|
|
||||||
|
const customList = reactive([
|
||||||
|
{
|
||||||
|
name: "客户总数",
|
||||||
|
value: 3
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "今年增加",
|
||||||
|
value: 3
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "今年增加",
|
||||||
|
value: 3
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "今年增加",
|
||||||
|
value: 3
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "今年增加",
|
||||||
|
value: 3
|
||||||
|
},
|
||||||
|
])
|
||||||
|
|
||||||
|
const labelOption = {
|
||||||
|
show: true,
|
||||||
|
rich: {
|
||||||
|
name: {}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const initChart = (id, opt) => {
|
||||||
|
var chartDom = document.getElementById(id);
|
||||||
|
var myChart = echarts.init(chartDom);
|
||||||
|
myChart.setOption(opt);
|
||||||
|
}
|
||||||
|
|
||||||
|
const setHistogramOption = (legend, xAxisData, series) => {
|
||||||
|
return {
|
||||||
|
tooltip: {
|
||||||
|
trigger: 'axis',
|
||||||
|
axisPointer: {
|
||||||
|
type: 'shadow'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
legend,
|
||||||
|
toolbox: {
|
||||||
|
show: true,
|
||||||
|
orient: 'vertical',
|
||||||
|
left: 'right',
|
||||||
|
top: 'center',
|
||||||
|
},
|
||||||
|
xAxis: [
|
||||||
|
{
|
||||||
|
type: 'category',
|
||||||
|
axisTick: { show: false },
|
||||||
|
data: xAxisData
|
||||||
|
}
|
||||||
|
],
|
||||||
|
yAxis: [
|
||||||
|
{
|
||||||
|
type: 'value'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
series
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
const getCustom = async () => {
|
||||||
|
let res = await apistatisticscontracts()
|
||||||
|
initChart("main3", setHistogramOption({ data: [res.series.name] }, res.column
|
||||||
|
, [{
|
||||||
|
name: res.series.name,
|
||||||
|
type: 'bar',
|
||||||
|
barGap: 0,
|
||||||
|
label: labelOption,
|
||||||
|
emphasis: {
|
||||||
|
focus: 'series'
|
||||||
|
},
|
||||||
|
data: res.series.data
|
||||||
|
},]))
|
||||||
|
customList[0].value = res.total_amount
|
||||||
|
customList[1].value = res.total_negotiate_amount
|
||||||
|
customList[2].value = res.total_num
|
||||||
|
customList[3].value = res.year_total_amount
|
||||||
|
customList[4].value = res.year_total_num
|
||||||
|
}
|
||||||
|
|
||||||
|
getCustom()
|
||||||
|
</script>
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.chart {
|
||||||
|
width: 100%;
|
||||||
|
height: 300px;
|
||||||
|
}
|
||||||
|
</style>
|
@ -1,185 +1,13 @@
|
|||||||
<template>
|
<template>
|
||||||
<div style="display: flex;flex-wrap: wrap;justify-content: space-between;">
|
<div style="display: flex;flex-wrap: wrap;justify-content: space-between;">
|
||||||
|
<Custom></Custom>
|
||||||
<el-card style="width: 49.9%;">
|
<Project></Project>
|
||||||
<template #header>
|
<Tender></Tender>
|
||||||
<div class="card-header">
|
<projectContracts></projectContracts>
|
||||||
<span>我的客户</span>
|
<ProjectPayment></ProjectPayment>
|
||||||
</div>
|
<PurchaseContracts></PurchaseContracts>
|
||||||
</template>
|
<Subcontract></Subcontract>
|
||||||
<div style="display: flex;justify-content: space-around;">
|
<ProjectWithdraw></ProjectWithdraw>
|
||||||
<div v-for=" item in customList" :key="item" style="text-align: center;">
|
|
||||||
<div>{{ item.value }}</div>
|
|
||||||
<div>{{ item.name }}</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div id="customNum" class="chart"></div>
|
|
||||||
</el-card>
|
|
||||||
|
|
||||||
<el-card style="width: 49.9%;">
|
|
||||||
<template #header>
|
|
||||||
<div class="card-header">
|
|
||||||
<span>我的立项</span>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
<div style="display: flex;justify-content: space-around;">
|
|
||||||
<div v-for=" item in customList" :key="item" style="text-align: center;">
|
|
||||||
<div>{{ item.value }}</div>
|
|
||||||
<div>{{ item.name }}</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div id="projectApproved" class="chart"></div>
|
|
||||||
</el-card>
|
|
||||||
|
|
||||||
<el-card style="width: 49.9%;">
|
|
||||||
<template #header>
|
|
||||||
<div class="card-header">
|
|
||||||
<span>我的投标</span>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
<div style="display: flex;justify-content: space-around;">
|
|
||||||
<div v-for=" item in customList" :key="item" style="text-align: center;">
|
|
||||||
<div>{{ item.value }}</div>
|
|
||||||
<div>{{ item.name }}</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div id="main"></div>
|
|
||||||
</el-card>
|
|
||||||
<el-card style="width: 49.9%;">
|
|
||||||
<template #header>
|
|
||||||
<div class="card-header">
|
|
||||||
<span>项目合同</span>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
<div style="display: flex;justify-content: space-around;">
|
|
||||||
<div v-for=" item in customList" :key="item" style="text-align: center;">
|
|
||||||
<div>{{ item.value }}</div>
|
|
||||||
<div>{{ item.name }}</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div id="main2"></div>
|
|
||||||
</el-card>
|
|
||||||
<el-card style="width: 49.9%;">
|
|
||||||
<template #header>
|
|
||||||
<div class="card-header">
|
|
||||||
<span>项目回款</span>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
<div style="display: flex;justify-content: space-around;">
|
|
||||||
<div v-for=" item in customList" :key="item" style="text-align: center;">
|
|
||||||
<div>{{ item.value }}</div>
|
|
||||||
<div>{{ item.name }}</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div id="main3"></div>
|
|
||||||
</el-card>
|
|
||||||
<el-card style="width: 49.9%;">
|
|
||||||
<template #header>
|
|
||||||
<div class="card-header">
|
|
||||||
<span>采购合同</span>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
<div style="display: flex;justify-content: space-around;">
|
|
||||||
<div v-for=" item in customList" :key="item" style="text-align: center;">
|
|
||||||
<div>{{ item.value }}</div>
|
|
||||||
<div>{{ item.name }}</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div id="main4" class="chart"></div>
|
|
||||||
</el-card>
|
|
||||||
|
|
||||||
<el-card style="width: 49.9%;">
|
|
||||||
<template #header>
|
|
||||||
<div class="card-header">
|
|
||||||
<span>分包合同</span>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
<div style="display: flex;justify-content: space-around;">
|
|
||||||
<div v-for=" item in customList" :key="item" style="text-align: center;">
|
|
||||||
<div>{{ item.value }}</div>
|
|
||||||
<div>{{ item.name }}</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div id="main5" class="chart"></div>
|
|
||||||
</el-card>
|
|
||||||
<el-card style="width: 49.9%;">
|
|
||||||
<template #header>
|
|
||||||
<div class="card-header">
|
|
||||||
<span>项目付款</span>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
<div style="display: flex;justify-content: space-around;">
|
|
||||||
<div v-for=" item in customList" :key="item" style="text-align: center;">
|
|
||||||
<div>{{ item.value }}</div>
|
|
||||||
<div>{{ item.name }}</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div id="main6" class="chart"></div>
|
|
||||||
</el-card>
|
|
||||||
<el-card style="width: 49.9%;">
|
|
||||||
<template #header>
|
|
||||||
<div class="card-header">
|
|
||||||
<span>我的报销</span>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
<div style="display: flex;justify-content: space-around;">
|
|
||||||
<div v-for=" item in customList" :key="item" style="text-align: center;">
|
|
||||||
<div>{{ item.value }}</div>
|
|
||||||
<div>{{ item.name }}</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div id="main7" class="chart"></div>
|
|
||||||
</el-card>
|
|
||||||
<el-card style="width: 49.9%;">
|
|
||||||
<template #header>
|
|
||||||
<div class="card-header">
|
|
||||||
<span>应收统计</span>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
<div style="display: flex;justify-content: space-around;">
|
|
||||||
<div v-for=" item in customList" :key="item" style="text-align: center;">
|
|
||||||
<div>{{ item.value }}</div>
|
|
||||||
<div>{{ item.name }}</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<el-table :data="pager.lists" @selection-change="handleSelectionChange" style="margin-top: 20px;">
|
|
||||||
<el-table-column type="selection" width="55" />
|
|
||||||
<el-table-column label="序号" type="index" width="55" />
|
|
||||||
<el-table-column label="项目名称" prop="project_name" show-overflow-tooltip />
|
|
||||||
<el-table-column label="技术人员" prop="technician" show-overflow-tooltip />
|
|
||||||
<el-table-column label="商务人员" prop="business_people" show-overflow-tooltip />
|
|
||||||
<el-table-column label="跨部门人员" prop="cross_departmental_personnel" show-overflow-tooltip />
|
|
||||||
<el-table-column label="添加人" prop="add_user" show-overflow-tooltip />
|
|
||||||
</el-table>
|
|
||||||
<div class="flex justify-end mt-4">
|
|
||||||
<pagination v-model="pager" @change="getLists" />
|
|
||||||
</div>
|
|
||||||
</el-card>
|
|
||||||
<el-card style="width: 49.9%;">
|
|
||||||
<template #header>
|
|
||||||
<div class="card-header">
|
|
||||||
<span>应付统计</span>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
<div style="display: flex;justify-content: space-around;">
|
|
||||||
<div v-for=" item in customList" :key="item" style="text-align: center;">
|
|
||||||
<div>{{ item.value }}</div>
|
|
||||||
<div>{{ item.name }}</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<el-table :data="pager.lists" @selection-change="handleSelectionChange" style="margin-top: 20px;">
|
|
||||||
<el-table-column type="selection" width="55" />
|
|
||||||
<el-table-column label="序号" type="index" width="55" />
|
|
||||||
<el-table-column label="项目名称" prop="project_name" show-overflow-tooltip />
|
|
||||||
<el-table-column label="技术人员" prop="technician" show-overflow-tooltip />
|
|
||||||
<el-table-column label="商务人员" prop="business_people" show-overflow-tooltip />
|
|
||||||
<el-table-column label="跨部门人员" prop="cross_departmental_personnel" show-overflow-tooltip />
|
|
||||||
<el-table-column label="添加人" prop="add_user" show-overflow-tooltip />
|
|
||||||
</el-table>
|
|
||||||
<div class="flex justify-end mt-4">
|
|
||||||
<pagination v-model="pager" @change="getLists" />
|
|
||||||
</div>
|
|
||||||
</el-card>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@ -187,555 +15,15 @@
|
|||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import * as echarts from 'echarts';
|
import * as echarts from 'echarts';
|
||||||
import { onMounted } from "vue"
|
|
||||||
import { reactive, ref } from "vue"
|
import { reactive, ref } from "vue"
|
||||||
import { usePaging } from '@/hooks/usePaging'
|
import Custom from "./components/Custom.vue"
|
||||||
import { apiProjectPreSalesMembersLists, } from '@/api/project_pre_sales_members'
|
import Project from "./components/Project.vue"
|
||||||
|
import Tender from "./components/Tender.vue"
|
||||||
|
import projectContracts from "./components/projectContracts.vue"
|
||||||
|
import ProjectPayment from "./components/ProjectPayment.vue"
|
||||||
|
import PurchaseContracts from "./components/PurchaseContracts.vue"
|
||||||
|
import Subcontract from "./components/Subcontract.vue"
|
||||||
|
import ProjectWithdraw from "./components/ProjectWithdraw.vue"
|
||||||
|
|
||||||
|
|
||||||
const { pager, getLists, resetParams, resetPage } = usePaging({
|
|
||||||
fetchFun: apiProjectPreSalesMembersLists,
|
|
||||||
// params: queryParams
|
|
||||||
})
|
|
||||||
getLists()
|
|
||||||
const customList = reactive([
|
|
||||||
{
|
|
||||||
name: "客户总数",
|
|
||||||
value: 3
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "客户总数",
|
|
||||||
value: 3
|
|
||||||
}, {
|
|
||||||
name: "客户总数",
|
|
||||||
value: 3
|
|
||||||
}, {
|
|
||||||
name: "客户总数",
|
|
||||||
value: 3
|
|
||||||
}, {
|
|
||||||
name: "客户总数",
|
|
||||||
value: 3
|
|
||||||
},
|
|
||||||
])
|
|
||||||
|
|
||||||
const customLists = reactive([
|
|
||||||
{
|
|
||||||
name: "客户总数",
|
|
||||||
value: 3
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "客户总数",
|
|
||||||
value: 3
|
|
||||||
}, {
|
|
||||||
name: "客户总数",
|
|
||||||
value: 3
|
|
||||||
}, {
|
|
||||||
name: "客户总数",
|
|
||||||
value: 3
|
|
||||||
}, {
|
|
||||||
name: "客户总数",
|
|
||||||
value: 3
|
|
||||||
},
|
|
||||||
])
|
|
||||||
var app = {};
|
|
||||||
const posList = [
|
|
||||||
'left',
|
|
||||||
'right',
|
|
||||||
'top',
|
|
||||||
'bottom',
|
|
||||||
'inside',
|
|
||||||
'insideTop',
|
|
||||||
'insideLeft',
|
|
||||||
'insideRight',
|
|
||||||
'insideBottom',
|
|
||||||
'insideTopLeft',
|
|
||||||
'insideTopRight',
|
|
||||||
'insideBottomLeft',
|
|
||||||
'insideBottomRight'
|
|
||||||
];
|
|
||||||
app.configParameters = {
|
|
||||||
rotate: {
|
|
||||||
min: -90,
|
|
||||||
max: 90
|
|
||||||
},
|
|
||||||
align: {
|
|
||||||
options: {
|
|
||||||
left: 'left',
|
|
||||||
center: 'center',
|
|
||||||
right: 'right'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
verticalAlign: {
|
|
||||||
options: {
|
|
||||||
top: 'top',
|
|
||||||
middle: 'middle',
|
|
||||||
bottom: 'bottom'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
position: {
|
|
||||||
options: posList.reduce(function (map, pos) {
|
|
||||||
map[pos] = pos;
|
|
||||||
return map;
|
|
||||||
}, {})
|
|
||||||
},
|
|
||||||
distance: {
|
|
||||||
min: 0,
|
|
||||||
max: 100
|
|
||||||
}
|
|
||||||
};
|
|
||||||
app.config = {
|
|
||||||
rotate: 90,
|
|
||||||
align: 'left',
|
|
||||||
verticalAlign: 'middle',
|
|
||||||
position: 'insideBottom',
|
|
||||||
distance: 15,
|
|
||||||
onChange: function () {
|
|
||||||
const labelOption = {
|
|
||||||
rotate: app.config.rotate,
|
|
||||||
align: app.config.align,
|
|
||||||
verticalAlign: app.config.verticalAlign,
|
|
||||||
position: app.config.position,
|
|
||||||
distance: app.config.distance
|
|
||||||
};
|
|
||||||
myChart.setOption({
|
|
||||||
series: [
|
|
||||||
{
|
|
||||||
label: labelOption
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: labelOption
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: labelOption
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: labelOption
|
|
||||||
}
|
|
||||||
]
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
const labelOption = {
|
|
||||||
show: true,
|
|
||||||
rich: {
|
|
||||||
name: {}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
var option = {
|
|
||||||
tooltip: {
|
|
||||||
trigger: 'axis',
|
|
||||||
axisPointer: {
|
|
||||||
type: 'shadow'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
legend: {
|
|
||||||
data: ['名称', 'Steppe', 'Desert', 'Wetland']
|
|
||||||
},
|
|
||||||
toolbox: {
|
|
||||||
show: true,
|
|
||||||
orient: 'vertical',
|
|
||||||
left: 'right',
|
|
||||||
top: 'center',
|
|
||||||
},
|
|
||||||
xAxis: [
|
|
||||||
{
|
|
||||||
type: 'category',
|
|
||||||
axisTick: { show: false },
|
|
||||||
data: ['2012', '2013', '2014', '2015', '2016', '2012', '2013', '2014', '2015', '2016']
|
|
||||||
}
|
|
||||||
],
|
|
||||||
yAxis: [
|
|
||||||
{
|
|
||||||
type: 'value'
|
|
||||||
}
|
|
||||||
],
|
|
||||||
series: [
|
|
||||||
{
|
|
||||||
name: '名称',
|
|
||||||
type: 'bar',
|
|
||||||
barGap: 0,
|
|
||||||
label: labelOption,
|
|
||||||
emphasis: {
|
|
||||||
focus: 'series'
|
|
||||||
},
|
|
||||||
data: [320, 332, 301, 334, 390]
|
|
||||||
},
|
|
||||||
// {
|
|
||||||
// name: 'Steppe',
|
|
||||||
// type: 'bar',
|
|
||||||
// label: labelOption,
|
|
||||||
// emphasis: {
|
|
||||||
// focus: 'series'
|
|
||||||
// },
|
|
||||||
// data: [220, 182, 191, 234, 290]
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// name: 'Desert',
|
|
||||||
// type: 'bar',
|
|
||||||
// label: labelOption,
|
|
||||||
// emphasis: {
|
|
||||||
// focus: 'series'
|
|
||||||
// },
|
|
||||||
// data: [150, 232, 201, 154, 190]
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// name: 'Wetland',
|
|
||||||
// type: 'bar',
|
|
||||||
// label: labelOption,
|
|
||||||
// emphasis: {
|
|
||||||
// focus: 'series'
|
|
||||||
// },
|
|
||||||
// data: [98, 77, 101, 99, 40]
|
|
||||||
// }
|
|
||||||
]
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
var option4 = {
|
|
||||||
tooltip: {
|
|
||||||
trigger: 'axis',
|
|
||||||
axisPointer: {
|
|
||||||
type: 'shadow'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
legend: {
|
|
||||||
data: ['名称', 'Steppe', 'Desert', 'Wetland']
|
|
||||||
},
|
|
||||||
toolbox: {
|
|
||||||
show: true,
|
|
||||||
orient: 'vertical',
|
|
||||||
left: 'right',
|
|
||||||
top: 'center',
|
|
||||||
|
|
||||||
},
|
|
||||||
xAxis: [
|
|
||||||
{
|
|
||||||
type: 'category',
|
|
||||||
axisTick: { show: false },
|
|
||||||
data: ['2012', '2013', '2014', '2015', '2016', '2012', '2013', '2014', '2015', '2016']
|
|
||||||
}
|
|
||||||
],
|
|
||||||
yAxis: [
|
|
||||||
{
|
|
||||||
type: 'value'
|
|
||||||
}
|
|
||||||
],
|
|
||||||
series: [
|
|
||||||
{
|
|
||||||
name: '名称',
|
|
||||||
type: 'bar',
|
|
||||||
barGap: 0,
|
|
||||||
label: labelOption,
|
|
||||||
emphasis: {
|
|
||||||
focus: 'series'
|
|
||||||
},
|
|
||||||
data: [320, 332, 301, 334, 390],
|
|
||||||
itemStyle: {
|
|
||||||
normal: {
|
|
||||||
label: {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'Steppe',
|
|
||||||
type: 'bar',
|
|
||||||
label: labelOption,
|
|
||||||
emphasis: {
|
|
||||||
focus: 'series'
|
|
||||||
},
|
|
||||||
data: [220, 182, 191, 234, 290],
|
|
||||||
itemStyle: {
|
|
||||||
normal: {
|
|
||||||
label: {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'Desert',
|
|
||||||
type: 'bar',
|
|
||||||
label: labelOption,
|
|
||||||
emphasis: {
|
|
||||||
focus: 'series'
|
|
||||||
},
|
|
||||||
data: [150, 232, 201, 154, 190],
|
|
||||||
itemStyle: {
|
|
||||||
normal: {
|
|
||||||
label: {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
// {
|
|
||||||
// name: 'Wetland',
|
|
||||||
// type: 'bar',
|
|
||||||
// label: labelOption,
|
|
||||||
// emphasis: {
|
|
||||||
// focus: 'series'
|
|
||||||
// },
|
|
||||||
// data: [98, 77, 101, 99, 40]
|
|
||||||
// }
|
|
||||||
]
|
|
||||||
};
|
|
||||||
|
|
||||||
let option2 = {
|
|
||||||
title: {
|
|
||||||
text: '',
|
|
||||||
subtext: '',
|
|
||||||
left: 'center'
|
|
||||||
},
|
|
||||||
tooltip: {
|
|
||||||
trigger: 'item'
|
|
||||||
},
|
|
||||||
|
|
||||||
series: [
|
|
||||||
{
|
|
||||||
name: 'Access From',
|
|
||||||
type: 'pie',
|
|
||||||
radius: '50%',
|
|
||||||
data: [
|
|
||||||
{ value: 1048, name: 'Search Engine' },
|
|
||||||
{ value: 735, name: 'Direct' },
|
|
||||||
{ value: 580, name: 'Email' },
|
|
||||||
{ value: 484, name: 'Union Ads' },
|
|
||||||
{ value: 300, name: 'Video Ads' }
|
|
||||||
],
|
|
||||||
emphasis: {
|
|
||||||
itemStyle: {
|
|
||||||
shadowBlur: 10,
|
|
||||||
shadowOffsetX: 0,
|
|
||||||
shadowColor: 'rgba(0, 0, 0, 0.5)'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
};
|
|
||||||
|
|
||||||
let value = 58; //图上角度数据
|
|
||||||
let option3 = {
|
|
||||||
title: {
|
|
||||||
text: '{a|' + value + '}{c|%}',
|
|
||||||
x: 'center',
|
|
||||||
y: 'center',
|
|
||||||
textStyle: {
|
|
||||||
rich: {
|
|
||||||
a: {
|
|
||||||
fontSize: 20,
|
|
||||||
color: 'black',
|
|
||||||
fontWeight: 'bold'
|
|
||||||
},
|
|
||||||
c: {
|
|
||||||
fontSize: 20,
|
|
||||||
color: 'black',
|
|
||||||
fontWeight: 'normal'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
series: [
|
|
||||||
//外环
|
|
||||||
{
|
|
||||||
name: "外环",
|
|
||||||
type: 'pie',
|
|
||||||
silent: true,
|
|
||||||
clockwise: true,
|
|
||||||
radius: ['70%', '75%'],
|
|
||||||
label: {
|
|
||||||
show: false,
|
|
||||||
},
|
|
||||||
labelLine: {
|
|
||||||
show: false
|
|
||||||
},
|
|
||||||
itemStyle: {
|
|
||||||
color: 'white',
|
|
||||||
},
|
|
||||||
data: [0]
|
|
||||||
},
|
|
||||||
//内环
|
|
||||||
{
|
|
||||||
name: "内环",
|
|
||||||
type: 'pie',
|
|
||||||
silent: true,
|
|
||||||
clockwise: true,
|
|
||||||
radius: ['45%', '46%'],
|
|
||||||
label: {
|
|
||||||
show: false,
|
|
||||||
},
|
|
||||||
labelLine: {
|
|
||||||
show: false
|
|
||||||
},
|
|
||||||
itemStyle: {
|
|
||||||
color: '#414f63',
|
|
||||||
},
|
|
||||||
data: [0]
|
|
||||||
},
|
|
||||||
//外环
|
|
||||||
{
|
|
||||||
name: '',
|
|
||||||
type: 'pie',
|
|
||||||
radius: ['55%', '65%'],
|
|
||||||
silent: true,
|
|
||||||
clockwise: true,
|
|
||||||
startAngle: 90,
|
|
||||||
label: {
|
|
||||||
show: false,
|
|
||||||
},
|
|
||||||
data: [
|
|
||||||
{
|
|
||||||
value: value,
|
|
||||||
itemStyle: {
|
|
||||||
normal: {
|
|
||||||
//外环发光
|
|
||||||
borderWidth: 0.5,
|
|
||||||
shadowBlur: 20,
|
|
||||||
borderColor: '#4bf3f9',
|
|
||||||
shadowColor: '#9bfeff',
|
|
||||||
color: { // 圆环的颜色
|
|
||||||
colorStops: [{
|
|
||||||
offset: 0,
|
|
||||||
color: '#15caff', // 0% 处的颜色
|
|
||||||
}, {
|
|
||||||
offset: 1,
|
|
||||||
color: '#159bfe', // 100% 处的颜色
|
|
||||||
}]
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
value: 100 - value,
|
|
||||||
label: {
|
|
||||||
normal: {
|
|
||||||
show: false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
itemStyle: {
|
|
||||||
normal: {
|
|
||||||
color: "#364662"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
]
|
|
||||||
};
|
|
||||||
|
|
||||||
// 获取柱状图option
|
|
||||||
const setHistogramOption = (legend, xAxisData, series) => {
|
|
||||||
return {
|
|
||||||
tooltip: {
|
|
||||||
trigger: 'axis',
|
|
||||||
axisPointer: {
|
|
||||||
type: 'shadow'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
// legend: {
|
|
||||||
// data: ['名称', 'Steppe', 'Desert', 'Wetland']
|
|
||||||
// },
|
|
||||||
legend,
|
|
||||||
toolbox: {
|
|
||||||
show: true,
|
|
||||||
orient: 'vertical',
|
|
||||||
left: 'right',
|
|
||||||
top: 'center',
|
|
||||||
},
|
|
||||||
xAxis: [
|
|
||||||
{
|
|
||||||
type: 'category',
|
|
||||||
axisTick: { show: false },
|
|
||||||
// data: ['2012', '2013', '2014', '2015', '2016', '2012', '2013', '2014', '2015', '2016']
|
|
||||||
data: xAxisData
|
|
||||||
}
|
|
||||||
],
|
|
||||||
yAxis: [
|
|
||||||
{
|
|
||||||
type: 'value'
|
|
||||||
}
|
|
||||||
],
|
|
||||||
// series: [
|
|
||||||
// // {
|
|
||||||
// // name: '名称',
|
|
||||||
// // type: 'bar',
|
|
||||||
// // barGap: 0,
|
|
||||||
// // label: labelOption,
|
|
||||||
// // emphasis: {
|
|
||||||
// // focus: 'series'
|
|
||||||
// // },
|
|
||||||
// // data: [320, 332, 301, 334, 390]
|
|
||||||
// // },
|
|
||||||
// // {
|
|
||||||
// // name: 'Steppe',
|
|
||||||
// // type: 'bar',
|
|
||||||
// // label: labelOption,
|
|
||||||
// // emphasis: {
|
|
||||||
// // focus: 'series'
|
|
||||||
// // },
|
|
||||||
// // data: [220, 182, 191, 234, 290]
|
|
||||||
// // },
|
|
||||||
// // {
|
|
||||||
// // name: 'Desert',
|
|
||||||
// // type: 'bar',
|
|
||||||
// // label: labelOption,
|
|
||||||
// // emphasis: {
|
|
||||||
// // focus: 'series'
|
|
||||||
// // },
|
|
||||||
// // data: [150, 232, 201, 154, 190]
|
|
||||||
// // },
|
|
||||||
// // {
|
|
||||||
// // name: 'Wetland',
|
|
||||||
// // type: 'bar',
|
|
||||||
// // label: labelOption,
|
|
||||||
// // emphasis: {
|
|
||||||
// // focus: 'series'
|
|
||||||
// // },
|
|
||||||
// // data: [98, 77, 101, 99, 40]
|
|
||||||
// // }
|
|
||||||
// ]
|
|
||||||
series
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
const initChart = (id, opt) => {
|
|
||||||
var chartDom = document.getElementById(id);
|
|
||||||
var myChart = echarts.init(chartDom);
|
|
||||||
myChart.setOption(opt);
|
|
||||||
}
|
|
||||||
|
|
||||||
onMounted(() => {
|
|
||||||
initChart("customNum", setHistogramOption({ data: ['名称'] }, ['2012', '2013', '2014', '2015', '2016', '2012', '2013', '2014', '2015', '2016'], [{
|
|
||||||
name: '名称',
|
|
||||||
type: 'bar',
|
|
||||||
barGap: 0,
|
|
||||||
label: labelOption,
|
|
||||||
emphasis: {
|
|
||||||
focus: 'series'
|
|
||||||
},
|
|
||||||
data: [320, 332, 301, 334, 390]
|
|
||||||
},]))
|
|
||||||
initChart("projectApproved", option2)
|
|
||||||
|
|
||||||
initChart("main", option3)
|
|
||||||
initChart("main2", option2)
|
|
||||||
initChart("main3", option)
|
|
||||||
initChart("main4", option)
|
|
||||||
initChart("main5", option)
|
|
||||||
initChart("main6", option4)
|
|
||||||
initChart("main7", option2)
|
|
||||||
})
|
|
||||||
</script>
|
</script>
|
||||||
<style lang="scss" scoped>
|
|
||||||
#main,
|
|
||||||
#main2,
|
|
||||||
#main3 {
|
|
||||||
width: 100%;
|
|
||||||
height: 300px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.chart {
|
|
||||||
width: 100%;
|
|
||||||
height: 300px;
|
|
||||||
}
|
|
||||||
</style>
|
|
Loading…
x
Reference in New Issue
Block a user