|
@@ -9,7 +9,7 @@
|
|
|
placeholder="月份"
|
|
|
@change="onQuery"
|
|
|
/>
|
|
|
- </el-form-item> -->
|
|
|
+ </el-form-item>
|
|
|
<el-form-item label="">
|
|
|
<el-radio-group v-model="queryForm.bb" size="large" @change="onQuery">
|
|
|
<el-radio-button label="本日" />
|
|
@@ -18,7 +18,7 @@
|
|
|
<el-radio-button label="今年" />
|
|
|
<el-radio-button label="其他" />
|
|
|
</el-radio-group>
|
|
|
- </el-form-item>
|
|
|
+ </el-form-item> -->
|
|
|
<el-form-item>
|
|
|
<el-date-picker
|
|
|
v-model="queryForm.timeArr"
|
|
@@ -42,47 +42,32 @@
|
|
|
style="margin-top: 10px"
|
|
|
v-loading="statisticsLoading"
|
|
|
>
|
|
|
- <div class="item first">
|
|
|
- <div class="left_">
|
|
|
- <div class="money">
|
|
|
- {{ moneyFormat(allData.salesStatisticsData.amount, 2) }}
|
|
|
- </div>
|
|
|
- <div>销售额(¥)</div>
|
|
|
- </div>
|
|
|
- <div class="right_">
|
|
|
- <div class="icon">
|
|
|
- <img src="@/assets/images/portrait/icon_sales.png" alt="" />
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- <div class="item two">
|
|
|
- <div class="left_">
|
|
|
- <div class="money">
|
|
|
- {{ allData.salesStatisticsData.contractCount }}
|
|
|
- </div>
|
|
|
- <div>订单(单)</div>
|
|
|
- </div>
|
|
|
- <div class="right_">
|
|
|
- <div class="icon">
|
|
|
- <img src="@/assets/images/portrait/icon_profits.png" alt="" />
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- <div class="item three">
|
|
|
- <div class="left_">
|
|
|
- <div class="money">
|
|
|
- {{ allData.salesStatisticsData.customerCount }}
|
|
|
- </div>
|
|
|
- <div>下单客户数(人)</div>
|
|
|
- </div>
|
|
|
- <div class="right_">
|
|
|
- <div class="icon">
|
|
|
- <img src="@/assets/images/portrait/icon_email.png" alt="" />
|
|
|
- </div>
|
|
|
- </div>
|
|
|
+ <div class="stat-warp">
|
|
|
+ <ul>
|
|
|
+ <li class="theme1">
|
|
|
+ <div class="num">{{ moneyFormat(allData.salesStatisticsData.amount, 2) }}</div>
|
|
|
+ <div class="label">销售额(¥)</div>
|
|
|
+ <div class="icon-box">
|
|
|
+ <i class="icon iconfont icon-iconx_caiwgl"></i>
|
|
|
+ </div>
|
|
|
+ </li>
|
|
|
+ <li class="theme2">
|
|
|
+ <div class="num">{{ allData.salesStatisticsData.contractCount }}</div>
|
|
|
+ <div class="label">订单(单)</div>
|
|
|
+ <div class="icon-box">
|
|
|
+ <i class="icon iconfont icon-iconm_fukgl"></i>
|
|
|
+ </div>
|
|
|
+ </li>
|
|
|
+ <li class="theme3">
|
|
|
+ <div class="num"> {{ allData.salesStatisticsData.customerCount }}</div>
|
|
|
+ <div class="label">下单客户数(人)</div>
|
|
|
+ <div class="icon-box">
|
|
|
+ <i class="icon iconfont icon-iconm_unread"></i>
|
|
|
+ </div>
|
|
|
+ </li>
|
|
|
+ </ul>
|
|
|
</div>
|
|
|
</div>
|
|
|
-
|
|
|
<div
|
|
|
class="bck scatter"
|
|
|
style="margin-top: 10px"
|
|
@@ -91,19 +76,29 @@
|
|
|
<el-row>
|
|
|
<el-col :span="8">
|
|
|
<TitleInfo :content="titleList[0]"></TitleInfo>
|
|
|
- <div ref="echartDomOne" style="height: 40vh"></div>
|
|
|
+ <div ref="echartDom" style="height: 40vh"></div>
|
|
|
</el-col>
|
|
|
<el-col :span="16">
|
|
|
- <div ref="echartDomTwo" style="height: 40vh"></div>
|
|
|
+ <byTable
|
|
|
+ :hideSearch="true"
|
|
|
+ :tableHeight="tableHeight"
|
|
|
+ :source="sourceList.scatterData"
|
|
|
+ :pagination="sourceList.scatterPagination"
|
|
|
+ :config="scatterConfig"
|
|
|
+ :loading="scatterLoading"
|
|
|
+ highlight-current-row
|
|
|
+ :hidePagination="true"
|
|
|
+ :selectConfig="[]"
|
|
|
+ >
|
|
|
+ </byTable>
|
|
|
</el-col>
|
|
|
</el-row>
|
|
|
</div>
|
|
|
-
|
|
|
<div style="margin-top: 10px">
|
|
|
<el-row>
|
|
|
<el-col :span="12" class="bck" v-loading="salesLoading">
|
|
|
<TitleInfo :content="titleList[1]"></TitleInfo>
|
|
|
- <div ref="echartDomOne22" style="height: 30vh"></div>
|
|
|
+ <div ref="echartDomOne" style="height: 30vh"></div>
|
|
|
<div style="margin-top: 10px">
|
|
|
<byTable
|
|
|
:hideSearch="true"
|
|
@@ -121,7 +116,7 @@
|
|
|
<el-col :span="12" style="padding-left: 10px">
|
|
|
<div class="bck" v-loading="salesmanSalesLoading">
|
|
|
<TitleInfo :content="titleList[2]"></TitleInfo>
|
|
|
- <!-- <div ref="echartDomTwo" style="height: 30vh"></div> -->
|
|
|
+ <div ref="echartDomTwo" style="height: 30vh"></div>
|
|
|
<div style="margin-top: 10px">
|
|
|
<byTable
|
|
|
:hideSearch="true"
|
|
@@ -246,6 +241,7 @@ const allData = reactive({
|
|
|
salesStatisticsData: {},
|
|
|
});
|
|
|
//图表
|
|
|
+const echartDom = ref(null);
|
|
|
const echartDomOne = ref(null);
|
|
|
const echartDomTwo = ref(null);
|
|
|
const echartDomThree = ref(null);
|
|
@@ -266,13 +262,14 @@ const optionOne = reactive({
|
|
|
},
|
|
|
series: [
|
|
|
{
|
|
|
- name: '111',
|
|
|
- type: 'pie',
|
|
|
- radius: [20, 140],
|
|
|
- center: ['50%', '50%'],
|
|
|
- roseType: 'area',
|
|
|
+ name: "销售分析",
|
|
|
+ type: "pie",
|
|
|
+ radius: ["30%", "70%"],
|
|
|
+ avoidLabelOverlap: false,
|
|
|
itemStyle: {
|
|
|
- borderRadius: 5
|
|
|
+ borderRadius: 10,
|
|
|
+ borderColor: "#fff",
|
|
|
+ borderWidth: 2,
|
|
|
},
|
|
|
label: {
|
|
|
show: false,
|
|
@@ -289,35 +286,57 @@ const optionOne = reactive({
|
|
|
show: false,
|
|
|
},
|
|
|
data: [
|
|
|
- { value: 1048, name: "中国" },
|
|
|
- { value: 735, name: "美国" },
|
|
|
- { value: 580, name: "韩国" },
|
|
|
- { value: 484, name: "德国" },
|
|
|
- { value: 300, name: "xxx" },
|
|
|
+ { value: 1048, name: "Search Engine" },
|
|
|
+ { value: 735, name: "Direct" },
|
|
|
+ { value: 580, name: "Email" },
|
|
|
+ { value: 484, name: "Union Ads" },
|
|
|
+ { value: 300, name: "Video Ads" },
|
|
|
],
|
|
|
},
|
|
|
],
|
|
|
},
|
|
|
});
|
|
|
const optionTwo = reactive({
|
|
|
- data:{
|
|
|
- legend: {},
|
|
|
- tooltip: {},
|
|
|
- dataset: {
|
|
|
- source: [
|
|
|
- ['product', '订单量', '交易金额'],
|
|
|
- ['Matcha Latte', 43.3, 85.8],
|
|
|
- ['Milk Tea', 83.1, 73.4],
|
|
|
- ['Cheese Cocoa', 86.4, 65.2],
|
|
|
- ['Walnut Brownie', 72.4, 53.9]
|
|
|
- ]
|
|
|
+ data: {
|
|
|
+ tooltip: {
|
|
|
+ trigger: "axis",
|
|
|
+ axisPointer: {
|
|
|
+ type: "shadow",
|
|
|
+ },
|
|
|
},
|
|
|
- xAxis: { type: 'category' },
|
|
|
- yAxis: {},
|
|
|
- // Declare several bar series, each will be mapped
|
|
|
- // to a column of dataset.source by default.
|
|
|
- series: [{ type: 'bar' }, { type: 'bar' }]
|
|
|
- }
|
|
|
+ grid: {
|
|
|
+ left: "1%",
|
|
|
+ right: "1%",
|
|
|
+ bottom: "1%",
|
|
|
+ top: "10%",
|
|
|
+ containLabel: true,
|
|
|
+ },
|
|
|
+ xAxis: [
|
|
|
+ {
|
|
|
+ type: "category",
|
|
|
+ data: ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"],
|
|
|
+ axisTick: {
|
|
|
+ alignWithLabel: true,
|
|
|
+ },
|
|
|
+ },
|
|
|
+ ],
|
|
|
+ yAxis: [
|
|
|
+ {
|
|
|
+ type: "value",
|
|
|
+ },
|
|
|
+ ],
|
|
|
+ series: [
|
|
|
+ {
|
|
|
+ name: "名称",
|
|
|
+ type: "bar",
|
|
|
+ barWidth: "25%",
|
|
|
+ data: [10, 52, 200, 334, 390, 330, 220],
|
|
|
+ itemStyle: {
|
|
|
+ color: "#0084FF",
|
|
|
+ },
|
|
|
+ },
|
|
|
+ ],
|
|
|
+ },
|
|
|
});
|
|
|
const scatterConfig = computed(() => {
|
|
|
return [
|
|
@@ -433,6 +452,9 @@ const productSalesConfig = computed(() => {
|
|
|
},
|
|
|
];
|
|
|
});
|
|
|
+const tableHeight = computed(() => {
|
|
|
+ return document.documentElement.clientHeight / 10 * 4;
|
|
|
+});
|
|
|
|
|
|
const productSalesOneConfig = computed(() => {
|
|
|
return [
|
|
@@ -476,64 +498,63 @@ const getData = () => {
|
|
|
});
|
|
|
proxy.post("/contract/countrySalesStatistics", queryForm).then((res) => {
|
|
|
sourceList.value.scatterData = res;
|
|
|
- // optionOne.data.series[0].data = res.map((x) => ({
|
|
|
- // value: x.amount,
|
|
|
- // name: x.countryName,
|
|
|
- // }));
|
|
|
- myChartOne.setOption(optionOne.data);
|
|
|
+ optionOne.data.series[0].data = res.map((x) => ({
|
|
|
+ value: x.amount,
|
|
|
+ name: x.countryName,
|
|
|
+ }));
|
|
|
+ myChart.setOption(optionOne.data);
|
|
|
setTimeout(() => {
|
|
|
scatterLoading.value = false;
|
|
|
}, 200);
|
|
|
- myChartTwo.setOption(optionTwo.data);
|
|
|
+ });
|
|
|
+
|
|
|
+ proxy.post("/contract/customSalesStatistics", queryForm).then((res) => {
|
|
|
+ sourceList.value.salesData = res;
|
|
|
+ const option = { ...optionTwo };
|
|
|
+ option.data.xAxis[0].data = res.map((x) => x.corporationName);
|
|
|
+ option.data.series[0].data = res.map((x) => x.amount);
|
|
|
+ option.data.series[0].name = "销售额(¥)";
|
|
|
+ myChartOne.setOption(option.data);
|
|
|
setTimeout(() => {
|
|
|
- salesmanSalesLoading.value = false;
|
|
|
+ salesLoading.value = false;
|
|
|
}, 200);
|
|
|
});
|
|
|
|
|
|
- // proxy.post("/contract/customSalesStatistics", queryForm).then((res) => {
|
|
|
- // sourceList.value.salesData = res;
|
|
|
- // const option = { ...optionTwo };
|
|
|
- // // option.data.xAxis[0].data = res.map((x) => x.corporationName);
|
|
|
- // // option.data.series[0].data = res.map((x) => x.amount);
|
|
|
- // // option.data.series[0].name = "销售额(¥)";
|
|
|
-
|
|
|
- // });
|
|
|
-
|
|
|
- // proxy.post("/contract/salesmanSalesStatistics", queryForm).then((res) => {
|
|
|
- // sourceList.value.salesmanSalesData = res;
|
|
|
- // const option = { ...optionTwo };
|
|
|
- // option.data.xAxis[0].data = res.map((x) => x.userName);
|
|
|
- // option.data.series[0].data = res.map((x) => x.amount);
|
|
|
- // option.data.series[0].name = "销售额(¥)";
|
|
|
- // myChartTwo.setOption(option.data);
|
|
|
- // setTimeout(() => {
|
|
|
- // salesmanSalesLoading.value = false;
|
|
|
- // }, 200);
|
|
|
- // });
|
|
|
+ proxy.post("/contract/salesmanSalesStatistics", queryForm).then((res) => {
|
|
|
+ sourceList.value.salesmanSalesData = res;
|
|
|
+ const option = { ...optionTwo };
|
|
|
+ option.data.xAxis[0].data = res.map((x) => x.userName);
|
|
|
+ option.data.series[0].data = res.map((x) => x.amount);
|
|
|
+ option.data.series[0].name = "销售额(¥)";
|
|
|
+ myChartTwo.setOption(option.data);
|
|
|
+ setTimeout(() => {
|
|
|
+ salesmanSalesLoading.value = false;
|
|
|
+ }, 200);
|
|
|
+ });
|
|
|
|
|
|
- // proxy.post("/contract/productSalesStatistics", queryForm).then((res) => {
|
|
|
- // sourceList.value.productSalesVolumeData = res;
|
|
|
- // const option = { ...optionTwo };
|
|
|
- // option.data.xAxis[0].data = res.map((x) => x.productName);
|
|
|
- // option.data.series[0].data = res.map((x) => x.amount);
|
|
|
- // option.data.series[0].name = "销售额(¥)";
|
|
|
- // myChartThree.setOption(option.data);
|
|
|
- // setTimeout(() => {
|
|
|
- // productSalesLoading.value = false;
|
|
|
- // }, 200);
|
|
|
- // });
|
|
|
+ proxy.post("/contract/productSalesStatistics", queryForm).then((res) => {
|
|
|
+ sourceList.value.productSalesVolumeData = res;
|
|
|
+ const option = { ...optionTwo };
|
|
|
+ option.data.xAxis[0].data = res.map((x) => x.productName);
|
|
|
+ option.data.series[0].data = res.map((x) => x.amount);
|
|
|
+ option.data.series[0].name = "销售额(¥)";
|
|
|
+ myChartThree.setOption(option.data);
|
|
|
+ setTimeout(() => {
|
|
|
+ productSalesLoading.value = false;
|
|
|
+ }, 200);
|
|
|
+ });
|
|
|
|
|
|
- // proxy.post("/contract/salesVolumeStatistics", queryForm).then((res) => {
|
|
|
- // sourceList.value.productSalesVolumeOneData = res;
|
|
|
- // const option = { ...optionTwo };
|
|
|
- // option.data.xAxis[0].data = res.map((x) => x.productName);
|
|
|
- // option.data.series[0].data = res.map((x) => x.quantity);
|
|
|
- // option.data.series[0].name = "销售量(个)";
|
|
|
- // myChartFour.setOption(option.data);
|
|
|
- // setTimeout(() => {
|
|
|
- // productSalesOneLoading.value = false;
|
|
|
- // }, 200);
|
|
|
- // });
|
|
|
+ proxy.post("/contract/salesVolumeStatistics", queryForm).then((res) => {
|
|
|
+ sourceList.value.productSalesVolumeOneData = res;
|
|
|
+ const option = { ...optionTwo };
|
|
|
+ option.data.xAxis[0].data = res.map((x) => x.productName);
|
|
|
+ option.data.series[0].data = res.map((x) => x.quantity);
|
|
|
+ option.data.series[0].name = "销售量(个)";
|
|
|
+ myChartFour.setOption(option.data);
|
|
|
+ setTimeout(() => {
|
|
|
+ productSalesOneLoading.value = false;
|
|
|
+ }, 200);
|
|
|
+ });
|
|
|
};
|
|
|
|
|
|
const onQuery = () => {
|
|
@@ -553,6 +574,10 @@ const onReset = () => {
|
|
|
};
|
|
|
|
|
|
onMounted(() => {
|
|
|
+ myChart = echarts.init(echartDom.value);
|
|
|
+ window.addEventListener("resize", () => {
|
|
|
+ myChart.resize();
|
|
|
+ });
|
|
|
// 客户分类柱状图
|
|
|
myChartOne = echarts.init(echartDomOne.value);
|
|
|
window.addEventListener("resize", () => {
|
|
@@ -573,6 +598,12 @@ onMounted(() => {
|
|
|
window.addEventListener("resize", () => {
|
|
|
myChartFour.resize();
|
|
|
});
|
|
|
+
|
|
|
+ let endData = new Date();
|
|
|
+ let beginDate = new Date();
|
|
|
+ beginDate.setMonth(0);
|
|
|
+ beginDate.setDate(1);
|
|
|
+ queryForm.timeArr = [proxy.parseTime(beginDate, "{y}-{m}-{d}"), proxy.parseTime(endData, "{y}-{m}-{d}")];
|
|
|
getData();
|
|
|
});
|
|
|
</script>
|
|
@@ -643,6 +674,155 @@ onMounted(() => {
|
|
|
background: linear-gradient(#ffebe9, #ffebe9);
|
|
|
}
|
|
|
}
|
|
|
+.stat-warp {
|
|
|
+ background: #fff;
|
|
|
+ padding: 20px;
|
|
|
+ overflow: hidden;
|
|
|
+ position: relative;
|
|
|
+ border-radius: 5px;
|
|
|
+
|
|
|
+ .title {
|
|
|
+ height: 60px;
|
|
|
+ select {
|
|
|
+ height: 60px;
|
|
|
+ border: none;
|
|
|
+ outline: none;
|
|
|
+ -webkit-appearance: none;
|
|
|
+ appearance: none;
|
|
|
+ font-size: 14px;
|
|
|
+ font-weight: bold;
|
|
|
+ background: url('@/assets/images/sanjiao.png') no-repeat right
|
|
|
+ center;
|
|
|
+ padding-right: 20px;
|
|
|
+ }
|
|
|
+ div {
|
|
|
+ height: 60px;
|
|
|
+ font-size: 14px;
|
|
|
+ font-weight: bold;
|
|
|
+ line-height: 60px;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ ul {
|
|
|
+ padding: 0;
|
|
|
+ overflow: hidden;
|
|
|
+ margin: 0;
|
|
|
+ li {
|
|
|
+ list-style: none;
|
|
|
+ min-width: 285px;
|
|
|
+ box-sizing: border-box;
|
|
|
+ margin-right: 20px;
|
|
|
+ background: linear-gradient(360deg, #C7E3FE 0%, #DFECFF 100%);
|
|
|
+ float: left;
|
|
|
+ overflow: hidden;
|
|
|
+ padding: 20px;
|
|
|
+ color: #333333;
|
|
|
+ position: relative;
|
|
|
+ border-radius: 10px;
|
|
|
+ cursor: pointer;
|
|
|
+ .label {
|
|
|
+ font-size: 14px;
|
|
|
+ margin-top: 10px;
|
|
|
+ }
|
|
|
+ .label::before {
|
|
|
+ // width: 10px;
|
|
|
+ // height: 10px;
|
|
|
+ // content: '';
|
|
|
+ // border-radius: 50%;
|
|
|
+ // background: #0084ff;
|
|
|
+ // display: inline-block;
|
|
|
+ // margin-right: 10px;
|
|
|
+
|
|
|
+ }
|
|
|
+ .num {
|
|
|
+
|
|
|
+ font-size: 24px;
|
|
|
+ font-weight: bold;
|
|
|
+ }
|
|
|
+ .icon-box{
|
|
|
+ position: absolute;
|
|
|
+ height: 40px;
|
|
|
+ width: 40px;
|
|
|
+ right: 20px;
|
|
|
+ top: 20px;
|
|
|
+ background: #fff;
|
|
|
+ border-radius: 10px;
|
|
|
+ text-align: center;
|
|
|
+ line-height: 40px;
|
|
|
+ i{
|
|
|
+ font-size: 20px;
|
|
|
+ color:#0084FF;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ //#F5F3FF #9E64ED
|
|
|
+ .theme2 {
|
|
|
+ background: linear-gradient(180deg, #EAE8FB 0%, #DED9FF 100%);
|
|
|
+ .label::before {
|
|
|
+ background: #7566F0;
|
|
|
+ }
|
|
|
+ .icon-box i {
|
|
|
+ color: #7566F0;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ //#FFF1E1 #FF9315
|
|
|
+ .theme3 {
|
|
|
+ background: #fff1e1;
|
|
|
+ .label::before {
|
|
|
+ background: #ff9315;
|
|
|
+ }
|
|
|
+ .icon-box i {
|
|
|
+ color: #FF9315;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ //#E2FBE8 #39C55A
|
|
|
+ .theme4 {
|
|
|
+ background: #e2fbe8;
|
|
|
+ .label::before {
|
|
|
+ background: #39c55a;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ .theme5 {
|
|
|
+ background: #ffebe9;
|
|
|
+ .label::before {
|
|
|
+ background: #f94539;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ .theme6 {
|
|
|
+ background: #e4f9f9;
|
|
|
+ .label::before {
|
|
|
+ background: #53cbcb;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ .multi-data {
|
|
|
+ .label::before {
|
|
|
+ display: none;
|
|
|
+ }
|
|
|
+ .label {
|
|
|
+ font-size: 14px;
|
|
|
+ font-weight: bold;
|
|
|
+ color: #333;
|
|
|
+ margin-bottom: 8px;
|
|
|
+ }
|
|
|
+ .num-warp {
|
|
|
+ overflow: hidden;
|
|
|
+ .num-box {
|
|
|
+ float: left;
|
|
|
+ min-width: 80px;
|
|
|
+ margin-right: 20px;
|
|
|
+ .num-small {
|
|
|
+ font-size: 16px;
|
|
|
+ font-weight: bold;
|
|
|
+ margin-bottom: 8px;
|
|
|
+ }
|
|
|
+ .label-small {
|
|
|
+ color: #666;
|
|
|
+ font-size: 14px;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
// .scatter {
|
|
|
// display: flex;
|
|
|
// }
|