1.图标新增利率,成本
@@ -35,6 +35,22 @@ const Api = {
|
|||||||
params
|
params
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
// 毛利率/净利率 柱状图 左下下
|
||||||
|
profitRateBarChart(params: any) {
|
||||||
|
return request<any>({
|
||||||
|
url: `${baseURL}/profitRateBarChart`,
|
||||||
|
method: "get",
|
||||||
|
params
|
||||||
|
});
|
||||||
|
},
|
||||||
|
// 成本折线图 右下下
|
||||||
|
costLineChart(params: any) {
|
||||||
|
return request<any>({
|
||||||
|
url: `${baseURL}/costLineChart`,
|
||||||
|
method: "get",
|
||||||
|
params
|
||||||
|
});
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export default Api;
|
export default Api;
|
||||||
|
|||||||
BIN
src/assets/marketing/1.png
Normal file
|
After Width: | Height: | Size: 5.0 KiB |
BIN
src/assets/marketing/2.png
Normal file
|
After Width: | Height: | Size: 3.8 KiB |
BIN
src/assets/marketing/3.png
Normal file
|
After Width: | Height: | Size: 3.7 KiB |
BIN
src/assets/marketing/4.png
Normal file
|
After Width: | Height: | Size: 3.9 KiB |
BIN
src/assets/marketing/5.png
Normal file
|
After Width: | Height: | Size: 3.8 KiB |
BIN
src/assets/marketing/6.png
Normal file
|
After Width: | Height: | Size: 3.4 KiB |
BIN
src/assets/marketing/7.png
Normal file
|
After Width: | Height: | Size: 3.1 KiB |
@@ -401,7 +401,7 @@
|
|||||||
style="height: 350px" />
|
style="height: 350px" />
|
||||||
</div>
|
</div>
|
||||||
<!-- 商品销售排行 -->
|
<!-- 商品销售排行 -->
|
||||||
<div class="item" style="margin-left: 20px">
|
<div class="item">
|
||||||
<div class="header">
|
<div class="header">
|
||||||
<div class="tab_wrap">
|
<div class="tab_wrap">
|
||||||
<div class="item active">商品销售排行</div>
|
<div class="item active">商品销售排行</div>
|
||||||
@@ -442,6 +442,28 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="chart_wrap">
|
||||||
|
<!-- 毛利率/净利率 -->
|
||||||
|
<div class="item">
|
||||||
|
<div class="header">
|
||||||
|
<div class="rate_title">
|
||||||
|
<span class="t1">毛利率/净利率</span>
|
||||||
|
<span class="t2">今天 {{ initInterestRateTime }} 更新</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div ref="initInterestRate" v-loading="initInterestRateLoading" class="chart" style="height: 350px" />
|
||||||
|
</div>
|
||||||
|
<!-- 成本(元) -->
|
||||||
|
<div class="item">
|
||||||
|
<div class="header">
|
||||||
|
<div class="rate_title">
|
||||||
|
<span class="t1">成本(元)</span>
|
||||||
|
<span class="t2">今天 {{ costUpdateTime }} 更新</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div ref="costRef" v-loading="costLoading" class="chart" style="height: 350px" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<!-- <div class="chart_wrap" style="display: flex;">
|
<!-- <div class="chart_wrap" style="display: flex;">
|
||||||
<div class="item" style="margin-left: 20px;">
|
<div class="item" style="margin-left: 20px;">
|
||||||
<div class="header">
|
<div class="header">
|
||||||
@@ -588,6 +610,12 @@ export default {
|
|||||||
isHeadShop: JSON.parse(localStorage.getItem("userInfo")).isHeadShop,
|
isHeadShop: JSON.parse(localStorage.getItem("userInfo")).isHeadShop,
|
||||||
loginType: localStorage.getItem("loginType"),
|
loginType: localStorage.getItem("loginType"),
|
||||||
shopInfo: JSON.parse(localStorage.getItem("userInfo")),
|
shopInfo: JSON.parse(localStorage.getItem("userInfo")),
|
||||||
|
initInterestRateLoading: true,
|
||||||
|
initInterestRate: null,
|
||||||
|
initInterestRateTime: '',
|
||||||
|
costLoading: true,
|
||||||
|
costRef: null,
|
||||||
|
costUpdateTime: ''
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
@@ -620,6 +648,8 @@ export default {
|
|||||||
this.dateProduct();
|
this.dateProduct();
|
||||||
// this.summaryDateGet();
|
// this.summaryDateGet();
|
||||||
this.timeChange(this.timeValue);
|
this.timeChange(this.timeValue);
|
||||||
|
this.profitRateBarChart()
|
||||||
|
this.costLineChart()
|
||||||
|
|
||||||
this.__resizeHandler = debounce(() => {
|
this.__resizeHandler = debounce(() => {
|
||||||
if (this.saleChart) {
|
if (this.saleChart) {
|
||||||
@@ -637,6 +667,12 @@ export default {
|
|||||||
if (this.productCountChart) {
|
if (this.productCountChart) {
|
||||||
this.productCountChart.resize();
|
this.productCountChart.resize();
|
||||||
}
|
}
|
||||||
|
if (this.initInterestRate) {
|
||||||
|
this.initInterestRate.resize();
|
||||||
|
}
|
||||||
|
if (this.costRef) {
|
||||||
|
this.costRef.resize();
|
||||||
|
}
|
||||||
// if (this.productSumChart) {
|
// if (this.productSumChart) {
|
||||||
// this.productSumChart.resize();
|
// this.productSumChart.resize();
|
||||||
// }
|
// }
|
||||||
@@ -879,6 +915,67 @@ export default {
|
|||||||
],
|
],
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
// 初始化成本折线图
|
||||||
|
initCostChart(time = [], data = []) {
|
||||||
|
this.costRef = echarts.init(this.$refs.costRef);
|
||||||
|
this.costRef.setOption({
|
||||||
|
tooltip: {
|
||||||
|
trigger: "item",
|
||||||
|
formatter: (params) => {
|
||||||
|
return `${params.value}`;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
xAxis: [
|
||||||
|
{
|
||||||
|
type: "category",
|
||||||
|
data: time,
|
||||||
|
axisTick: {
|
||||||
|
alignWithLabel: true,
|
||||||
|
},
|
||||||
|
axisLine: {
|
||||||
|
lineStyle: {
|
||||||
|
color: "#999",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
axisLabel: {
|
||||||
|
rotate: time.length <= 7 ? 0 : 45,
|
||||||
|
interval: 0,
|
||||||
|
fontSize: "9",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
grid: {
|
||||||
|
top: '5%',
|
||||||
|
right: '5%',
|
||||||
|
bottom: '8%',
|
||||||
|
left: '8%',
|
||||||
|
},
|
||||||
|
color: "#165DFF",
|
||||||
|
yAxis: [
|
||||||
|
{
|
||||||
|
type: "value",
|
||||||
|
axisLine: {
|
||||||
|
lineStyle: {
|
||||||
|
color: "#999",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
splitLine: {
|
||||||
|
lineStyle: {
|
||||||
|
type: "dashed",
|
||||||
|
color: "#ececec",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
series: [
|
||||||
|
{
|
||||||
|
data: data,
|
||||||
|
type: "line",
|
||||||
|
symbol: "none",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
},
|
||||||
// 初始化销售额图标
|
// 初始化销售额图标
|
||||||
initSaleChart(time, data) {
|
initSaleChart(time, data) {
|
||||||
this.saleChart = null;
|
this.saleChart = null;
|
||||||
@@ -952,6 +1049,83 @@ export default {
|
|||||||
],
|
],
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
// 初始化毛利率/净利率图表
|
||||||
|
initInterestRateChart(time, data) {
|
||||||
|
this.initInterestRate = null;
|
||||||
|
this.initInterestRate = echarts.init(this.$refs.initInterestRate);
|
||||||
|
this.initInterestRate.setOption({
|
||||||
|
tooltip: {
|
||||||
|
trigger: "item",
|
||||||
|
formatter: (params) => {
|
||||||
|
return `${params.value}`;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
xAxis: [
|
||||||
|
{
|
||||||
|
type: "category",
|
||||||
|
data: time,
|
||||||
|
axisTick: {
|
||||||
|
alignWithLabel: true,
|
||||||
|
},
|
||||||
|
axisLine: {
|
||||||
|
lineStyle: {
|
||||||
|
color: "#999",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
axisLabel: {
|
||||||
|
rotate: time.length <= 7 ? 0 : 45,
|
||||||
|
interval: 0,
|
||||||
|
fontSize: "9",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
color: ["#165DFF", "#14C9C9", "#F98B26"],
|
||||||
|
yAxis: [
|
||||||
|
{
|
||||||
|
type: "value",
|
||||||
|
axisLine: {
|
||||||
|
lineStyle: {
|
||||||
|
color: "#999",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
splitLine: {
|
||||||
|
lineStyle: {
|
||||||
|
type: "dashed",
|
||||||
|
color: "#ececec",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
grid: {
|
||||||
|
top: '5%',
|
||||||
|
right: '5%',
|
||||||
|
bottom: '8%',
|
||||||
|
left: '8%',
|
||||||
|
},
|
||||||
|
series: [
|
||||||
|
{
|
||||||
|
name: "毛利率",
|
||||||
|
type: "bar",
|
||||||
|
barGap: '0%',
|
||||||
|
barWidth: time.length <= 7 ? "50%" : "30%",
|
||||||
|
data: data.map((item) => item.profitRate),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '净利率',
|
||||||
|
type: "bar",
|
||||||
|
barGap: '0%',
|
||||||
|
barWidth: time.length <= 7 ? "50%" : "30%",
|
||||||
|
data: data.map(item => item.netProfitRate),
|
||||||
|
},
|
||||||
|
// {
|
||||||
|
// name: '优惠金额',
|
||||||
|
// type: "bar",
|
||||||
|
// barWidth: time.length <= 7 ? "30%" : "20%",
|
||||||
|
// data: data.map(item => item.discountAmount),
|
||||||
|
// }
|
||||||
|
],
|
||||||
|
});
|
||||||
|
},
|
||||||
// 初始化销售额图表
|
// 初始化销售额图表
|
||||||
initPayChart(data) {
|
initPayChart(data) {
|
||||||
this.payChart = echarts.init(this.$refs.payChart);
|
this.payChart = echarts.init(this.$refs.payChart);
|
||||||
@@ -1021,6 +1195,48 @@ export default {
|
|||||||
this.saleLoading = false;
|
this.saleLoading = false;
|
||||||
}, 300);
|
}, 300);
|
||||||
},
|
},
|
||||||
|
// 获取毛利率/净利率柱状图数据
|
||||||
|
async profitRateBarChart() {
|
||||||
|
try {
|
||||||
|
this.initInterestRateLoading = true;
|
||||||
|
const res = await dataSummaryApi.profitRateBarChart({ day: this.saleActive, shopId: this.shopId });
|
||||||
|
|
||||||
|
this.initInterestRateTime = dayjs().format('HH:mm')
|
||||||
|
|
||||||
|
const data = res.map((item) => {
|
||||||
|
return {
|
||||||
|
profitRate: item.profitRate || 0,
|
||||||
|
netProfitRate: item.netProfitRate || 0,
|
||||||
|
// discountAmount: item.discountAmount
|
||||||
|
};
|
||||||
|
});
|
||||||
|
const time = res.map((item) => item.tradeDay);
|
||||||
|
this.initInterestRateChart(time, data);
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error);
|
||||||
|
}
|
||||||
|
setTimeout(() => {
|
||||||
|
this.initInterestRateLoading = false;
|
||||||
|
}, 300);
|
||||||
|
},
|
||||||
|
// 获取成本折线图数据
|
||||||
|
async costLineChart() {
|
||||||
|
try {
|
||||||
|
this.costLoading = true;
|
||||||
|
const res = await dataSummaryApi.costLineChart({ day: this.saleActive, shopId: this.shopId });
|
||||||
|
|
||||||
|
this.costUpdateTime = dayjs().format('HH:mm')
|
||||||
|
|
||||||
|
const data = res.map((item) => item.productCostAmount || 0);
|
||||||
|
const time = res.map((item) => item.tradeDay);
|
||||||
|
this.initCostChart(time, data);
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error);
|
||||||
|
}
|
||||||
|
setTimeout(() => {
|
||||||
|
this.costLoading = false;
|
||||||
|
}, 300);
|
||||||
|
},
|
||||||
paginationChange(e) {
|
paginationChange(e) {
|
||||||
this.saleTablePage = e;
|
this.saleTablePage = e;
|
||||||
this.dateProduct();
|
this.dateProduct();
|
||||||
@@ -1601,6 +1817,8 @@ export default {
|
|||||||
|
|
||||||
.chart_wrap {
|
.chart_wrap {
|
||||||
margin-top: 20px;
|
margin-top: 20px;
|
||||||
|
display: flex;
|
||||||
|
gap: 20px;
|
||||||
|
|
||||||
.sale_data {
|
.sale_data {
|
||||||
display: flex;
|
display: flex;
|
||||||
@@ -1647,6 +1865,24 @@ export default {
|
|||||||
border-bottom: 1px solid #ececec;
|
border-bottom: 1px solid #ececec;
|
||||||
padding: 0 20px;
|
padding: 0 20px;
|
||||||
|
|
||||||
|
.rate_title {
|
||||||
|
flex: 1;
|
||||||
|
padding: 20px 0;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
|
||||||
|
.t1 {
|
||||||
|
font-size: 16px;
|
||||||
|
color: #111;
|
||||||
|
}
|
||||||
|
|
||||||
|
.t2 {
|
||||||
|
font-size: 12px;
|
||||||
|
color: #999;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.tab_wrap {
|
.tab_wrap {
|
||||||
display: flex;
|
display: flex;
|
||||||
$color: #1890ff;
|
$color: #1890ff;
|
||||||
|
|||||||
@@ -163,20 +163,20 @@
|
|||||||
<el-table-column label="商品描述" prop="productSkuName"></el-table-column>
|
<el-table-column label="商品描述" prop="productSkuName"></el-table-column>
|
||||||
<el-table-column label="单价" prop="price"></el-table-column> -->
|
<el-table-column label="单价" prop="price"></el-table-column> -->
|
||||||
<el-table-column label="商品名称" prop="productName"></el-table-column>
|
<el-table-column label="商品名称" prop="productName"></el-table-column>
|
||||||
<el-table-column label="销量" prop="saleCount"></el-table-column>
|
<el-table-column label="销量" prop="saleCount" sortable></el-table-column>
|
||||||
<el-table-column label="销售金额" prop="saleAmount">
|
<el-table-column label="销售金额" prop="saleAmount" sortable>
|
||||||
<template v-slot="scope">¥{{ scope.row.saleAmount }}</template>
|
<template v-slot="scope">¥{{ scope.row.saleAmount }}</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="退单量" prop="refundCount"></el-table-column>
|
<el-table-column label="退单量" prop="refundCount" sortable></el-table-column>
|
||||||
<el-table-column label="退款金额" prop="refundAmount">
|
<el-table-column label="退款金额" prop="refundAmount" sortable>
|
||||||
<template v-slot="scope">¥{{ scope.row.refundAmount }}</template>
|
<template v-slot="scope">¥{{ scope.row.refundAmount }}</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="实际销量" prop="refundCount">
|
<!-- <el-table-column label="实际销量" prop="refundCount">
|
||||||
<template v-slot="scope"> {{ scope.row.saleCount - scope.row.refundCount }} </template>
|
<template v-slot="scope"> {{ scope.row.saleCount - scope.row.refundCount }} </template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="实际销售额" prop="refundCount">
|
<el-table-column label="实际销售额" prop="refundCount">
|
||||||
<template v-slot="scope"> ¥{{ scope.row.saleAmount - scope.row.refundAmount }} </template>
|
<template v-slot="scope"> ¥{{ scope.row.saleAmount - scope.row.refundAmount }} </template>
|
||||||
</el-table-column>
|
</el-table-column> -->
|
||||||
</el-table>
|
</el-table>
|
||||||
</div>
|
</div>
|
||||||
<div class="head-container">
|
<div class="head-container">
|
||||||
|
|||||||
@@ -63,14 +63,14 @@
|
|||||||
<!-- <el-table-column label="门店id" prop="shopId"></el-table-column> -->
|
<!-- <el-table-column label="门店id" prop="shopId"></el-table-column> -->
|
||||||
<!-- <el-table-column label="台桌Id" prop="tableId"></el-table-column> -->
|
<!-- <el-table-column label="台桌Id" prop="tableId"></el-table-column> -->
|
||||||
<el-table-column label="台桌号" prop="tableName"></el-table-column>
|
<el-table-column label="台桌号" prop="tableName"></el-table-column>
|
||||||
<el-table-column label="订单数量" prop="orderCount">
|
<el-table-column label="订单数量" prop="orderCount" sortable>
|
||||||
<template v-slot="scope">
|
<template v-slot="scope">
|
||||||
<div class="cursor-pointer" @click="toTableOrderList(scope.row)">
|
<div class="cursor-pointer" @click="toTableOrderList(scope.row)">
|
||||||
{{ scope.row.orderCount }}
|
{{ scope.row.orderCount }}
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="订单金额" prop="orderAmount"></el-table-column>
|
<el-table-column label="订单金额" prop="orderAmount" sortable></el-table-column>
|
||||||
</el-table>
|
</el-table>
|
||||||
<!-- <el-table :data="tableData.data" v-loading="tableData.loading" v-if="orderType == 2">
|
<!-- <el-table :data="tableData.data" v-loading="tableData.loading" v-if="orderType == 2">
|
||||||
<el-table-column label="商品名称" prop="productName"></el-table-column>
|
<el-table-column label="商品名称" prop="productName"></el-table-column>
|
||||||
|
|||||||
@@ -1,17 +1,38 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="app-container">
|
<div class="app-container">
|
||||||
<div class="card">
|
<div class="card">
|
||||||
<div class="row" v-for="(item, index) in menus" :key="index">
|
<div class="row">
|
||||||
<div class="title">
|
<div class="title">
|
||||||
{{ item.label }}
|
营销中心
|
||||||
</div>
|
</div>
|
||||||
<div class="menus_wrap">
|
<div class="menus_wrap">
|
||||||
<div class="item" v-for="(val, i) in item.list" :key="i" @click="to(val)">
|
<div class="item" v-for="(item, index) in newMenus" :key="index" @click="showChildrenHandle(index)">
|
||||||
<img :src="getIconPath(val.icon)" class="icon" @error="handleImageError(val)" />
|
<el-image :src="getIconPathNew(`${index + 1}`)" :style="iconSize"></el-image>
|
||||||
<div class="info">
|
<div class="info">
|
||||||
<div class="name">{{ val.name }}</div>
|
<div class="name">{{ item.name }}</div>
|
||||||
<div class="intro">
|
<div class="intro">{{ item.intro }}</div>
|
||||||
{{ val.intro }}
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="children_wrap" :class="{ active: childrenShow }">
|
||||||
|
<div class="close" @click="childrenShow = false">
|
||||||
|
<el-icon size="24" color="#333">
|
||||||
|
<CircleClose />
|
||||||
|
</el-icon>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="title">
|
||||||
|
{{ newMenus[menusActive].name }}
|
||||||
|
</div>
|
||||||
|
<div class="menus_wrap">
|
||||||
|
<div class="item" v-for="(val, index) in newMenus[menusActive].childrenList" :key="index" @click="to(val)">
|
||||||
|
<img :src="getIconPath(val.icon)" class="icon" @error="handleImageError(val)" />
|
||||||
|
<div class="info">
|
||||||
|
<div class="name">{{ val.name }}</div>
|
||||||
|
<div class="intro">
|
||||||
|
{{ val.intro }}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -22,9 +43,243 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
|
import { ref } from 'vue'
|
||||||
import defaultIcon from "@/assets/logo.png";
|
import defaultIcon from "@/assets/logo.png";
|
||||||
import { ElMessage } from "element-plus";
|
import { ElMessage } from "element-plus";
|
||||||
|
|
||||||
|
const iconSize = ref({
|
||||||
|
width: '55px',
|
||||||
|
height: '55px'
|
||||||
|
})
|
||||||
|
|
||||||
|
function showChildrenHandle(index) {
|
||||||
|
menusActive.value = index
|
||||||
|
childrenShow.value = true
|
||||||
|
}
|
||||||
|
|
||||||
|
const childrenShow = ref(false)
|
||||||
|
const menusActive = ref(0)
|
||||||
|
const newMenus = ref([
|
||||||
|
{
|
||||||
|
name: '顾客中心',
|
||||||
|
intro: '以顾客为核心统一管理',
|
||||||
|
childrenList: [
|
||||||
|
{
|
||||||
|
name: "超级会员",
|
||||||
|
icon: "cjhy",
|
||||||
|
pathName: "superVip",
|
||||||
|
intro: "用户会员管理设置"
|
||||||
|
},
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '拉新拓客',
|
||||||
|
intro: '协助商家拉来新客户,拓展客户群体',
|
||||||
|
childrenList: [
|
||||||
|
{
|
||||||
|
name: "分销",
|
||||||
|
icon: "zhcz",
|
||||||
|
pathName: "distribution_page",
|
||||||
|
intro: "用户成为业务员,可促进消费"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "套餐推广",
|
||||||
|
icon: "tctg",
|
||||||
|
pathName: "",
|
||||||
|
intro: "下单通过用户邀请好友减免金额的方式裂变宣传套餐加购",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "新客立减",
|
||||||
|
icon: "xklj",
|
||||||
|
pathName: "newUserDiscount",
|
||||||
|
intro: "首单下单减免金额"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "商品拼团",
|
||||||
|
icon: "sppt",
|
||||||
|
pathName: "",
|
||||||
|
intro: "拼团"
|
||||||
|
},
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '拉高客单价',
|
||||||
|
intro: '提高每一位顾客单次购买的金额',
|
||||||
|
childrenList: [
|
||||||
|
{
|
||||||
|
name: "满减活动",
|
||||||
|
icon: "mjhd", pathName: "discount_activity",
|
||||||
|
intro: "达到指定支付金额享受减价"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "点餐智能推荐",
|
||||||
|
icon: "dczntj",
|
||||||
|
pathName: "order_recommendation",
|
||||||
|
intro: "进入点单页X秒未点自动推荐商品,此推荐设置启用即生效",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "限时折扣",
|
||||||
|
icon: "xszk",
|
||||||
|
pathName: "discount_limit",
|
||||||
|
intro: "批量设置商品折扣"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "弹窗广告",
|
||||||
|
icon: "tcgg",
|
||||||
|
pathName: "",
|
||||||
|
intro: "设置弹窗广告"
|
||||||
|
},
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '提升复购率',
|
||||||
|
intro: '提升客户再次购买的概率和频次',
|
||||||
|
childrenList: [
|
||||||
|
{
|
||||||
|
name: "积分锁客",
|
||||||
|
icon: "jfsk",
|
||||||
|
pathName: "points",
|
||||||
|
intro: "设置充值消费的N倍,当前订单立即免单",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "消费返现",
|
||||||
|
icon: "xffx",
|
||||||
|
pathName: "cashback",
|
||||||
|
intro: "用户下单后返现一定的金额到余额,可促进复购",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "消费赠券",
|
||||||
|
icon: "xfzq",
|
||||||
|
pathName: "consume_ticket",
|
||||||
|
intro: "达到指定消费金额赠送优惠券",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "私域引流",
|
||||||
|
icon: "syyl",
|
||||||
|
pathName: "drainage",
|
||||||
|
intro: "可设置用户下单成功后的群二维码",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "生日有礼",
|
||||||
|
icon: "sryl",
|
||||||
|
pathName: "birthdayGift",
|
||||||
|
intro: "用户生日管理设置"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "推送活动消息",
|
||||||
|
icon: "tshdxx",
|
||||||
|
pathName: "",
|
||||||
|
intro: "给用户推送服务通知"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '增加现金流',
|
||||||
|
intro: '增加商家特定时期内实际可支配的现金流入',
|
||||||
|
childrenList: [
|
||||||
|
{
|
||||||
|
name: "霸王餐",
|
||||||
|
icon: "bwc",
|
||||||
|
pathName: "king_dine",
|
||||||
|
intro: "设置充值消费的N倍,当前订单立即免单",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "智慧充值",
|
||||||
|
icon: "zhcz",
|
||||||
|
pathName: "wisdom_recharge",
|
||||||
|
intro: "允许客户充值并使用余额支付",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "充值兑换码",
|
||||||
|
icon: "czdhm",
|
||||||
|
pathName: "recharge_exchange",
|
||||||
|
intro: "兑换码直充余额,可当作礼品赠送",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "券兑换码",
|
||||||
|
icon: "qdhm",
|
||||||
|
pathName: "coupon_exchange_code",
|
||||||
|
intro: "可添加多券组合兑换"
|
||||||
|
},
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '优惠券体系',
|
||||||
|
intro: '完整且系统化的优惠体系',
|
||||||
|
childrenList: [
|
||||||
|
{
|
||||||
|
name: "折扣券",
|
||||||
|
icon: "zkq",
|
||||||
|
pathName: "rebate_coupon",
|
||||||
|
intro: "下单享折扣但折扣的金额将在券中抵扣。",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "满减券",
|
||||||
|
icon: "mjq",
|
||||||
|
pathName: "discount_coupon",
|
||||||
|
intro:
|
||||||
|
"用户满足指定金额后,可使用优惠券立减相应金额,如:设置满100-50券,符合要求的订单满100元后,立减50元。",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "商品兑换券",
|
||||||
|
icon: "spdhq",
|
||||||
|
pathName: "product_redemption",
|
||||||
|
intro: "设置可兑换成商品的券",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "买一送一券",
|
||||||
|
icon: "myzy",
|
||||||
|
pathName: "buy_one",
|
||||||
|
intro: "针对营销活动买一送一设置券品",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "第二件半价券",
|
||||||
|
icon: "dejbjq",
|
||||||
|
pathName: "half_price",
|
||||||
|
intro: "设置第二件半价券",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "免配送费券",
|
||||||
|
icon: "mfpsq",
|
||||||
|
pathName: "",
|
||||||
|
intro: "可设置一张免除订单配送费的券",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "固定价格券",
|
||||||
|
icon: "gdjkq",
|
||||||
|
pathName: "",
|
||||||
|
intro:
|
||||||
|
"设置该券后,允许用户以固定价格兑换指定商品,如:设置一个固定价格9.9的券,商品20元,用户使用券后只需要9.9元兑换该商品。",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "超值券包",
|
||||||
|
icon: "czqb",
|
||||||
|
pathName: "",
|
||||||
|
intro: "下单加购"
|
||||||
|
},
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '消息推送功能',
|
||||||
|
intro: '推送商家/平台优惠活动消息的方式',
|
||||||
|
childrenList: [
|
||||||
|
{
|
||||||
|
name: "短信推送",
|
||||||
|
icon: "dxts",
|
||||||
|
pathName: "note_push",
|
||||||
|
intro: "给用户推送服务通知"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "微信公众号",
|
||||||
|
icon: "wxgzh",
|
||||||
|
pathName: "official_accounts",
|
||||||
|
intro:
|
||||||
|
"授权微信公众号后,让你能够在后台查看和维护公众号的粉丝;同时你的店铺也有出现关注公众号的入口。",
|
||||||
|
},
|
||||||
|
]
|
||||||
|
}
|
||||||
|
])
|
||||||
|
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const to = (item) => {
|
const to = (item) => {
|
||||||
if (!item.pathName) {
|
if (!item.pathName) {
|
||||||
@@ -188,6 +443,17 @@ const getIconPath = (iconName) => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 动态获取PNG图标路径
|
||||||
|
const getIconPathNew = (iconName) => {
|
||||||
|
try {
|
||||||
|
// 直接导入对应PNG文件
|
||||||
|
return new URL(`/src/assets/marketing/${iconName}.png`, import.meta.url).href;
|
||||||
|
} catch (error) {
|
||||||
|
console.warn(`图标 ${iconName}.png 不存在`);
|
||||||
|
return defaultIcon; // 图标不存在时使用默认图标
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// 处理图片加载失败
|
// 处理图片加载失败
|
||||||
const handleImageError = (item) => {
|
const handleImageError = (item) => {
|
||||||
console.error(`图标 ${item.icon}.png 加载失败`);
|
console.error(`图标 ${item.icon}.png 加载失败`);
|
||||||
@@ -199,11 +465,52 @@ const handleImageError = (item) => {
|
|||||||
padding: 14px;
|
padding: 14px;
|
||||||
|
|
||||||
.card {
|
.card {
|
||||||
|
height: 81vh;
|
||||||
|
overflow-y: auto;
|
||||||
padding: 14px;
|
padding: 14px;
|
||||||
background-color: #fff;
|
background-color: #fff;
|
||||||
|
border-radius: 10px;
|
||||||
|
position: relative;
|
||||||
|
overflow: hidden;
|
||||||
|
|
||||||
|
.children_wrap {
|
||||||
|
width: 100%;
|
||||||
|
height: 81vh;
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
z-index: 99;
|
||||||
|
background-color: rgba(255, 255, 255, 0.8);
|
||||||
|
backdrop-filter: blur(20px);
|
||||||
|
padding: 14px;
|
||||||
|
border-radius: 10px;
|
||||||
|
transition: all .3s ease-in-out;
|
||||||
|
transform: translateY(200%);
|
||||||
|
|
||||||
|
&.active {
|
||||||
|
transform: translateY(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
.close {
|
||||||
|
width: 30px;
|
||||||
|
height: 30px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
position: absolute;
|
||||||
|
top: 10px;
|
||||||
|
right: 10px;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.row {
|
.row {
|
||||||
padding-bottom: 14px;
|
&:not(:first-child) {
|
||||||
|
padding-bottom: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
.title {
|
.title {
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
@@ -235,6 +542,8 @@ const handleImageError = (item) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.info {
|
.info {
|
||||||
|
padding-left: 10px;
|
||||||
|
|
||||||
.name {
|
.name {
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1 +1,294 @@
|
|||||||
<template></template>
|
<template>
|
||||||
|
<div class="app-container">
|
||||||
|
<div class="head-container">
|
||||||
|
<el-form :model="query" inline>
|
||||||
|
<el-form-item>
|
||||||
|
<el-input v-model="query.orderNo" placeholder="订单号"></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item>
|
||||||
|
<el-select v-model="query.payType" placeholder="支付类型">
|
||||||
|
<el-option label="微信支付" value="wechatPay" />
|
||||||
|
<el-option label="支付宝支付" value="aliPay" />
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item>
|
||||||
|
<el-input v-model="query.phone" placeholder="联系电话"></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item>
|
||||||
|
<el-input v-model="query.proName" placeholder="商品名称"></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item>
|
||||||
|
<el-select v-model="query.status" placeholder="状态">
|
||||||
|
<el-option label="待付款" value="unpaid" />
|
||||||
|
<el-option label="待使用" value="unused" />
|
||||||
|
<el-option label="已完成" value="closed" />
|
||||||
|
<el-option label="退款中" value="refunding" />
|
||||||
|
<el-option label="已退款" value="refund" />
|
||||||
|
<el-option label="已取消" value="cancelled" />
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item>
|
||||||
|
<el-date-picker v-model="query.createdAt" type="daterange" range-separator="至" start-placeholder="开始日期"
|
||||||
|
end-placeholder="结束日期" :default-time="['00:00:00', '23:59:59']" value-format="yyyy-MM-dd HH:mm:ss">
|
||||||
|
</el-date-picker>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item>
|
||||||
|
<el-button type="primary" @click="getTableData">查询</el-button>
|
||||||
|
<el-button @click="resetHandle">重置</el-button>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
</div>
|
||||||
|
<div class="head-container">
|
||||||
|
<el-table :data="tableData.data" v-loading="tableData.loading">
|
||||||
|
<el-table-column label="订单号" prop="orderNo"></el-table-column>
|
||||||
|
<el-table-column label="团购卷名称" prop="proName"></el-table-column>
|
||||||
|
<el-table-column label="到期日期" prop="expDate"></el-table-column>
|
||||||
|
<el-table-column label="创建时间" prop="createTime"></el-table-column>
|
||||||
|
<el-table-column label="下单数量" prop="number"></el-table-column>
|
||||||
|
<el-table-column label="已退数量" prop="refundNumber"></el-table-column>
|
||||||
|
<el-table-column label="订单金额" prop="orderAmount">
|
||||||
|
<template v-slot="scope">
|
||||||
|
¥{{ scope.row.orderAmount }}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="支付金额" prop="payAmount">
|
||||||
|
<template v-slot="scope">
|
||||||
|
¥{{ scope.row.payAmount }}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="支付方式" prop="payType">
|
||||||
|
<template v-slot="scope">
|
||||||
|
{{ payF(scope.row.payType) }}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="下单人电话" prop="phone"></el-table-column>
|
||||||
|
<el-table-column label="是否支持退款" prop="refundAble">
|
||||||
|
<template v-slot="scope">
|
||||||
|
{{ scope.row.refundAble ? "是" : "否" }}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="备注" prop="remark"></el-table-column>
|
||||||
|
<el-table-column label="状态" prop="status">
|
||||||
|
<template v-slot="scope">
|
||||||
|
<el-tag :type="statusF(scope.row.status)">
|
||||||
|
{{ scope.row.status }}
|
||||||
|
</el-tag>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="交易日期" prop="tradeDay"></el-table-column>
|
||||||
|
<el-table-column label="核销员" prop="verifier"></el-table-column>
|
||||||
|
<!-- <el-table-column label="操作" width="100">
|
||||||
|
<template v-slot="scope">
|
||||||
|
<el-button type="text" icon="el-icon-edit" @click="showRefund(scope.row)"
|
||||||
|
:disabled="!scope.row.refundAble">退款</el-button>
|
||||||
|
</template>
|
||||||
|
</el-table-column> -->
|
||||||
|
</el-table>
|
||||||
|
</div>
|
||||||
|
<div class="head-container">
|
||||||
|
<el-pagination :total="tableData.total" :current-page="tableData.page + 1" :page-size="tableData.size"
|
||||||
|
@current-change="paginationChange" layout="total, sizes, prev, pager, next, jumper"></el-pagination>
|
||||||
|
</div>
|
||||||
|
<el-dialog title="退款" :visible.sync="showDialog" width="400px">
|
||||||
|
<el-form ref="refundForm" :model="refundForm" :rules="refundFormRules" label-position="top">
|
||||||
|
<el-form-item label="退单数" prop="num">
|
||||||
|
<el-select v-model="refundForm.num" placeholder="请选择退单数" style="width: 100%;" @change="refundNumChange">
|
||||||
|
<el-option :label="item" :value="item" v-for="item in refundNumList" :key="item"></el-option>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="退单金额">
|
||||||
|
<el-input v-model="refundForm.refundAmount" disabled placeholder="请选择退单数"></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="退款原因">
|
||||||
|
<el-input v-model="refundForm.refundReason" type="textarea" placeholder="请输入退款原因"></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
<span slot="footer" class="dialog-footer">
|
||||||
|
<el-button @click="showDialog = false">取消</el-button>
|
||||||
|
<el-button type="primary" :loading="refundLoading" @click="refundConfirm">确 定</el-button>
|
||||||
|
</span>
|
||||||
|
</el-dialog>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { tbGroupOrderInfo, returnGpOrder } from "@/api/order";
|
||||||
|
import dayjs from "dayjs";
|
||||||
|
export default {
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
query: {
|
||||||
|
orderNo: "",
|
||||||
|
payType: "",
|
||||||
|
phone: "",
|
||||||
|
proName: "",
|
||||||
|
status: "",
|
||||||
|
createTime: []
|
||||||
|
},
|
||||||
|
resetQuery: "",
|
||||||
|
tableData: {
|
||||||
|
data: [],
|
||||||
|
page: 0,
|
||||||
|
size: 10,
|
||||||
|
loading: false,
|
||||||
|
total: 0
|
||||||
|
},
|
||||||
|
payTypes: [
|
||||||
|
{
|
||||||
|
value: "wechatPay",
|
||||||
|
label: "微信支付"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: "aliPay",
|
||||||
|
label: "支付宝支付"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
statusList: [
|
||||||
|
{
|
||||||
|
value: "unpaid",
|
||||||
|
label: "待付款",
|
||||||
|
type: "warning"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: "unused",
|
||||||
|
label: "待使用",
|
||||||
|
type: "primary"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: "closed",
|
||||||
|
label: "已完成",
|
||||||
|
type: "success"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: "refunding",
|
||||||
|
label: "退款中",
|
||||||
|
type: "warning"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: "refund",
|
||||||
|
label: "已退款",
|
||||||
|
type: "default"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: "cancelled",
|
||||||
|
label: "已取消",
|
||||||
|
type: "danger"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
row: '',
|
||||||
|
showDialog: false,
|
||||||
|
refundNumList: [],
|
||||||
|
refundLoading: false,
|
||||||
|
refundForm: {
|
||||||
|
num: '',
|
||||||
|
orderId: '',
|
||||||
|
refundAmount: '',
|
||||||
|
refundDesc: '',
|
||||||
|
refundReason: ''
|
||||||
|
},
|
||||||
|
refundFormRules: {
|
||||||
|
num: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: ' ',
|
||||||
|
trigger: 'change'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
};
|
||||||
|
},
|
||||||
|
filters: {
|
||||||
|
timeFilter(s) {
|
||||||
|
return dayjs(s).format("YYYY-MM-DD HH:mm:ss");
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.getTableData();
|
||||||
|
this.resetQuery = { ...this.query };
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
// 提交退单
|
||||||
|
refundConfirm() {
|
||||||
|
this.$refs.refundForm.validate(async valid => {
|
||||||
|
if (valid) {
|
||||||
|
try {
|
||||||
|
this.refundLoading = true
|
||||||
|
const res = await returnGpOrder(this.refundForm)
|
||||||
|
this.refundLoading = false
|
||||||
|
this.$notify({
|
||||||
|
title: '成功',
|
||||||
|
message: `退单成功`,
|
||||||
|
type: 'success'
|
||||||
|
});
|
||||||
|
this.showDialog = false
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error);
|
||||||
|
this.refundLoading = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
// 计算退单金额
|
||||||
|
refundNumChange(e) {
|
||||||
|
this.refundForm.refundAmount = Math.floor(this.row.orderAmount / e * 100) / 100
|
||||||
|
},
|
||||||
|
// 显示退款
|
||||||
|
showRefund(row) {
|
||||||
|
this.row = row
|
||||||
|
let arr = []
|
||||||
|
for (let i = 1; i <= row.number - row.refundNumber; i++) {
|
||||||
|
arr.push(i)
|
||||||
|
}
|
||||||
|
this.refundNumList = arr
|
||||||
|
this.refundForm.orderId = row.id
|
||||||
|
this.showDialog = true
|
||||||
|
},
|
||||||
|
payF(p) {
|
||||||
|
return p && this.payTypes.find(item => item.value == p).label;
|
||||||
|
},
|
||||||
|
statusF(t) {
|
||||||
|
return t && this.statusList.find(item => item.label == t).type;
|
||||||
|
},
|
||||||
|
// 切换状态
|
||||||
|
async statusChange(e, row) {
|
||||||
|
try {
|
||||||
|
this.tableData.loading = true;
|
||||||
|
const data = { ...row };
|
||||||
|
data.status = e;
|
||||||
|
await tbPrintMachine(data, "put");
|
||||||
|
this.getTableData();
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error);
|
||||||
|
this.tableData.loading = false;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 重置查询
|
||||||
|
resetHandle() {
|
||||||
|
this.query = { ...this.resetQuery };
|
||||||
|
this.getTableData();
|
||||||
|
},
|
||||||
|
// 分页回调
|
||||||
|
paginationChange(e) {
|
||||||
|
this.tableData.page = e - 1;
|
||||||
|
this.getTableData();
|
||||||
|
},
|
||||||
|
// 获取列表
|
||||||
|
async getTableData() {
|
||||||
|
this.tableData.loading = true;
|
||||||
|
try {
|
||||||
|
const res = await tbGroupOrderInfo({
|
||||||
|
...this.query,
|
||||||
|
page: this.tableData.page,
|
||||||
|
size: this.tableData.size,
|
||||||
|
sort: "id"
|
||||||
|
});
|
||||||
|
this.tableData.loading = false;
|
||||||
|
this.tableData.data = res.content;
|
||||||
|
this.tableData.total = res.totalElements;
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|||||||