初始上传

This commit is contained in:
2026-04-04 17:27:12 +08:00
parent 4d80d28eb4
commit b7e11774ee
11191 changed files with 1588469 additions and 0 deletions

653
app/shop/view/member/index.html Executable file
View File

@@ -0,0 +1,653 @@
<style>
.body-content {
background: none !important;
padding: 0 !important;
margin: 0 !important;
}
.summary-wrap {
display: flex;
flex-wrap: wrap;
}
.summary-wrap .summary-item {
padding: 0 15px;
box-sizing: border-box;
flex: 1;
}
.summary-wrap .summary-item .title, .summary-wrap .summary-item .bottom-title {
color: #909399;
font-size: 14px;
margin-top: 5px;
}
.summary-wrap .summary-item .value {
color: #303133;
font-size: 26px;
margin-top: 10px;
}
.summary-wrap .last {
width: 240px;
flex: none;
padding-left: 80px !important;
border-left: 1px solid #eee;
}
.trend-wrap, .constitute-wrap, .distribution {
display: flex;
}
.trend-wrap .common-wrap, .constitute-wrap .common-wrap, .distribution .wrap {
flex: 1;
}
.trend-wrap .common-wrap:first-child, .constitute-wrap .common-wrap:first-child{
margin-right: 0;
}
.distribution .wrap:first-child {
margin-right: 15px;
display: flex;
justify-content: center;
}
</style>
<div class="common-wrap">
<div class="head">
<div class="title">实时概况</div>
<div class="sub-title">更新时间:{:date('Y-m-d H:i:s')}</div>
</div>
<div class="body summary-wrap">
<div class="summary-item">
<div class="title">今日新增会员数</div>
<div class="value" id="today_member_count">0</div>
<div class="bottom-title">昨日:<span id="yesterday_member_count">0</span></div>
</div>
<div class="summary-item">
<div class="title">今日下单会员数</div>
<div class="value" id="today_order_member_count">0</div>
<div class="bottom-title">昨日:<span id="yesterday_order_member_count">0</span></div>
</div>
<div class="summary-item">
<div class="title">今日储值会员数</div>
<div class="value" id="today_member_recharge_member_count">0</div>
<div class="bottom-title">昨日:<span id="yesterday_member_recharge_member_count">0</span></div>
</div>
<div class="summary-item">
<div class="title">今日领券会员数</div>
<div class="value" id="today_coupon_member_count">0</div>
<div class="bottom-title" >昨日:<span id="yesterday_coupon_member_count">0</span></div>
</div>
<div class="summary-item last">
<div class="title">下单会员数</div>
<div class="value" id="buyed_count">0</div>
<div class="bottom-title" >未下单会员数:<span id="not_buyed_count">0</span></div>
</div>
<div class="echart">
<div id="main" style="width: 230px; height: 90px;"></div>
</div>
</div>
</div>
<div class="trend-wrap">
<div class="common-wrap">
<div class="head">
<div class="title">新增会员数</div>
</div>
<div class="body">
<div id="newAdd" style="width: 100%; height: 300px;"></div>
</div>
</div>
<div class="common-wrap">
<div class="head">
<div class="title">消费会员数</div>
</div>
<div class="body">
<div id="consume" style="width: 100%; height: 300px;"></div>
</div>
</div>
</div>
<div class="constitute-wrap">
<div class="common-wrap">
<div class="head">
<div class="title">会员注册渠道比率</div>
</div>
<div class="body">
<div id="channel" style="width: 100%; height: 200px;"></div>
</div>
</div>
<div class="common-wrap">
<div class="head">
<div class="title">会员等级比率</div>
</div>
<div class="body">
<div id="level" style="width: 100%; height: 200px;"></div>
</div>
</div>
</div>
<div class="common-wrap">
<div class="head">
<div class="title">会员分布</div>
</div>
<div class="body distribution">
<div class="wrap">
<div id="china_echart" style="width: 80%;height: 600px"></div>
</div>
<div class="wrap">
<table id="member_list" lay-filter="member_list" class="layui-table"></table>
</div>
</div>
</div>
<script>
$(document).ready(function () {
getMemberStatData();
getMemberLevelRatio();
getMemberStat();
getMemberChannelRatio();
layui.use('form', function () {
var table, form = layui.form;
form.render();
table = new Table({
elem: '#member_list',
url: ns.url("shop/member/areaCount"),
where: {
handle: true
},
parseData: function (res) { //res 即为原始返回的数据
var list = [];
var result = res.data.list;
if (result.length > 0) {
china_option.series[0].data = result;
for (var i in result){
if(result[i].value > 0){
list.push(result[i])
}
}
}
china_echart.setOption(china_option);
return {
"code": res.code, //解析接口状态
"msg": res.message, //解析提示文本
"count": res.data.list.length, //解析数据长度
"data": list //解析数据列表
};
},
page: false,
cols: [
[
{
field: 'LAY_INDEX',
title: '排名',
unresize: 'false',
width: '20%',
templet: function (data) {
return data.LAY_INDEX;
}
}, {
field: 'name',
title: '地区',
unresize: 'false',
width: '30%'
}, {
field: 'value',
title: '会员数',
unresize: 'false',
width: '25%'
}, {
field: 'ratio',
title: '会员占比',
unresize: 'false',
width: '25%',
templet: function (data) {
return data.ratio + '%';
}
}
]
]
});
});
// 基于准备好的dom初始化echarts实例
if($('#main').length) {
var myChart = echarts.init(document.getElementById('main'));
// 指定图表的配置项和数据
var option = {
tooltip: {
trigger: 'item',
formatter: '{a} <br/>{b}: {c} ({d}%)'
},
legend: {
orient: 'vertical',
right: 0,
top: 0,
data: ['下单会员数', '未下单会员数']
},
color: ['#2FCE63', '#F5CC4E'],
series: [{
width: 100,
height: 100,
top: -5,
left: 0,
name: '',
type: 'pie',
radius: ['50%', '70%'],
avoidLabelOverlap: false,
label: {
show: false,
position: 'center'
},
emphasis: {
label: {
show: true,
fontSize: '12',
color: baseColor
}
},
labelLine: {
show: false
},
data: [
{
value: 0,
name: '下单会员数',
tooltip: {
trigger: 'item',
backgroundColor: 'rgba(255, 255, 255, 0.7)',
borderColor: '#999',
borderWidth: 1,
padding: 10,
textStyle: {
fontSize: 12,
color: '#333'
}
}
},
{
value: 0,
name: '未下单会员数',
tooltip: {
trigger: 'item',
backgroundColor: 'rgba(255, 255, 255, 0.7)',
borderColor: '#999',
borderWidth: 1,
padding: 10,
textStyle: {
color: '#333',
fontSize: 12
}
}
}
]
}]
};
// 使用刚指定的配置项和数据显示图表。
myChart.setOption(option);
}
if($("#china_echart").length) {
var china_echart = echarts.init(document.getElementById('china_echart'));
var china_option = {
tooltip: {
formatter: function (params, ticket, callback) {
return params.seriesName + '<br />' + params.name + '' + params.value
}
},
visualMap: {
min: 0,
max: 1500,
left: 'left',
top: 'bottom',
text: ['高', '低'],
inRange: {
color: ['#FFF', '#ff8143']
},
show: false
},
geo: {
map: 'china',
roam: false,
zoom: 1.23,
label: {
normal: {
show: true,
fontSize: '10',
color: 'rgba(0,0,0,0.7)'
}
},
itemStyle: {
normal: {
borderColor: 'rgba(0, 0, 0, 0.2)'
},
emphasis: {
areaColor: '#e0ffff',
shadowOffsetX: 0,
shadowOffsetY: 0,
shadowBlur: 20,
borderWidth: 0,
shadowColor: 'rgba(0, 0, 0, 0.5)'
}
}
},
series: [{
name: '会员数',
type: 'map',
geoIndex: 0,
data: [{"name": "北京", "value": 0}, {"name": "天津", "value": 0}, {"name": "河北", "value": 0}, {
"name": "山西",
"value": 0
}, {"name": "内蒙古", "value": 0}, {"name": "辽宁", "value": 0}, {"name": "吉林", "value": 0}, {
"name": "黑龙江",
"value": 0
}, {"name": "上海", "value": 0}, {"name": "江苏", "value": 0}, {"name": "浙江", "value": 0}, {
"name": "安徽",
"value": 0
}, {"name": "福建", "value": 0}, {"name": "江西", "value": 0}, {"name": "山东", "value": 0}, {
"name": "河南",
"value": 0
}, {"name": "湖北", "value": 0}, {"name": "湖南", "value": 0}, {"name": "广东", "value": 0}, {
"name": "广西",
"value": 0
}, {"name": "海南", "value": 0}, {"name": "重庆", "value": 0}, {"name": "四川", "value": 0}, {
"name": "贵州",
"value": 0
}, {"name": "云南", "value": 0}, {"name": "西藏", "value": 0}, {"name": "陕西", "value": 0}, {
"name": "甘肃",
"value": 0
}, {"name": "青海", "value": 0}, {"name": "宁夏", "value": 0}, {"name": "新疆", "value": 0}, {
"name": "香港",
"value": 0
}, {"name": "澳门", "value": 0}, {"name": "台湾", "value": 0}]
}]
};
china_echart.setOption(china_option);
}
function getMemberStat(){
$.ajax({
type:'post',
dataType:'json',
url:ns.url('shop/member/stat'),
success:function(res){
$("#not_buyed_count").html(res.not_buyed_count)
$("#buyed_count").html(res.buyed_count)
$("#today_member_count").html(res.today.member_count)
$("#yesterday_member_count").html(res.yesterday.member_count)
$("#today_order_member_count").html(res.today.order_member_count)
$("#yesterday_order_member_count").html(res.yesterday.order_member_count)
$("#today_member_recharge_member_count").html(res.today.member_recharge_member_count)
$("#yesterday_member_recharge_member_count").html(res.yesterday.member_recharge_member_count)
$("#today_coupon_member_count").html(res.today.coupon_member_count)
$("#yesterday_coupon_member_count").html(res.yesterday.coupon_member_count)
option.series[0].data[0].value = res.buyed_count;
option.series[0].data[1].value = res.not_buyed_count;
myChart.setOption(option);
}
})
}
});
var baseColor = getComputedStyle(document.documentElement).getPropertyValue('--base-color');
function areaCount() {
$.ajax({
url: ns.url("shop/member/areaCount"),
dataType: 'JSON',
type: 'POST',
success: function (res) {
if (res.data.list.length > 0) {
china_option.series[0].data = res.data.list;
}
china_echart.setOption(china_option);
}
})
}
// areaCount();
/**
* 获取会员七日趋势数据
*/
function getMemberStatData() {
$.ajax({
dataType: 'JSON',
type: 'POST',
url: ns.url("shop/stat/getStatData"),
success: function(res) {
// 基于准备好的dom初始化echarts实例
if($('#newAdd').length == 0 && $('#consume').length == 0) return;
var newAddChart = echarts.init(document.getElementById('newAdd'));
var consumeChart = echarts.init(document.getElementById('consume'));
// 指定图表的配置项和数据
var option = {
xAxis: {
type: 'category',
data: []
},
yAxis: {
type: 'value'
},
grid: {
top: '8%',
bottom: '9%',
left: '8%',
right: '4%'
},
tooltip: {
trigger: 'axis',
showContent: true,
backgroundColor: 'rgba(0, 0, 0, 0.5)',
padding: [5, 10],
textStyle: {
color: '#fff',
lineHeight: 30,
},
formatter: function(params, ticket, callback) {
return "日期:" + params[0].axisValue + '<br />' + params[0].seriesName + "" + params[0].value + "人";
},
},
series: [{
name: [''],
data: [],
type: 'line',
smooth: true,
itemStyle: {
color: baseColor
},
areaStyle: {
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{
offset: 0,
color: baseColor
}, {
offset: 1,
color: '#fff'
}])
}
}]
};
option.xAxis.data = res.time;
option.series[0].name = '新增会员数';
option.series[0].data = res.member_count;
newAddChart.setOption(option);
option.series[0].name = '消费会员数';
option.series[0].data = res.order_member_count;
consumeChart.setOption(option);
}
});
}
function getMemberLevelRatio() {
$.ajax({
dataType: 'JSON',
type: 'POST',
url: ns.url("shop/member/memberLevel"),
data: {
page_size: 0,
},
success: function(res) {
var level = res.data;
if($('#level').length == 0) return;
var echart = echarts.init(document.getElementById('level'));
// 指定图表的配置项和数据
var option = {
tooltip: {
trigger: 'item',
formatter: '{a} <br/>{b}: {c} ({d}%)'
},
legend: {
orient: 'vertical',
left: '55%',
top: '10%',
align: 'auto',
data: level.map(function (item) {
return {
name: item.level_name,
icon: 'circle',
}
})
},
color: level.map(function (item) {
return getRandomColor();
}),
series: [{
width: 180,
height: 180,
top: 10,
left: '10%',
name: '',
type: 'pie',
radius: ['50%', '70%'],
avoidLabelOverlap: false,
label: {
show: false,
position: 'center'
},
emphasis: {
label: {
show: true,
fontSize: '12',
color: baseColor
}
},
labelLine: {
show: false
},
data: level.map(function (item) {
return {
value: item.member_num,
name: item.level_name,
tooltip: {
trigger: 'item',
backgroundColor: 'rgba(255, 255, 255, 0.7)',
borderColor: '#999',
borderWidth: 1,
padding: 10,
textStyle: {
fontSize: 12,
color: '#333'
}
}
}
})
}]
};
// 使用刚指定的配置项和数据显示图表。
echart.setOption(option);
}
})
}
function getMemberChannelRatio() {
$.ajax({
dataType: 'JSON',
type: 'POST',
url: ns.url("shop/member/getRegisterChannelMemberNum"),
success: function(res) {
var level = res.data;
if ($("#channel").length == 0) return;
var echart = echarts.init(document.getElementById('channel'));
// 指定图表的配置项和数据
var option = {
tooltip: {
trigger: 'item',
formatter: '{a} <br/>{b}: {c} ({d}%)'
},
legend: {
orient: 'vertical',
left: '55%',
top: '20%',
data: level.map(function (item) {
return {
name: item.name,
icon: 'circle',
}
})
},
color: level.map(function (item) {
return getRandomColor();
}),
series: [{
width: 180,
height: 180,
top: 10,
left: '10%',
name: '',
type: 'pie',
radius: ['50%', '70%'],
avoidLabelOverlap: false,
label: {
show: false,
position: 'center'
},
emphasis: {
label: {
show: true,
fontSize: '12',
color: baseColor
}
},
labelLine: {
show: false
},
data: level.map(function (item) {
return {
value: item.member_num,
name: item.name,
tooltip: {
trigger: 'item',
backgroundColor: 'rgba(255, 255, 255, 0.7)',
borderColor: '#999',
borderWidth: 1,
padding: 10,
textStyle: {
fontSize: 12,
color: '#333'
}
}
}
})
}]
};
// 使用刚指定的配置项和数据显示图表。
echart.setOption(option);
}
})
}
/**
* 随机生成颜色
* @returns {string}
*/
function getRandomColor(){
return '#' + (function(color){
return (color += '0123456789abcdef'[Math.floor(Math.random()*16)])
&& (color.length == 6) ? color : arguments.callee(color);
})('');
}
</script>
<script src="SHOP_JS/echarts.min.js"></script>
<script src="SHOP_JS/china.js"></script>