commit message

This commit is contained in:
Chopper
2021-05-13 10:56:04 +08:00
commit ec3e958037
728 changed files with 132685 additions and 0 deletions

View File

@@ -0,0 +1,120 @@
<template>
<div>
<Affix :offset-top="100">
<Card class="card fixed-bottom">
<affixTime :closeShop="true" @selected="clickBreadcrumb"/>
</Card>
</Affix>
<Card class="card">
<Tabs @on-click="handleClickType">
<TabPane label="热门商品订单数量" name="NUM">
<Table :columns="columns" :data="data"></Table>
</TabPane>
<TabPane label="热门商品订单金额" name="PRICE">
<Table :columns="columns" :data="data"></Table>
</TabPane>
</Tabs>
</Card>
</div>
</template>
<script>
import memberLayout from "@/views/member/list";
import * as API_Goods from "@/api/goods";
import affixTime from "@/views/lili-components/affix-time";
export default {
components: {
affixTime,
memberLayout,
},
data() {
return {
total: 0,
year: "",
params: {
searchType: "LAST_SEVEN",
year: "",
month: "",
shopId: "",
type: "NUM"
},
columns: [
{
title: "商品名称",
key: "goodsName",
},
{
title: "销售数量",
key: "num",
},
{
title: "销售金额",
key: "price",
render: (h, params) => {
return h(
"div",
this.$options.filters.unitPrice(params.row.price)
);
},
},
],
data: [],
};
},
methods: {
handleClickType(name) {
this.params.type = name;
this.getData();
},
clickBreadcrumb(item, index) {
let callback = item;
let type = this.params.type;
this.params = {...callback};
this.params.type = type;
this.getData();
},
getData() {
Promise.all([API_Goods.goodsStatistics(this.params)]).then((res) => {
if (res[0].result) {
this.data = res[0].result;
}
});
},
},
mounted() {
this.getData();
},
};
</script>
<style scoped lang="scss">
.page-col {
text-align: right;
margin: 10px 0;
}
.order-col {
display: flex;
> div {
margin-right: 8px;
padding: 16px;
font-size: 15px;
}
}
.order-list {
display: flex;
}
.tips {
margin: 0 8px;
}
.card {
margin-bottom: 10px;
}
</style>

View File

@@ -0,0 +1,221 @@
<template>
<div class="wrapper">
<Affix :offset-top="100">
<Card class="card fixed-bottom">
<affixTime :closeShop="true" @selected="clickBreadcrumb" />
</Card>
</Affix>
<Card class="card">
<div>
<h4>客户增长趋势</h4>
<div id="orderChart"></div>
</div>
</Card>
<Card class="card">
<div>
<h4>客户增长报表</h4>
<Table style="margin-top:10px;" stripe :columns="columns" :data="data"></Table>
</div>
</Card>
</div>
</template>
<script>
import * as API_Member from "@/api/member";
import { Chart } from "@antv/g2";
import affixTime from "@/views/lili-components/affix-time";
export default {
components: { affixTime },
data() {
return {
columns: [
{
key: "createDate",
title: "日期",
sortable: true,
},
{
key: "memberCount",
title: "当前会员",
},
{
key: "newlyAdded",
title: "新增会员",
},
{
key: "activeQuantity",
title: "活跃会员",
},
],
// 时间
dateList: [
{
title: "今天",
selected: false,
value: "TODAY",
},
{
title: "昨天",
selected: false,
value: "YESTERDAY",
},
{
title: "最近7天",
selected: true,
value: "LAST_SEVEN",
},
{
title: "最近30天",
selected: false,
value: "LAST_THIRTY",
},
],
year: "",
orderChart: "",
defaultParams: {
month: "",
searchType: "LAST_SEVEN", // TODAY , YESTERDAY , LAST_SEVEN , LAST_THIRTY
storeId: "",
year: "",
},
params: {
searchType: "LAST_SEVEN",
year: "",
month: "",
shopId: "",
},
data: [],
};
},
watch: {
params: {
handler(val) {
this.init();
},
deep: true,
immediate:true,
},
year(val) {
this.params.year = new Date(val).getFullYear();
},
},
methods: {
// 订单图
initMemberChart() {
// 默认已经加载 legend-filter 交互
/**
* 将数据分成三组来进行展示
*/
let count = [];
let newly = [];
let actives = [];
this.data.forEach((item) => {
if (item.memberCount!="" || item.memberCount!=null) {
count.push({
createDate: item.createDate,
memberCount: item.memberCount,
title: "当前会员数量",
});
}
if (item.newlyAdded!="" || item.newlyAdded!=null) {
newly.push({
createDate: item.createDate,
memberCount: item.newlyAdded,
title: "新增会员数量",
});
}
if (item.activeQuantity!="" || item.activeQuantity!=null) {
actives.push({
createDate: item.createDate,
memberCount: item.activeQuantity,
title: "当日活跃数量",
});
}
});
let data = [...count, ...newly, ...actives];
this.orderChart.data(data);
this.orderChart.scale({
activeQuantity: {
range: [0, 1],
nice: true,
},
});
this.orderChart.tooltip({
showCrosshairs: true,
shared: true,
});
this.orderChart
.line()
.position("createDate*memberCount")
.color("title")
.label("memberCount")
.shape("smooth");
this.orderChart
.point()
.position("createDate*memberCount")
.color("title")
.label("memberCount")
.shape("circle")
.style({
stroke: "#fff",
lineWidth: 1,
});
this.orderChart.render();
},
clickBreadcrumb(item, index) {
let callback = item;
console.warn(callback);
this.params = {...callback};
},
init() {
API_Member.getMemberStatistics(this.params).then((res) => {
if (res.result) {
res.result.forEach((item) => {
item.activeQuantity += "";
});
this.data = res.result;
if (!this.orderChart) {
this.orderChart = new Chart({
container: "orderChart",
autoFit: true,
height: 500,
padding: [70, 35, 70, 35],
});
}
this.initMemberChart();
}
});
},
},
mounted() {
let data = new Date();
this.year = data;
},
};
</script>
<style scoped lang="scss">
.wrapper {
padding-bottom: 200px;
}
.card {
margin-bottom: 10px;
}
</style>

View File

@@ -0,0 +1,801 @@
<template>
<div class="wrapper">
<Affix :offset-top="100">
<Card class="card fixed-bottom">
<affixTime @selected="clickBreadcrumb" />
</Card>
</Affix>
<Card class="card">
<div>
<h4>交易概况</h4>
<div class="flex">
<div class="transactionList">
<div class="transaction-item" v-for="(item,index) in transactionList" :key="index">
<h4>{{item.label}}</h4>
<div class="transaction-card" v-if="item.label=='转换'">
<div class="card-item">
<div class="card-item-label">访客数UV</div>
<div class="card-item-value">{{overViewList.uvNum || 0}}</div>
</div>
<div class="card-item">
<div class="card-item-label">下单转化率</div>
<div class="card-item-value">{{overViewList.orderConversionRate || '0%'}}</div>
</div>
<div class="card-item">
<div class="card-item-label">付款转化率</div>
<div class="card-item-value">{{overViewList.paymentsConversionRate ||'0%'}}</div>
</div>
<div class="card-item">
<div class="card-item-label">全店转化率</div>
<div class="card-item-value">{{overViewList.overallConversionRate || '0%'}}</div>
</div>
</div>
<div class="transaction-card" v-if="item.label=='订单'">
<div class="card-item">
<div class="card-item-label">下单笔数</div>
<div class="card-item-value">{{overViewList.orderNum || 0}}</div>
</div>
<div class="card-item">
<div class="card-item-label">下单人数</div>
<div class="card-item-value">{{overViewList.orderMemberNum || 0}}</div>
</div>
<div class="card-item">
<div class="card-item-label">下单金额</div>
<div class="card-item-value">{{overViewList.orderAmount| unitPrice('¥') }}</div>
</div>
<div class="card-item">
<div class="card-item-label">付款笔数</div>
<div class="card-item-value">{{overViewList.paymentsNum || 0}}</div>
</div>
<div class="card-item">
<div class="card-item-label">付款金额</div>
<div class="card-item-value">{{overViewList.paymentAmount | unitPrice('¥')}}</div>
</div>
</div>
<div class="transaction-card" v-if="item.label=='退单'">
<div class="card-item">
<div class="card-item-label">退单笔数</div>
<div class="card-item-value">{{overViewList.refundOrderNum || 0}}</div>
</div>
<div class="card-item">
<div class="card-item-label">退单金额</div>
<div class="card-item-value">{{overViewList.refundOrderPrice || 0}}</div>
</div>
</div>
</div>
</div>
<div class="shap">
<div id="overViewChart">
<!-- -->
<div class="block">
<div class="box">
<span>访客数</span>
<span>{{overViewList.uvNum || 0}}</span>
</div>
</div>
<!-- -->
<div class="block">
<div class="box">
<span>下单笔数</span>
<span>{{overViewList.orderNum || 0}}</span>
</div>
</div>
<!-- -->
<div class="block">
<div class="box">
<span>付款笔数</span>
<span>{{overViewList.paymentsNum || 0 }}</span>
</div>
</div>
<!-- 线 -->
<div class="rightBorder">
</div>
<div class="leftTopBorder">
</div>
<div class="leftBottomBorder">
</div>
<!--数据 -->
<div class="leftTopTips">
<div>下单转化率 </div>
<div>{{overViewList.orderConversionRate || '0%' }}</div>
</div>
<div class="leftBottomTips">
<div>付款转化率</div>
<div>{{overViewList.paymentsConversionRate || '0%'}}</div>
</div>
<div class="rightTips">
<div>整体转换率</div>
<div>{{overViewList.overallConversionRate || '0%'}}</div>
</div>
</div>
</div>
</div>
</div>
</Card>
<Card class="card">
<div>
<h4>交易趋势</h4>
<div>
</div>
</div>
<div>
<div id="orderChart"></div>
</div>
</Card>
<Card class="card">
<div>
<h4>订退单统计</h4>
<div class="breadcrumb" style="margin-bottom:20px;">
<span @click="clickTab(item,index)" :class="{'active':item.selected}" v-for="(item,index) in orderType" :key="index"> {{item.title}}</span>
</div>
<div>
<Table stripe :columns="columns" :data="data"></Table>
</div>
<Page @on-change="(index)=>{refundParams.pageNumber = index}" @on-page-size-change="(size)=>{refundParams.pageSize= size}" class="page" show-total show-elevator :total="total" />
</div>
</Card>
</div>
</template>
<script>
import * as API_Goods from "@/api/goods";
import { Chart } from "@antv/g2";
import empty from "@/views/lili-empty";
import orderRow from "./order/orderDetail";
import refundRow from "./order/refundOrder";
import affixTime from "@/views/lili-components/affix-time";
export default {
components: { empty, orderRow, refundRow, affixTime },
data() {
return {
total: "0",
orderType: [
{
title: "订单",
selected: true,
},
{
title: "退单",
selected: false,
},
],
// 订单状态
orderStatusList: {
UNDELIVERED: "待发货",
UNPAID: "未付款",
PAID: "已付款",
DELIVERED: "已发货",
CANCELLED: "已取消",
COMPLETED: "已完成",
TAKE: "已完成",
},
serviceTypeList: {
CANCEL: "取消",
RETURN_GOODS: "退货",
EXCHANGE_GOODS: "换货",
RETURN_MONEY: "退款",
},
serviceStatusList: {
APPLY: "申请售后",
PASS: "通过售后",
REFUSE: "拒绝售后",
BUYER_RETURN: "买家退货待卖家收货",
SELLER_RE_DELIVERY: "商家换货/补发",
SELLER_CONFIRM: "卖家确认收货",
SELLER_TERMINATION: "卖家终止售后",
BUYER_CONFIRM: "买家确认收货",
BUYER_CANCEL: "买家取消售后",
WAIT_REFUND: "等待平台退款",
COMPLETE: "完成售后",
},
//
data: [], //定退单存储值
columns: [], // 定退单title
orderColumns: [
{
type: "expand",
width: 50,
render: (h, params) => {
return h(orderRow, {
props: {
res: params.row,
},
});
},
},
{
title: "商家名称",
key: "storeName",
},
{
title: "用户名",
key: "memberName",
},
{
title: "订单状态",
key: "orderStatus",
render: (h, params) => {
return h("div", this.orderStatusList[params.row.orderStatus]);
},
},
{
title: "创建时间",
key: "createTime",
},
{
title: "支付时间",
key: "paymentTime",
render: (h, params) => {
return h("div", params.row.paymentTime || "暂无");
},
},
{
title: "价格",
key: "flowPrice",
render: (h, params) => {
return h(
"div",
this.$options.filters.unitPrice(params.row.flowPrice, "")
);
},
},
],
refundColumns: [
{
type: "expand",
width: 50,
render: (h, params) => {
return h(refundRow, {
props: {
res: params.row,
},
});
},
},
{
title: "商品图片",
key: "goodsImage",
render: (h, params) => {
return h("img", {
attrs: {
src: params.row.goodsImage,
},
style: {
width: "60px",
verticalAlign: "middle",
},
});
},
},
{
title: "商品名称",
key: "goodsName",
},
{
title: "商家名称",
key: "sellerName",
},
{
title: "售后单类型",
key: "serviceType",
render: (h, params) => {
return h("div", this.serviceTypeList[params.row.serviceType]);
},
},
{
title: "售后单状态",
key: "serviceStatus",
render: (h, params) => {
return h("div", this.serviceStatusList[params.row.serviceStatus]);
},
},
{
title: "退款时间",
key: "refundTime",
render: (h, params) => {
return h("div", params.row.refundTime || "暂无");
},
},
{
title: "申请退款金额",
key: "applyRefundPrice",
render: (h, params) => {
return h(
"div",
"" +
(params.row.applyRefundPrice ? params.row.applyRefundPrice : 0)
);
},
},
{
title: "申请原因",
key: "reason",
},
{
title: "实际金额",
key: "flowPrice",
render: (h, params) => {
return h(
"div",
this.$options.filters.unitPrice(params.row.flowPrice, "")
);
},
},
],
// 交易概况
transactionList: [
{
label: "转换",
value: "",
},
{
label: "订单",
value: "",
},
{
label: "退单",
value: "",
},
],
chartList: [], // 绘制订单图表数据
orderChart: "", //订单图表
overViewList: {}, // 绘制订单统计概览
overViewChart: "", //订单订单统计概览图标
// 时间
dateList: [
{
title: "今天",
selected: false,
value: "TODAY",
},
{
title: "昨天",
selected: false,
value: "YESTERDAY",
},
{
title: "最近7天",
selected: true,
value: "LAST_SEVEN",
},
{
title: "最近30天",
selected: false,
value: "LAST_THIRTY",
},
],
year: "",
// 订单传参
orderParams: {
searchType: "LAST_SEVEN", // TODAY , YESTERDAY , LAST_SEVEN , LAST_THIRTY
year: "",
shopId: "",
memberId: "",
},
// 订单概念
overViewParams: {
month: "",
searchType: "LAST_SEVEN", // TODAY , YESTERDAY , LAST_SEVEN , LAST_THIRTY
storeId: "",
year: "",
},
defaultParams: {
month: "",
searchType: "LAST_SEVEN", // TODAY , YESTERDAY , LAST_SEVEN , LAST_THIRTY
storeId: "",
year: "",
},
refundIndex: 0,
// 退单订单
refundParams: {
pageNumber: 1,
pageSize: 10,
searchType: "LAST_SEVEN",
storeId: "",
year: "",
},
//
//
};
},
watch: {
refundParams: {
handler() {
if (this.refundIndex == 1) {
this.getOrderRefundList();
} else {
this.getOrderList();
}
},
deep: true,
immediate: true,
},
orderParams: {
handler() {
this.initOrderChartList();
},
deep: true,
},
overViewParams: {
handler() {
this.initOrderOverViewList();
},
deep: true,
},
},
methods: {
clickTab(item, index) {
this.refundIndex = index;
this.orderType.forEach((res) => {
res.selected = false;
});
if (item.title == "退单") {
this.getOrderRefundList();
} else {
this.getOrderList();
}
item.selected = true;
},
// 订单图
initOrderChart() {
// 默认已经加载 legend-filter 交互
let data = this.chartList;
data.forEach(item=>{
item.createTime = item.createTime.split(" ")[0]
item.title="交易额"
})
this.orderChart.data(data);
this.orderChart.tooltip({
showCrosshairs: true,
shared: true,
});
this.orderChart
.line()
.position("createTime*price")
.label("price")
.color("title")
.shape("smooth");
this.orderChart
.point()
.position("createTime*price")
.label("price")
.color("title")
.shape("circle")
.style({
stroke: "#fff",
lineWidth: 1,
});
this.orderChart.render();
},
clickBreadcrumb(item, index) {
let callback = JSON.parse(JSON.stringify(item));
this.orderParams = callback;
this.overViewParams = callback;
this.refundParams = callback;
},
// 实例化订单概览
async initOrderOverViewList() {
const res = await API_Goods.getOrderOverView(this.overViewParams);
if (res.success) {
this.overViewList = res.result;
}
},
// 实例化订单图表
async initOrderChartList(name) {
const res = await API_Goods.getOrderChart(this.orderParams);
if (res.success) {
this.chartList = res.result;
if (!this.orderChart) {
this.orderChart = new Chart({
container: "orderChart",
autoFit: true,
height: 500,
padding: [70, 35, 70, 35],
});
}
this.initOrderChart(); //订单表
}
},
// 统计相关订单统计
async getOrderList() {
const res = await API_Goods.statisticsOrderList(this.refundParams);
if (res.success) {
this.data = res.result.records;
this.columns = this.orderColumns;
this.total = res.result.total;
}
},
// 统计相关退单统计
async getOrderRefundList() {
const res = await API_Goods.statisticsOrderRefundList(this.refundParams);
if (res.success) {
this.data = res.result.records;
this.columns = this.refundColumns;
this.total = res.result.total;
}
},
// 实例化初始值
initBaseParams() {
let data = new Date();
this.getOrderList();
this.orderParams.year = data.getFullYear();
this.overViewParams.year = data.getFullYear();
},
},
mounted() {
this.initBaseParams();
},
};
</script>
<style scoped lang="scss">
.active {
color: $theme_color;
position: relative;
&::before {
content: "";
position: absolute;
width: 100%;
height: 3px;
bottom: -5px;
left: 0;
background: $theme_color;
}
}
.breadcrumb{
span{
cursor: pointer;
}
}
.page-col {
text-align: right;
margin: 10px 0;
}
.wrapper {
padding-bottom: 200px;
}
.page {
text-align: right;
margin: 20px 0;
}
#overViewChart {
display: flex;
justify-content: center;
flex-direction: column;
align-items: center;
position: relative;
margin-left: 20px;
> .leftTopTips {
position: absolute;
top: 68px;
left: -2px;
width: 85px;
text-align: center;
background: rgb(255, 255, 255);
z-index: 1;
padding: 5px 0px;
}
> .leftBottomTips {
position: absolute;
bottom: 100px;
left: -2px;
width: 85px;
text-align: center;
background: rgb(255, 255, 255);
z-index: 1;
padding: 5px 0px;
}
> .rightTips {
position: absolute;
bottom: 240px;
right: 0px;
width: 85px;
text-align: center;
background: rgb(255, 255, 255);
z-index: 1;
padding: 5px 0px;
}
> .rightBorder {
width: 110px;
position: absolute;
top: 30px;
right: 40px;
border: 2px solid #d9d9d9;
border-left: 0;
height: 280px;
}
> .leftTopBorder {
border: 2px solid #d9d9d9;
height: 118px;
width: 56px;
position: absolute;
left: 40px;
top: 30px;
border-right: 0;
}
> .leftBottomBorder {
width: 108px;
border: 2px solid #d9d9d9;
height: 150px;
position: absolute;
bottom: 45px;
left: 40px;
border-right: 0;
}
> .block {
height: 0px;
border-left: 30px solid transparent;
border-right: 30px solid transparent;
position: relative;
background: rgb(255, 255, 255);
z-index: 1;
position: relative;
}
> .block:nth-of-type(1) {
width: 240px;
border-top: 90px solid #ff4646;
> .box {
left: -30px;
top: -90px;
width: 240px;
height: 90px;
}
}
> .block:nth-of-type(2) {
width: 172px;
border-top: 100px solid #ff8585;
margin-top: 10px;
> .box {
left: -29px;
top: -100px;
width: 172px;
height: 100px;
}
}
> .block:nth-of-type(3) {
width: 100px;
margin-top: 10px;
border-top: 150px solid #ffb396;
border-left: 50px solid transparent;
border-right: 50px solid transparent;
> .box {
left: -50px;
top: -150px;
width: 100px;
height: 120px;
z-index: 2;
}
}
/deep/ .box {
color: #fff;
position: absolute;
z-index: 2;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
> span {
font-size: 16px;
font-weight: bold;
}
}
}
.transaction-item {
margin: 10px 0;
}
h4 {
margin: 0 0 20px 0;
}
.transactionList {
flex: 7;
padding: 0 20px;
}
.shap {
width: 400px;
margin-left: 20px;
margin-top: 50px;
}
.transaction-card {
height: 120px;
border-radius: 0.4em;
display: flex;
background: #f3f5f7;
}
.card-item-label {
font-weight: bold;
font-size: #666;
font-size: 15px;
margin-bottom: 10px;
}
.card-item-value {
font-size: 15px;
font-weight: bold;
color: $theme_color;
}
.card-item {
height: 100%;
width: 20%;
align-items: center;
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
}
.order-col {
display: flex;
> div {
margin-right: 8px;
padding: 16px;
font-size: 15px;
}
}
.order-list {
display: flex;
}
.tips {
margin: 0 8px;
}
.card {
margin-bottom: 10px;
}
</style>

View File

@@ -0,0 +1,151 @@
<template>
<div class="wrapper">
<div class="shop">
<h3>订单详情</h3>
<div class="shop-item">
<div class="label-item">
<span>订单来源</span>
<span>{{res.clientType}}</span>
</div>
<div class="label-item">
<span>订单状态</span>
<span>{{orderStatusList[res.orderStatus]}}</span>
</div>
<div class="label-item">
<span>付款状态</span>
<span>{{res.payStatus == "UNPAID"
? "未付款"
: res.payStatus == "PAID"
? "已付款"
: ""}}</span>
</div>
<div class="label-item">
<span>支付时间</span>
<span>{{res.paymentTime || '暂无'}}</span>
</div>
<div class="label-item">
<span>支付方式</span>
<span>{{res.paymentMethod == "ONLINE" ? "在线支付" : ""
}}{{ res.paymentMethod == "ALIPAY" ? "支付宝" : res.paymentMethod == "BANK_TRANSFER" ? "银行卡" : "" || '暂无'}}</span>
</div>
</div>
<div class="shop-item">
<div class="label-item">
<span>用户名</span>
<span>{{res.memberName}}</span>
</div>
<div class="label-item">
<span>店铺名称</span>
<span>{{res.storeName}}</span>
</div>
<div class="label-item">
<span>创建时间</span>
<span>{{res.createTime}}</span>
</div>
</div>
<h3>商品详情</h3>
<div class="shop-item">
<div class="goods-item" v-for="(item,index) in res.orderItems" :key="index">
<div class="goods-img">
<img class="img" :src="item.image" alt="">
</div>
<div class="goods-title">
<div>{{item.name}}</div>
<div>{{'x'+item.num}}</div>
<div class="goods-price">{{res.flowPrice | unitPrice('¥')}}</div>
</div>
</div>
</div>
<div class="count-price">
<div class="label-item">
<span>总价格</span>
<span class="flowPrice">{{res.flowPrice | unitPrice('¥')}}</span>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
data() {
return {
orderStatusList: {
UNDELIVERED: "待发货",
UNPAID: "未付款",
PAID: "已付款",
DELIVERED: "已发货",
CANCELLED: "已取消",
COMPLETED: "已完成",
TAKE: "已完成",
},
};
},
props: ["res"],
};
</script>
<style lang="scss" scoped>
.wrapper {
}
.shop {
padding: 10px 0;
background: #fff;
}
.shop-item {
display: flex;
flex-wrap: wrap;
}
h3 {
margin: 20px 16px;
font-size: 18px;
}
.goods-price {
font-size: 18px;
color: red;
}
.goods-item {
display: flex;
width: 100%;
margin: 16px;
}
.count-price {
display: flex;
justify-content: flex-end;
align-items: center;
}
.flowPrice {
font-size: 24px;
color: red;
}
.goods-title {
margin: 0 16px;
display: flex;
flex-direction: column;
justify-content: center;
font-weight: bold;
}
.img {
width: 100px;
height: 100px;
border-radius: 10px;
}
.label-item {
margin: 10px 0;
width: 20%;
padding: 8px;
align-items: center;
font-weight: bold;
display: flex;
> span {
padding: 8px;
}
}
</style>

View File

@@ -0,0 +1,170 @@
<template>
<div class="wrapper">
<div class="shop">
<h3>售后详情</h3>
<div class="shop-item">
<div class="label-item">
<span>售后类型</span>
<span>{{serviceTypeList[res.serviceType]}}</span>
</div>
<div class="label-item">
<span>售后单状态</span>
<span>{{serviceStatusList[res.serviceStatus]}}</span>
</div>
<div class="label-item">
<span>退款时间</span>
<span>{{res.refundTime || '暂无'}}</span>
</div>
<div class="label-item">
<span>申请退款金额</span>
<span>{{res.applyRefundPrice || '0'}}</span>
</div>
<div class="label-item">
<span>商家备注</span>
<span>{{res.auditRemark || '暂无'}}</span>
</div>
<div class="label-item">
<span>申请原因</span>
<span>{{res.reason || '暂无'}}</span>
</div>
</div>
<div class="shop-item">
<div class="label-item">
<span>用户名</span>
<span>{{res.memberName}}</span>
</div>
<div class="label-item">
<span>店铺名称</span>
<span>{{res.sellerName}}</span>
</div>
<div class="label-item">
<span>创建时间</span>
<span>{{res.createTime}}</span>
</div>
</div>
<h3>商品详情</h3>
<div class="shop-item">
<div class="goods-item">
<div class="goods-img">
<img class="img" :src="res.goodsImage" alt="">
</div>
<div class="goods-title">
<div>{{res.goodsName}}</div>
<div>{{'x'+res.num}}</div>
<div class="goods-price">{{res.flowPrice | unitPrice('¥')}}</div>
</div>
</div>
</div>
<div class="count-price">
<div class="label-item">
<span>实际退款金额</span>
<span class="flowPrice">{{res.flowPrice | unitPrice('¥')}}</span>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
data() {
return {
orderStatusList: {
UNDELIVERED: "待发货",
UNPAID: "未付款",
PAID: "已付款",
DELIVERED: "已发货",
CANCELLED: "已取消",
COMPLETED: "已完成",
TAKE: "已完成",
},
// 售后类型
serviceTypeList: {
CANCEL: "取消",
RETURN_GOODS: "退货",
EXCHANGE_GOODS: "换货",
RETURN_MONEY: "退款",
},
serviceStatusList: {
APPLY: "申请售后",
PASS: "通过售后",
REFUSE: "拒绝售后",
BUYER_RETURN: "买家退货,待卖家收货",
SELLER_RE_DELIVERY: "商家换货/补发",
SELLER_CONFIRM: "卖家确认收货",
SELLER_TERMINATION: "卖家终止售后",
BUYER_CONFIRM: "买家确认收货",
BUYER_CANCEL: "买家取消售后",
WAIT_REFUND: "等待平台退款",
COMPLETE: "完成售后",
},
};
},
props: ["res"],
};
</script>
<style lang="scss" scoped>
.wrapper {
}
.shop {
padding: 10px 0;
background: #fff;
}
.shop-item {
display: flex;
flex-wrap: wrap;
}
h3 {
margin: 20px 16px;
font-size: 18px;
}
.goods-price {
font-size: 18px;
color: red;
}
.goods-item {
display: flex;
width: 100%;
margin: 16px;
}
.count-price {
display: flex;
justify-content: flex-end;
align-items: center;
}
.flowPrice {
font-size: 24px;
color: red;
}
.goods-title {
margin: 0 16px;
display: flex;
flex-direction: column;
justify-content: center;
font-weight: bold;
}
.img {
width: 100px;
height: 100px;
border-radius: 10px;
}
.label-item {
margin: 10px 0;
width: 20%;
padding: 8px;
align-items: center;
font-weight: bold;
display: flex;
> span {
padding: 8px;
}
}
</style>

View File

@@ -0,0 +1,248 @@
<template>
<div class="wrapper">
<Affix :offset-top="100">
<Card class="card fixed-bottom">
<affixTime @selected="clickBreadcrumb" />
</Card>
</Affix>
<Card class="card">
<div>
<h4>流量概况</h4>
</div>
<div class="box">
<div class="box-item">
<div>
访客数UV
</div>
<div>
{{uvs||0}}
</div>
</div>
<div class="box-item">
<div>
浏览量PV
</div>
<div>
{{pvs||0}}
</div>
</div>
</div>
</Card>
<Card class="card">
<div>
<h4>流量趋势</h4>
<div id="orderChart"></div>
</div>
</Card>
<Card class="card">
<div>
<h4>客户增长报表</h4>
<Table class="table" stripe :columns="columns" :data="data"></Table>
</div>
</Card>
</div>
</div>
</template>
<script>
import affixTime from "@/views/lili-components/affix-time";
import * as API_Member from "@/api/member";
import { Chart } from "@antv/g2";
export default {
components: { affixTime },
data() {
return {
// 时间
uvs: 0,
pvs: 0,
dateList: [
{
title: "今天",
selected: false,
value: "TODAY",
},
{
title: "昨天",
selected: false,
value: "YESTERDAY",
},
{
title: "最近7天",
selected: true,
value: "LAST_SEVEN",
},
{
title: "最近30天",
selected: false,
value: "LAST_THIRTY",
},
],
orderChart: "",
params: {
searchType: "LAST_SEVEN",
year: "",
month: "",
// storeId: "",
},
columns: [
{
key: "date",
title: "日期",
},
{
key: "pvNum",
title: "浏览量",
},
{
key: "uvNum",
title: "访客数",
},
],
data: [],
};
},
watch: {
params: {
handler(val) {
this.init();
},
deep: true,
},
},
methods: {
// 订单图
initChart() {
// 默认已经加载 legend-filter 交互
/**
* 将数据分成三组来进行展示
*/
let uv = [];
let pv = [];
this.data.forEach((item) => {
uv.push({
date: item.date,
uvNum: item.uvNum,
title: "访客数UV",
pv: item.uvNum,
});
pv.push({
date: item.date,
pvNum: item.pvNum,
pv: item.pvNum,
title: "浏览量PV",
});
});
let data = [...uv, ...pv];
this.orderChart.data(data);
this.orderChart.scale({
activeQuantity: {
range: [0, 1],
nice: true,
},
});
this.orderChart.tooltip({
showCrosshairs: true,
shared: true,
});
this.orderChart
.line()
.position("date*pv")
.color("title")
.label("pv")
.shape("smooth");
this.orderChart
.point()
.position("date*pv")
.color("title")
.label("pv")
.shape("circle")
.style({
stroke: "#fff",
lineWidth: 1,
});
this.orderChart.render();
},
clickBreadcrumb(item, index) {
let callback = JSON.parse(JSON.stringify(item));
this.params = callback;
},
init() {
API_Member.getStatisticsList(this.params).then((res) => {
if (res.result) {
this.data = res.result;
res.result.forEach((item) => {
this.uvs += item.uvNum;
this.pvs += item.pvNum;
});
if (!this.orderChart) {
this.orderChart = new Chart({
container: "orderChart",
autoFit: true,
height: 500,
padding: [70, 35, 70, 35],
});
}
this.initChart();
}
});
},
},
mounted() {
this.init();
},
};
</script>
<style scoped lang="scss">
.table {
margin-top: 10px;
}
.wrapper {
padding-bottom: 200px;
}
.box-item {
display: flex;
flex-direction: column;
width: 25%;
font-weight: bold;
// align-items: center;
justify-content: center;
> div {
margin: 4px;
}
}
.box {
background: rgb(250, 250, 250);
padding: 10px;
margin-top: 10px;
display: flex;
}
.card {
margin-bottom: 10px;
}
</style>