初始上传

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

View File

@@ -0,0 +1,221 @@
<style>
.custom-panel .custom-panel-from { display: flex; }
.custom-panel .custom-panel-from .layui-form-label{
text-align: center;
}
.custom-panel .custom-panel-from>div{
text-align: center;
}
.custom-panel .custom-panel-from .layui-form-item>div>span{
margin-right: 10px;
}
.screen {
margin: 15px 0;
}
.layui-colla-content {
border: none;
background-color: #F2F3F5;
}
</style>
<div class="custom-panel">
<div class="screen layui-collapse" lay-filter="selection_panel">
<div class="layui-colla-item">
<form class="layui-colla-content layui-form layui-show">
<div class="layui-form-item flex">
{if $account_type == 'balance,balance_money'}
<div class="layui-inline">
<label class="layui-form-label">账户类型</label>
<div class="layui-input-inline">
<select name="account_type" lay-filter="account_type">
<option value="balance,balance_money">请选择</option>
<option value="balance">储值余额</option>
<option value="balance_money">现金余额</option>
</select>
</div>
</div>
<div class="layui-inline">
<label class="layui-form-label">来源类型</label>
<div class="layui-input-inline">
<select name="from_type" class="from_type">
<option value="">请选择</option>
</select>
</div>
</div>
{else /}
<div class="layui-inline">
<label class="layui-form-label">来源类型</label>
<div class="layui-input-inline">
<select name="from_type" class="from_type">
<option value="">请选择</option>
{foreach $from_type_arr as $from_type_arr_k => $from_type_arr_v}
<option value="{$from_type_arr_k}">{$from_type_arr_v['type_name']}</option>
{/foreach}
</select>
</div>
</div>
{/if}
</div>
<div class="layui-form-item flex">
<div class="layui-inline">
<label class="layui-form-label">发生时间</label>
<div class="layui-input-inline">
<input type="text" class="layui-input" name="start_date" id="start_date_{$table_id}" placeholder="开始时间" autocomplete="off" readonly>
</div>
</div>
<div class="layui-inline">
<div class="layui-input-inline split">&nbsp;&nbsp;-&nbsp;&nbsp;</div>
<div class="layui-input-inline">
<input type="text" class="layui-input" name="end_date" id="end_date_{$table_id}" placeholder="结束时间" autocomplete="off" readonly>
</div>
</div>
</div>
<div class="form-row">
<button class="layui-btn" lay-submit lay-filter="search_{$table_id}">筛选</button>
<button type="reset" class="layui-btn layui-btn-primary">重置</button>
</div>
<input type="hidden" name="member_id" value="{$member_id}" id="member_id"/>
</form>
</div>
</div>
</div>
<!-- 列表 -->
<table id="member_account_{$table_id}" lay-filter="member_account_{$table_id}"></table>
<script>
//余额 积分 成长值 都是同一个页面 变量都是相同的 需要通过闭包避免变量污染
(function(){
var form, table, laydate, laytpl;
var currentDate = new Date();
currentDate.setDate(currentDate.getDate() - 7);
layui.use(['form', 'laydate', 'laytpl'], function() {
form = layui.form;
laydate = layui.laydate;
laytpl = layui.laytpl;
form.render();
//开始时间
laydate.render({
elem: '#start_date_{$table_id}',
type: 'datetime'
});
//结束时间
laydate.render({
elem: '#end_date_{$table_id}',
type: 'datetime'
});
laydate.render({
elem: '#start_date2',
type: 'datetime'
});
//结束时间
laydate.render({
elem: '#end_date2',
type: 'datetime'
});
laydate.render({
elem: '#start_date3',
type: 'datetime'
});
//结束时间
laydate.render({
elem: '#end_date3',
type: 'datetime'
});
//根据账户类型获取来源类型
form.on('select(account_type)', function (data) {
if (data.value == 'balance,balance_money') return;
$.ajax({
type: "POST",
url: ns.url("shop/member/getfromtype"),
data: {type: data.value},
dataType: 'JSON',
success: function (res) {
var html = '<option value="">请选择</option>';
$.each(res, function (k, v) {
html += '<option value="' + k + '">' + v.type_name + '</option>';
});
$('.from_type').html(html);
form.render();
}
});
});
table = new Table({
elem: '#member_account_{$table_id}',
url: ns.url("shop/member/accountDetail"),
where:{
member_id : $("#member_id").val(),
account_type : '{$account_type}',
},
cols: [
[{
field: 'account_type_name',
title: '账户类型',
width: '15%',
unresize: 'false'
}, {
title: '数据金额',
width: '15%',
unresize: 'false',
align:'right',
templet: function (d) {
if (d.account_data > 0) {
return '+' + (d.account_type == "point" || d.account_type == 'growth' ? parseInt(d.account_data) : d.account_data);
} else {
return d.account_type == "point" || d.account_type == 'growth' ? parseInt(d.account_data) : d.account_data;
}
}
}, {
field: '',
title: '',
width: '5%',
align:'center',
unresize: 'false'
}, {
field: 'type_name',
title: '发生方式',
unresize: 'false'
}, {
field: 'remark',
title: '备注',
width: '35%',
unresize: 'false',
templet: function(data) {
return `<a href="javascript:showRemark('${data.remark}');" class="text-color" style="margin-right:5px;">查看</a>`+data.remark;
}
}, {
field: 'create_time',
title: '发生时间',
unresize: 'false',
templet: function(data) {
return ns.time_to_date(data.create_time);
}
}]
]
});
form.on('submit(search_{$table_id})', function(data) {
table.reload({
page: {
curr: 1
},
where: data.field
});
return false;
});
});
})()
function showRemark(content) {
layer.open({
title: '备注',
content
});
}
</script>

View File

@@ -0,0 +1,189 @@
<div class="layui-form form-wrap">
<div class="layui-form-item">
<label class="layui-form-label"><span class="required">*</span>用户名:</label>
<div class="layui-input-block">
<input name="username" type="text" lay-verify="user" class="layui-input len-long" autocomplete="off" readonly onfocus="this.removeAttribute('readonly');" onblur="this.setAttribute('readonly',true);">
</div>
<div class="word-aux">用于登录,添加成功后不可编辑,请认真填写</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label"><span class="required">*</span>昵称:</label>
<div class="layui-input-block">
<input name="nickname" type="text" lay-verify="required" class="layui-input len-long">
</div>
<div class="word-aux">会员名称</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">手机号:</label>
<div class="layui-input-block">
<input name="mobile" type="text" lay-verify="mobile" class="layui-input len-long">
</div>
<div class="word-aux">请填写正确的手机号</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label"><span class="required">*</span>密码:</label>
<div class="layui-input-block">
<input type="password" name="password" lay-verify="required" class="layui-input len-long">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label short-label">头像:</label>
<div class="layui-input-inline">
<div class="upload-img-block square">
<div class="upload-img-box">
<div class="upload-default" id="headImg">
<div class="upload">
<i class="iconfont iconshangchuan"></i>
<p>点击上传</p>
</div>
</div>
<div class="operation">
<div>
<i title="图片预览" class="iconfont iconreview js-preview" style="margin-right: 20px;"></i>
<i title="删除图片" class="layui-icon layui-icon-delete js-delete"></i>
</div>
<div class="replace_img js-replace">点击替换</div>
</div>
<input type="hidden" name="headimg" />
</div>
<!-- <p id="headImg" class="no-replace">替换</p>
<i class="del">x</i> -->
</div>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">会员等级:</label>
<div class="layui-input-inline len-mid">
<select class="member_level" name="member_level" lay-filter="member_level">
<option value="">请选择</option>
{volist name="member_level_list" id="member_level"}
<option value="{$member_level.level_id}">{$member_level.level_name}</option>
{/volist}
</select>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">真实姓名:</label>
<div class="layui-input-inline">
<input name="realname" type="text" class="layui-input len-long">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">性别:</label>
<div class="layui-input-inline">
<input type="radio" name="sex" value="0" title="未知" checked="">
<input type="radio" name="sex" value="1" title="男">
<input type="radio" name="sex" value="2" title="女">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">生日:</label>
<div class="layui-input-inline">
<input name="birthday" type="text" id="laydate" class="layui-input len-mid" autocomplete="off">
</div>
</div>
<div class="form-row">
<button class="layui-btn" lay-submit lay-filter="save">保存</button>
<button class="layui-btn layui-btn-primary" onclick="backMemberList()">返回</button>
</div>
</div>
<script>
layui.use(['form', 'laydate'], function() {
var form = layui.form,
laydate = layui.laydate,
repeat_flag = false; //防重复标识
form.render();
laydate.render({
elem: '#laydate'
});
/**
* 表单验证
*/
form.verify({
mobile: function(value) {
if (value == '') {
return;
}
if (!ns.parse_mobile(value)) {
return '请输入正确的手机号码!';
}
},
isemail: function(value) {
var reg = /^[a-z0-9]+([._\\-]*[a-z0-9])*@([a-z0-9]+[-a-z0-9]*[a-z0-9]+.){1,63}[a-z0-9]+$/;
if (value == '') {
return;
}
if (!reg.test(value)) {
return '请输入正确的邮箱!';
}
},
user: function(value){
var reg = /^[A-Za-z0-9]+$/;
if (!reg.test(value)) {
return '用户名只能输入英文跟数字!';
}
}
});
var upload = new Upload({
elem: '#headImg'
});
/**
* 监听提交
*/
form.on('submit(save)', function(data) {
if (data.field.member_level) data.field.member_level_name = $(".member_level").find("option[value=" + data.field.member_level + "]").text();
// 删除图片
if(!data.field.headimg) upload.delete();
if(repeat_flag) return false;
repeat_flag = true;
$.ajax({
url: ns.url("shop/member/addMember"),
data: data.field,
dataType: 'JSON', //服务器返回json格式数据
type: 'POST', //HTTP请求类型
success: function(res) {
repeat_flag = false;
if (res.code == 0) {
layer.confirm('添加成功', {
title:'操作提示',
btn: ['返回列表', '继续添加'],
closeBtn: 0,
yes: function(index, layero) {
location.hash = ns.hash("shop/member/{$type == 'member' ? 'memberList' : 'customerlist'}")
layer.close(index);
},
btn2: function(index, layero) {
listenerHash(); // 刷新页面
layer.close(index);
}
});
}else{
layer.msg(res.message);
}
}
});
});
});
function backMemberList() {
location.hash = ns.hash("shop/member/{$type == 'member' ? 'memberList' : 'customerlist'}");
}
</script>

View File

@@ -0,0 +1,41 @@
<div style="margin: 15px 0;">
<table id="member_address_list" lay-filter="member_address_list"></table>
</div>
<script>
var table = new Table({
elem: '#member_address_list',
filter: "member_address_list",
url: ns.url("shop/member/addressdetail"),
where:{ member_id : "{$member_id}" },
cols: [[{
field: 'name',
width: '30%',
title: '名称',
unresize : 'true'
}, {
field: 'mobile',
width: '10%',
title: '手机号',
unresize : 'true'
}, {
field: 'telephone',
width: '20%',
title: '联系电话',
unresize : 'true'
}, {
width: '30%',
title: '地址信息',
unresize : 'true',
templet: function (d) {
return '<span title="'+ d.full_address.replace(/-/g, " ") + " " + d.address+'">'+ d.full_address.replace(/-/g, " ") + " " + d.address +'</span>';
}
}, {
width: '10%',
title: '是否默认地址',
unresize : 'true',
templet: function (d) {
return d.is_default ? "是" : "否";
}
}]],
});
</script>

View File

@@ -0,0 +1,212 @@
<div class="screen layui-collapse" lay-filter="selection_panel">
<div class="layui-colla-item">
<form class="layui-colla-content layui-form layui-show">
<div class="layui-form-item">
<div class="layui-inline">
<label class="layui-form-label">账号</label>
<div class="layui-input-inline">
<select name="search_text_type">
<option value="username">用户名</option>
<option value="nickname">昵称</option>
<option value="mobile">手机号</option>
</select>
</div>
<div class="layui-input-inline">
<input type="text" name="search_text" placeholder="用户名/昵称/手机号" autocomplete="off" class="layui-input ">
</div>
</div>
</div>
<div class="form-row">
<button class="layui-btn" lay-submit lay-filter="search">筛选</button>
</div>
</form>
</div>
</div>
<!-- 列表 -->
<table id="member_list" lay-filter="member_list"></table>
<!-- 用户信息 -->
<script type="text/html" id="userdetail">
<div class='table-title'>
<div class='title-pic'>
<img layer-src src="{{ns.img(d.headimg)}}" onerror="this.src = '{:img('public/static/img/default_img/head.png')}' ">
</div>
<div class='title-content'>
<p class="layui-elip">{{d.nickname}}</p>
</div>
</div>
</script>
<!-- 工具栏操作 -->
<script type="text/html" id="operation">
<div class="table-btn">
<a class="layui-btn" lay-event="remove">移除</a>
</div>
</script>
<script type="text/html" id="toolbarOperation">
<button class="layui-btn layui-btn-primary" lay-event="remove">批量移除</button>
</script>
<script type="text/html" id="batchOperation">
<button class="layui-btn layui-btn-primary" lay-event="remove">批量移除</button>
</script>
<script type="text/javascript">
var table, form;
layui.use(['form', 'laytpl'], function() {
form = layui.form;
table = new Table({
elem: '#member_list',
url: ns.url("shop/member/blacklist"),
cols: [
[
{
width: "3%",
type: 'checkbox',
unresize: 'false'
}, {
field: 'userdetail',
title: '账户',
width: '16%',
unresize: 'false',
templet: '#userdetail'
}, {
field: 'member_level_name',
title: '会员等级',
width: '12%',
unresize: 'false'
}, {
field: 'point',
title: '积分',
width: '15%',
unresize: 'false',
align: 'left',
templet: function (data) {
return parseInt(data.point);
}
}, {
field: 'balance',
title: '余额',
width: '15%',
unresize: 'false',
align: 'left',
templet: function(data) {
var balance = parseFloat(data.balance) + parseFloat(data.balance_money);
return '<span style="color: red;" title="'+ balance.toFixed(2) +'">¥' + balance.toFixed(2) + '</span>';
}
}, {
field: 'growth',
title: '成长值',
width: '15%',
unresize: 'false',
align: 'left'
}, {
field: 'reg-login',
title: '最后登录时间',
width: '20%',
unresize: 'false',
templet: function (data) {
return ns.time_to_date(data.last_login_time);
}
}, {
title: '操作',
unresize: 'false',
toolbar: '#operation',
align : 'right'
}
]
],
toolbar: '#toolbarOperation',
bottomToolbar: "#batchOperation"
});
/**
* 批量操作
*/
table.bottomToolbar(function(obj) {
if (obj.data.length < 1) {
layer.msg('请选择要操作的数据');
return;
}
switch (obj.event) {
case "remove":
var id_array = new Array();
for (i in obj.data) id_array.push(obj.data[i].member_id);
removeBlacklist(id_array.toString());
break;
}
});
/**
* 批量操作
*/
table.toolbar(function(obj) {
if (obj.data.length < 1) {
layer.msg('请选择要操作的数据');
return;
}
switch (obj.event) {
case "remove":
var id_array = new Array();
for (i in obj.data) id_array.push(obj.data[i].member_id);
removeBlacklist(id_array.toString());
break;
}
});
/**
* 监听工具栏操作
*/
table.tool(function(obj) {
var data = obj.data;
switch (obj.event) {
case 'remove': // 移除黑名单
removeBlacklist(data.member_id);
break;
}
});
function removeBlacklist(member_ids) {
layer.confirm('确定要移除黑名单?', function(index) {
layer.close(index);
$.ajax({
url: ns.url("shop/member/modifyStatus"),
data: {
member_ids: member_ids,
status: 1
},
dataType: 'JSON',
type: 'POST',
success: function(res) {
layer.msg(res.message);
if (res.code == 0) {
table.reload();
}
}
});
}, function () {
layer.close();
});
}
/**
* 搜索功能
*/
form.on('submit(search)', function(data) {
table.reload({
page: {
curr: 1
},
where: data.field
});
return false;
});
})
</script>

View File

@@ -0,0 +1,366 @@
<link rel="stylesheet" type="text/css" href="__STATIC__/ext/layui/extend/cascader/cascader.css"/>
<style>
.layui-layer-content .form-wrap {padding: 0}
.layui-layer-page .layui-layer-content {overflow-y: auto!important;}
.layui-layout-admin .layui-body .body-content {background: none;padding: 0}
.info-wrap {display: flex}
.info-wrap .layui-card {flex: 1;margin-top: 0}
.info-wrap .layui-card:first-child {margin-right: 15px}
.member-info {display: flex}
.member-info .headimg {margin-right: 15px;width: 70px;height: 70px;display: flex;align-items: center;justify-content: center;overflow: hidden}
.member-info .headimg img {max-width: 100%;height: auto}
.member-info .info {flex: 1;width: 0;display: flex;flex-wrap: wrap}
.member-info .info .data-item {width: 50%;padding-right: 10px;box-sizing: border-box;line-height: 30px}
.member-info .data-item .layui-icon {cursor: pointer}
.layui-tab-content {padding: 0}
.screen {margin: 15px 0}
.select-level-layer .layui-layer-content {overflow: unset!important;}
.card-common{padding-top: 20px;}
</style>
<div class="info-wrap">
<div class="layui-card card-common card-brief head">
<div class="layui-card-header">
<span class="card-title">基本信息</span>
</div>
<div class="layui-card-body">
<div class="member-info">
<div class="headimg">
{notempty name="$member_info.data.headimg"}
<img src="{:img($member_info.data.headimg)}" alt="">
{else/}
<img src="{:img('public/static/img/default_img/head.png')}" alt="">
{/notempty}
</div>
<div class="info">
<div class="data-item">
<span>用户名:</span>
<span>{$member_info.data.username}</span>
</div>
<div class="data-item">
<span>昵称:</span>
<span>{$member_info.data.nickname}</span>
<i class="layui-icon text-color" style="margin-left: 5px;" onclick="editNickname(this)"></i>
</div>
<div class="data-item">
<span>手机号:</span>
<span>{notempty name="$member_info.data.mobile"}{$member_info.data.mobile}{else/}暂无{/notempty}</span>
<i class="layui-icon text-color" style="margin-left: 5px;" onclick="editMobile(this)"></i>
</div>
{if $member_info.data.is_member}
<div class="data-item">
<span>会员码:</span>
<span>{notempty name="$member_info.data.member_code"}{$member_info.data.member_code}{else/}--{/notempty}</span>
</div>
{/if}
<div class="data-item">
<span>真实姓名:</span>
<span>{notempty name="$member_info.data.realname"}{$member_info.data.realname}{else/}暂无{/notempty}</span>
<i class="layui-icon text-color" style="margin-left: 5px;" onclick="editRealName(this)"></i>
</div>
<div class="data-item">
<span>性别:</span>
<span>
{switch name="$member_info.data.sex"}
{case value="0"}未知{/case}
{case value="1"}男{/case}
{case value="2"}女{/case}
{/switch}
</span>
<i class="layui-icon text-color" style="margin-left: 5px;" onclick="editSex(this)"></i>
</div>
<div class="data-item">
<span data-value="{$member_info.data.birthday}">生日:</span>
<span>{notempty name="$member_info.data.birthday"}{:date('Y-m-d', $member_info.data.birthday)}{else/}未知{/notempty}</span>
<i class="layui-icon text-color" style="margin-left: 5px;" onclick="editBirthday(this)"></i>
</div>
<div class="data-item">
<span>会员等级:</span>
<span>{$member_info.data.member_level_name}</span>
<i class="layui-icon text-color" style="margin-left: 5px;" onclick="editMemberLevel(this)"></i>
</div>
<div class="data-item">
<span>注册时间:</span>
<span>{:time_to_date($member_info.data.reg_time)}</span>
</div>
<div class="data-item">
<span>来源渠道:</span>
<span>{$member_info.data.login_type_name}</span>
</div>
<div class="data-item">
<span>最后访问时间:</span>
<span>{:time_to_date($member_info.data.last_visit_time)}</span>
</div>
<div class="data-item" style="width: 100%">
<span>会员地址:</span>
<span>{$member_info.data.full_address ? $member_info.data.full_address : '--'} {$member_info.data.address ? $member_info.data.address : ''}</span>
<i class="layui-icon text-color" style="margin-left: 5px;" onclick="editMemberAddress(this)"></i>
</div>
<input type="hidden" name="member_id" value="{$member_info.data.member_id}" />
<input type="hidden" class="birthday" value="{$member_info.data.birthday}" />
</div>
</div>
</div>
</div>
<div class="layui-card card-common card-brief head">
<div class="layui-card-header">
<span class="card-title">账户信息</span>
</div>
<div class="layui-card-body">
<div class="member-info">
<div class="info">
<div class="data-item">
<span>储值余额:</span>
<span id="member_balance">{:moneyFormat($member_info.data.balance)}</span>
<i class="layui-icon text-color" style="margin-left: 5px;" data-num="{$member_info.data.balance}" onclick="saveBalance(this)"></i>
</div>
<div class="data-item">
<span>现金余额:</span>
<span>{:moneyFormat($member_info.data.balance_money)}</span>
</div>
<div class="data-item">
<span>积分:</span>
<span id="member_point">{:round($member_info.data.point)}</span>
<i class="layui-icon text-color" style="margin-left: 5px;" data-num="{$member_info.data.point}" onclick="savePoint(this)"></i>
</div>
<div class="data-item">
<span>成长值:</span>
<span id="member_growth">{$member_info.data.growth}</span>
<i class="layui-icon text-color" style="margin-left: 5px;" data-num="{$member_info.data.growth}" onclick="saveGrowth(this)"></i>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="layui-card card-common card-brief head">
<div class="layui-card-header">
<span class="card-title">账户明细</span>
</div>
<div class="layui-card-body layui-tab layui-tab-brief" lay-filter="edit_member_tab">
<ul class="layui-tab-title">
<li class="layui-this" lay-id="account">余额</li>
<li lay-id="account">积分</li>
<li lay-id="account">成长值</li>
<li lay-id="basic_info">订单管理</li>
<li lay-id="basic_info">收货地址</li>
<li lay-id="basic_info">收藏记录</li>
<li lay-id="basic_info">浏览记录</li>
<li lay-id="basic_info">优惠券</li>
{if addon_is_exit('cardservice') == 1 }
<li lay-id="basic_info">卡项</li>
{/if}
</ul>
<div class="layui-tab-content">
<div class="layui-tab-item layui-show">
{:event('MemberDetail', [ 'member_id' => $member_info.data.member_id, 'type' => 'account', 'account_type' => 'balance,balance_money' ], true)}
</div>
<div class="layui-tab-item">
{:event('MemberDetail', [ 'member_id' => $member_info.data.member_id, 'type' => 'account', 'account_type' => 'point' ], true)}
</div>
<div class="layui-tab-item">
{:event('MemberDetail', [ 'member_id' => $member_info.data.member_id, 'type' => 'account', 'account_type' => 'growth' ], true)}
</div>
<div class="layui-tab-item">
{:event('MemberDetail', [ 'member_id' => $member_info.data.member_id, 'type' => 'order' ], true)}
</div>
<div class="layui-tab-item">
{:event('MemberDetail', [ 'member_id' => $member_info.data.member_id, 'type' => 'address_detail' ], true)}
</div>
<div class="layui-tab-item">
{:event('MemberDetail', [ 'member_id' => $member_info.data.member_id, 'type' => 'member_goods_collect' ], true)}
</div>
<div class="layui-tab-item">
{:event('MemberDetail', [ 'member_id' => $member_info.data.member_id, 'type' => 'member_goods_browse' ], true)}
</div>
<div class="layui-tab-item">
{:event('MemberDetail', [ 'member_id' => $member_info.data.member_id, 'type' => 'member_coupon' ], true)}
</div>
{if addon_is_exit('cardservice') == 1 }
<div class="layui-tab-item">
{:event('MemberDetail', [ 'member_id' => $member_info.data.member_id, 'type' => 'member_goods_card' ], true)}
</div>
{/if}
</div>
</div>
</div>
<!-- 积分弹框html -->
<script type="text/html" id="point">
<div class="layui-form integral-bounced">
<div class="layui-form-item">
<label class="layui-form-label">当前积分</label>
<div class="layui-input-block account-value">{{ parseInt(d.point) }}</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">调整数额</label>
<div class="layui-input-block amount">
<input type="number" value="0" placeholder="请输入调整数额" name="adjust_num" lay-verify="num" class="layui-input len-short">
</div>
<span class="word-aux">调整数额与当前积分数相加不能小于0</span>
</div>
<div class="layui-form-item">
<label class="layui-form-label">备注</label>
<div class="layui-input-block len-long">
<textarea class="layui-textarea" name="remark" placeholder="请输入备注" maxlength="150"></textarea>
</div>
</div>
<div class="form-row" style="margin-left: 200px;">
<button class="layui-btn" lay-submit lay-filter="savePoint">确定</button>
</div>
<input type="hidden" name="member_id" value="{$member_info.data.member_id}" />
<input type="hidden" name="point" value="{{ d.point }}" />
</div>
</script>
<!-- 余额弹框html -->
<script type="text/html" id="balance">
<div class="layui-form">
<div class="layui-form-item">
<label class="layui-form-label">当前储值余额</label>
<div class="layui-input-block account-value">{{ d.balance }}</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">调整数额</label>
<div class="layui-input-block">
<input type="number" value="0" placeholder="请输入调整数额" name="adjust_num" lay-verify="num" class="layui-input len-short">
</div>
<span class="word-aux">调整数额与当前储值余额相加不能小于0</span>
</div>
<div class="layui-form-item">
<label class="layui-form-label">备注</label>
<div class="layui-input-block len-long">
<textarea class="layui-textarea" name="remark" placeholder="请输入备注" maxlength="150"></textarea>
</div>
</div>
<div class="form-row" style="margin-left: 200px;">
<button class="layui-btn" lay-submit lay-filter="saveBalance">确定</button>
</div>
<input type="hidden" name="member_id" value="{$member_info.data.member_id}" />
<input type="hidden" name="point" value="{{ d.balance }}" />
</div>
</script>
<!-- 成长值弹框html -->
<script type="text/html" id="growth">
<div class="layui-form">
<div class="layui-form-item">
<label class="layui-form-label">当前成长值</label>
<div class="layui-input-block account-value">{{ d.growth }}</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">调整数额</label>
<div class="layui-input-block">
<input type="number" value="0" placeholder="请输入调整数额" name="adjust_num" lay-verify="num" class="layui-input len-short">
</div>
<span class="word-aux">调整数额与当前成长值相加不能小于0</span>
</div>
<div class="layui-form-item">
<label class="layui-form-label">备注</label>
<div class="layui-input-block len-long">
<textarea class="layui-textarea" name="remark" placeholder="请输入备注" maxlength="150"></textarea>
</div>
</div>
<div class="form-row" style="margin-left: 200px;">
<button class="layui-btn" lay-submit lay-filter="saveGrowth">确定</button>
</div>
<input type="hidden" name="member_id" value="{$member_info.data.member_id}" />
<input type="hidden" name="point" value="{{ d.growth }}" />
</div>
</script>
<script type="text/html" id="memberLevel">
<div class="layui-form" id="setMemberLevel">
<div class="layui-form-item">
<label class="layui-form-label sm">类型</label>
<div class="layui-input-block">
<input type="radio" name="level_type" value="0" title="会员等级" checked lay-filter="level_type">
<input type="radio" name="level_type" value="1" title="会员卡" lay-filter="level_type">
</div>
</div>
<div class="level-type type-0">
<div class="layui-form-item">
<label class="layui-form-label sm">会员等级</label>
<div class="layui-input-block len-mid">
<select name="member_level">
<option value="0">请选择会员等级</option>
{foreach name="member_level_list" item="vo"}
{if $vo.level_type eq 0}
<option value="{$vo.level_id}" {if $vo.level_id eq $member_info.data.member_level}selected{/if}>{$vo.level_name}</option>
{/if}
{/foreach}
</select>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label sm">会员卡号</label>
<div class="layui-input-block">
<input type="text" class="layui-input len-mid" value="{$member_info.data.member_code}" name="member_code" placeholder="">
</div>
<div class="word-aux" style="margin-left: 80px;">会员卡号为会员唯一编号若不设置将会自动生成</div>
</div>
</div>
<div class="level-type type-1" style="display: none">
<div class="layui-form-item">
<label class="layui-form-label sm">会员卡</label>
<div class="layui-input-block len-mid">
<select name="member_card" lay-filter="member_card">
<option value="0">请选择会员卡</option>
{foreach name="member_level_list" item="vo"}
{if $vo.level_type eq 1}
<option value="{$vo.level_id}" {if $vo.level_id eq $member_info.data.member_level}selected{/if}>{$vo.level_name}</option>
{/if}
{/foreach}
</select>
</div>
</div>
{foreach name="member_level_list" item="vo"}
{if $vo.level_type eq 1}
<div class="layui-form-item member-card member-card-{$vo.level_id}" style="display: none">
<label class="layui-form-label sm">发卡规格</label>
<div class="layui-input-block">
{foreach :json_decode($vo.charge_rule, true) as $key => $money}
<input type="radio" name="member_card_{$vo.level_id}" value="{$key}" title="{$level_time[$key]}/{$money}元" checked>
{/foreach}
</div>
</div>
{/if}
{/foreach}
</div>
</div>
</script>
<script>
var date = {$member_info.data.reg_time};
$(".reg-time").text(ns.time_to_date(date, "Y-m-d"));
$("#member_point").text(parseInt("{$member_info.data.point}"));
var point = {$member_info.data.point};
var balance = {$member_info.data.balance};
var growth = {$member_info.data.growth};
var member_id = '{$member_info.data.member_id}';
var province_id = '{$member_info.data.province_id}';
var city_id = '{$member_info.data.city_id}';
var district_id = '{$member_info.data.district_id}';
var address = '{$member_info.data.address}';
var full_address = '{$member_info.data.full_address}';
</script>
<script src="SHOP_JS/member_detail.js?time=5"></script>

View File

@@ -0,0 +1,75 @@
<style>
.layui-layout-admin .tips-wrap{margin-bottom: 15px;}
</style>
<div class="detail-card tips-wrap">
<div class="detail-con">
<p class="detail-line">
<span class="goods-name">会员导入</span>
<span class="text-color">{$info.data.status_name}</span>
</p>
<p class="detail-line">导入时间:{:date('Y-m-d H:i:s', $info.data.create_time)}</p>
</div>
</div>
<!-- 列表 -->
<table id="member_import_log_list" lay-filter="member_import_log_list"></table>
<!-- 工具栏操作 -->
<input id="record_id" type="hidden" value="{$id}" />
<script>
var table;
layui.use(['form','laytpl'], function() {
var form = layui.form,
record_id = $("#record_id").val();
form.render();
/**
* 表格加载
*/
table = new Table({
elem: '#member_import_log_list',
url: ns.url("shop/member/memberimportlist"),
where : {
"id" : record_id
},
cols: [
[{
field: 'username',
title: '用户名',
width: '8%',
unresize: 'false',
}, {
field: 'mobile',
title: '手机号',
width: '8%',
unresize: 'false',
}, {
field: 'nickname',
title: '昵称',
width: '15%',
unresize: 'false',
}, {
field: 'wx_openid',
title: '微信公众号openid',
width: '20%',
unresize: 'false',
}, {
field: 'weapp_openid',
title: '小程序openid',
width: '20%',
unresize: 'false',
}, {
field: 'password',
title: '密码',
width: '8%',
unresize: 'false',
}, {
field: 'content',
title: '内容',
width: '21%',
unresize: 'false',
}]
]
});
});
</script>

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>

View File

@@ -0,0 +1,90 @@
<div style="margin:15px 0;">
<table id="member_coupon_list" lay-filter="member_coupon_list"></table>
</div>
<!--状态-->
<script type="text/html" id="state">
{{# if(d.state == 1){ }}
<div class="layui-elip">已领取</div>
{{# }else if(d.state == 2){ }}
<div class="layui-elip">已使用</div>
{{# }else if(d.state == 3){ }}
<div class="layui-elip">已过期</div>
{{# } }}
</script>
<!--面额-->
<script type="text/html" id="types">
{{# if(d.type == 'reward'){ }}
<div class="layui-elip">{{d.money}}</div>
{{# }else if(d.type == 'discount'){ }}
<div class="layui-elip">{{d.discount}}</div>
{{# } }}
</script>
<!--领取时间-->
<script type="text/html" id="fetch_time">
{{ ns.time_to_date(d.fetch_time) }}
</script>
<!--使用时间-->
<script type="text/html" id="use_time">
{{ ns.time_to_date(d.use_time) }}
</script>
<!--结束时间-->
<script type="text/html" id="end_time">
{{ ns.time_to_date(d.end_time) }}
</script>
<script>
var getType = {:json_encode($get_type)};
var table = new Table({
elem: '#member_coupon_list',
filter: "member_coupon_list",
url: ns.url("shop/member/memberCoupon"),
where:{ member_id : "{$member_id}" },
cols: [[{
field: 'coupon_name',
width: '14%',
title: '优惠券名称',
unresize : 'true'
}, {
field: 'coupon_code',
width: '11%',
title: '优惠码',
unresize : 'true'
}, {
width: '10%',
title: '面额',
templet: '#types',
unresize : 'true',
}, {
width: '10%',
title: '获取方式',
templet: function (data) {
return getType[data.get_type] ? getType[data.get_type] : '';
},
unresize : 'true',
}, {
width: '10%',
title: '状态',
templet: '#state',
unresize : 'true'
}, {
width: '15%',
title: '领取时间',
templet: '#fetch_time',
unresize : 'true'
}, {
width: '15%',
title: '结束时间',
templet: '#end_time',
unresize : 'true'
}, {
width: '15%',
title: '使用时间',
templet: '#use_time',
unresize : 'true'
}]],
});
</script>

View File

@@ -0,0 +1,135 @@
<style>
.single-filter-box {justify-content: left;line-height: 34px}
.single-filter-box a{cursor:pointer;margin-left: 10px}
</style>
<div class="single-filter-box">
<button class="layui-btn" id="member_file">导入会员</button>
<a class="layui-btn layui-btn-primary" onclick="downloadMemberFile()">点击下载模板</a>
</div>
<!-- 列表 -->
<table id="member_import_log_list" lay-filter="member_import_log_list"></table>
<!-- 工具栏操作 -->
<script type="text/html" id="operation">
<div class="table-btn">
<a class="layui-btn" lay-event="info">查看</a>
</div>
</script>
<script>
var table,upload;
layui.use(['form', 'upload'], function() {
var form = layui.form;
upload = layui.upload;
form.render();
/**
* 表格加载
*/
table = new Table({
elem: '#member_import_log_list',
url: ns.url("shop/member/memberImport"),
cols: [
[{
field: 'create_time',
title: '导入时间',
width: '20%',
unresize: 'false',
}, {
field: 'member_num',
title: '导入会员数',
width: '20%',
unresize: 'false',
}, {
field: 'success_num',
title: '导入成功会员数',
width: '20%',
unresize: 'false',
}, {
field: 'error_num',
title: '导入失败会员数',
width: '15%',
unresize: 'false',
},
// {
// field: 'status_name',
// title: '导入状态',
// width: '15%',
// unresize: 'false',
// },
{
title: '操作',
unresize: 'false',
toolbar: '#operation',
align : 'right'
}]
]
});
//允许上传的文件后缀
upload.render({
elem: '#member_file'
,url: ns.url("shop/member/file"),
accept:'file',
acceptMime: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
exts: 'xlsx',
done: function(res){
if (res.code >= 0) {
member_import(1, res.data.name, res.data.path);
}else{
layer.msg(res.message);
}
}
});
/**
* 监听工具栏操作
*/
table.tool(function(obj) {
var data = obj.data;
switch (obj.event) {
case 'info': //查看
location.hash = ns.hash("shop/member/memberimportlist?id=" + data.id);
break
}
});
});
function member_import(index, name, path, success_num = 0, error_num = 0, record = 0){
$.ajax({
url: ns.url("shop/member/import"),
data: {
filename: name,
path: path,
index: index,
success_num : success_num,
error_num : error_num,
record : record
},
dataType: 'JSON',
type: 'POST',
success: function (res) {
index ++;
if(res.code == 0){
if(res.data.num < res.data.allRow){
member_import(index, res.data.name, res.data.path, res.data.success_num, res.data.error_num, res.data.record);
}else{
table.reload();
}
}
if(res.data.error_num > 0) {
layer.msg('导入失败');
} else {
layer.msg('导入成功');
}
}
});
}
function downloadMemberFile(){
location.href = ns.url("shop/member/downloadMemberFile",{ request_mode: 'download' });
}
</script>

File diff suppressed because it is too large Load Diff

120
app/shop/view/member/order.html Executable file
View File

@@ -0,0 +1,120 @@
<!-- 搜索框 -->
<div class="single-filter-box" style="margin:15px 0;">
<div class="layui-form" lay-filter="trade_search">
<div class="layui-input-inline len-mid">
<input type="text" id="search_text" name="search_text" placeholder="订单编号" autocomplete="off" class="layui-input ">
<button type="button" class="layui-btn layui-btn-primary" lay-filter="order_search" lay-submit>
<i class="layui-icon">&#xe615;</i>
</button>
</div>
</div>
</div>
<table id="trade_list" lay-filter="trade_list"></table>
<!-- 工具栏操作 -->
<script type="text/html" id="operation">
<div class="table-btn">
<a class="layui-btn" lay-event="detail">详情</a>
</div>
</script>
<script>
layui.use(['form'], function() {
var table,
form = layui.form;
/**
* 加载表格
*/
table = new Table({
elem: '#trade_list',
url: ns.url("shop/order/tradelist"),
where : {member_id:"{$member_id}"},
cols: [
[{
field: 'order_no',
title: '订单编号',
width: '15%',
unresize: 'false'
}, {
field: 'order_name',
title: '商品信息',
width: '12%',
unresize: 'false'
}, {
field: 'order_money',
title: '订单金额',
align: 'right',
width: '10%',
unresize: 'false',
templet: function(data) {
return '¥' + data.order_money;
}
}, {
field: 'order_from_name',
title: '订单来源',
align: 'center',
width: '10%',
unresize: 'false',
}, {
field: 'order_type_name',
title: '订单类型',
width: '8%',
align: 'center',
unresize: 'false'
}, {
field: 'pay_type_name',
title: '支付方式',
align: 'center',
width: '12%',
unresize: 'false',
}, {
field: 'order_status_name',
title: '订单状态',
width: '11%',
unresize: 'false'
}, {
field: 'create_time',
title: '下单时间',
width: '13%',
templet: function(data) {
return ns.time_to_date(data.create_time)
}
}, {
title: '操作',
unresize: 'false',
toolbar: '#operation',
align:'right'
}]
]
});
/**
* 监听工具栏操作
*/
table.tool(function(obj) {
var data = obj.data;
switch (obj.event) {
case 'detail': //详情
var url = "shop/order/detail";
window.open(ns.href(url,{order_id:data.order_id}));
break;
}
});
/**
* 搜索功能
*/
form.on('submit(order_search)', function(data) {
table.reload({
page: {
curr: 1
},
where: data.field
});
return false;
});
})
</script>

View File

@@ -0,0 +1,77 @@
<style type="text/css">
.form-wrap {position: relative;}
.examples {cursor: pointer;}
</style>
<div class="layui-form form-wrap">
<div class="layui-form-item">
<label class="layui-form-label">协议:</label>
<div class="layui-input-inline">
<input type="text" name="title" required lay-verify="required" placeholder="请输入协议标题" value="{$document_info.data.title}" autocomplete="off" class="layui-input len-long">
</div>
</div>
<div class="word-aux">
<p>协议内容展示使用该网站的一些相关规定</p>
<p>注册会员时需同意该协议才可继续注册 <a onclick="showDemo()" class="examples text-color">查看示例</a></p>
</div>
<div class="layui-form-item">
<label class="layui-form-label">内容:</label>
<div class="layui-input-inline">
<script id="editor" type="text/plain" class="special-length" style="height:300px;"></script>
</div>
</div>
<div class="form-row">
<button class="layui-btn" lay-submit lay-filter="save">保存</button>
</div>
<input type="hidden" name="" id="agreementContent" value="{$document_info.data.content}" />
</div>
<script type="text/javascript" charset="utf-8" src="STATIC_EXT/ueditor/ueditor.config.js?time=20240614"></script>
<script type="text/javascript" charset="utf-8" src="STATIC_EXT/ueditor/ueditor.all.js?time=20240614"></script>
<script type="text/javascript" charset="utf-8" src="STATIC_EXT/ueditor/lang/zh-cn/zh-cn.js"></script>
<script>
//实例化富文本
var ue = UE.getEditor('editor');
if($("#agreementContent").val()){
ue.ready(function() {
ue.setContent($("#agreementContent").val());
});
}
layui.use('form', function() {
var form = layui.form,
repeat_flag = false; //防重复标识
form.render();
//表单提交
form.on('submit(save)', function(data) {
if(repeat_flag) return false;
repeat_flag = true;
$.ajax({
url: ns.url("shop/member/privacyAgreement"),
data: {
'title': data.field.title,
'content': ue.getContent(),
},
dataType: 'JSON', //服务器返回json格式数据
type: 'POST', //HTTP请求类型
success: function(res) {
layer.msg(res.message);
repeat_flag = false;
}
});
});
});
function showDemo(){
layer.open({
title: '查看示例',
type: 1,
area: ['500px', '660px'],
content: '<img style="margin: 20px 80px;" src="SHOP_IMG/reg_info.png">'
})
}
</script>

View File

@@ -0,0 +1,77 @@
<style type="text/css">
.form-wrap {position: relative;}
.examples {cursor: pointer;}
</style>
<div class="layui-form form-wrap">
<div class="layui-form-item">
<label class="layui-form-label">协议:</label>
<div class="layui-input-inline">
<input type="text" name="title" required lay-verify="required" placeholder="请输入协议标题" value="{$document_info.data.title}" autocomplete="off" class="layui-input len-long">
</div>
</div>
<div class="word-aux">
<p>协议内容展示使用该网站的一些相关规定</p>
<p>注册会员时需同意该协议才可继续注册 <a onclick="showDemo()" class="examples text-color">查看示例</a></p>
</div>
<div class="layui-form-item">
<label class="layui-form-label">内容:</label>
<div class="layui-input-inline">
<script id="editor" type="text/plain" class="special-length" style="height:300px;"></script>
</div>
</div>
<div class="form-row">
<button class="layui-btn" lay-submit lay-filter="save">保存</button>
</div>
<input type="hidden" name="" id="agreementContent" value="{$document_info.data.content}" />
</div>
<script type="text/javascript" charset="utf-8" src="STATIC_EXT/ueditor/ueditor.config.js?time=20240614"></script>
<script type="text/javascript" charset="utf-8" src="STATIC_EXT/ueditor/ueditor.all.js?time=20240614"></script>
<script type="text/javascript" charset="utf-8" src="STATIC_EXT/ueditor/lang/zh-cn/zh-cn.js"></script>
<script>
//实例化富文本
var ue = UE.getEditor('editor');
if($("#agreementContent").val()){
ue.ready(function() {
ue.setContent($("#agreementContent").val());
});
}
layui.use('form', function() {
var form = layui.form,
repeat_flag = false; //防重复标识
form.render();
//表单提交
form.on('submit(save)', function(data) {
if(repeat_flag) return false;
repeat_flag = true;
$.ajax({
url: ns.url("shop/member/regAgreement"),
data: {
'title': data.field.title,
'content': ue.getContent(),
},
dataType: 'JSON', //服务器返回json格式数据
type: 'POST', //HTTP请求类型
success: function(res) {
layer.msg(res.message);
repeat_flag = false;
}
});
});
});
function showDemo(){
layer.open({
title: '查看示例',
type: 1,
area: ['500px', '660px'],
content: '<img style="margin: 20px 80px;" src="SHOP_IMG/reg_info.png">'
})
}
</script>

View File

@@ -0,0 +1,249 @@
<style>
.layui-form-item .layui-form-checkbox[lay-skin=primary] {
margin-top: 0;
}
.desc{
margin-bottom: 15px;border:1px dashed;padding: 5px 10px;width: 65%;
}
.word-aux{
width: 50%!important;
}
.examples {cursor: pointer; margin-left: 5px; font-weight: 500;}
.layui-carousel {width: 850px !important; height: 580px !important; background: #fff !important;}
.layui-carousel>[carousel-item]>* {background: #fff !important;}
</style>
<div class="layui-form form-wrap">
<div class="layui-card card-common card-brief">
<div class="layui-card-header">
<span class="card-title">普通登录注册设置<a onclick="showDemo1()" class="examples text-color">查看示例</a></span>
</div>
<div class="layui-card-body">
<div class="desc text-color border-color bg-color-light-9">
设置在非第三方平台(第三方平台是指微信公众号,微信小程序,支付宝小程序等平台内部)或第三方平台自动注册未开启情况下会员的注册登录方式。
</div>
<div class="layui-form-item">
<label class="layui-form-label ">用户名:</label>
<div class="layui-input-block">
<input type="checkbox" name="register" value="username" title="注册" lay-skin="primary" {if condition="!empty($value['register']) && in_array('username', $value['register'])"}checked{/if}>
<input type="checkbox" name="login" value="username" title="登录" lay-skin="primary" {if condition="!empty($value['login']) && in_array('username', $value['login'])"}checked{/if}>
</div>
<div class="word-aux">用户名是指通过用户名加密码的注册登录方式。</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label ">手机号:</label>
<div class="layui-input-block">
<input type="checkbox" name="register" value="mobile" title="注册" lay-skin="primary" {if condition="!empty($value['register']) && in_array('mobile', $value['register'])"}checked{/if}>
<input type="checkbox" name="login" value="mobile" title="登录" lay-skin="primary" {if condition="!empty($value['login']) && in_array('mobile', $value['login'])"}checked{/if}>
</div>
<div class="word-aux">手机号是指通过手机号加动态验证码的注册登录方式。</div>
<div class="word-aux">启用前需配置好“注册验证”,“动态码登录”短信模板,<a href="{:href_url('shop/message/lists')}" class="text-color" >前去配置</a></div>
</div>
</div>
</div>
<div class="layui-card card-common card-brief ">
<div class="layui-card-header">
<span class="card-title">第三方平台注册设置<a onclick="showDemo2()" class="examples text-color">查看示例</a></span>
</div>
<div class="layui-card-body">
<div class="desc text-color border-color bg-color-light-9">
第三方平台注册是指在微信公众号,微信小程序,支付宝小程序等平台下会员的注册方式.
</div>
<div class="layui-form-item">
<label class="layui-form-label ">允许三方平台自动注册:</label>
<div class="layui-input-block">
<input type="checkbox" name="third_party" value="1" lay-filter="third_party" lay-skin="switch" {if condition="isset($value.third_party) && $value.third_party == 1"} checked {/if} >
</div>
<div class="word-aux">第三方直接注册是指系统通过获取第三方的粉丝信息直接注册会员,会员用户名随机生成,昵称是第三方获取的用户昵称,注册过程中会将第三方平台获取的信息绑定到注册的会员,方便后期直接自动登录。若关闭,系统将按照普通注册方式注册会员。</div>
<div class="word-aux text-color">注∶第三方直接注册会员如果不强制绑定手机情况下会导致在不同第三方平台会员无法统一,如果只是在微信环境(微信公众号与微信小程序),可以通过绑定<a href="https://open.weixin.qq.com/" class="text-color" target="_blank">微信开放平台</a>获取unionid实现账户统一。</div>
</div>
<div class="layui-form-item {if $value.third_party neq 1}layui-hide{/if}" id="bindMobile">
<label class="layui-form-label ">是否强制绑定手机:</label>
<div class="layui-input-block">
<input type="checkbox" name="bind_mobile" value="1" lay-filter="bind_mobile" lay-skin="switch" {if condition="$value.bind_mobile == 1"} checked {/if} >
</div>
<div class="word-aux">为了实现不同的第三方平台用户账户的统一,需要在注册过程中强制绑定用户手机,通过手机实现微信平台与支付宝平台,抖音平台等账号的统一。开启之后在对应会员相关页面会引导会员绑定手机账号。</div>
<div class="word-aux">启用前需配置好“账户绑定”短信模板,<a href="{:href_url('shop/message/lists')}" class="text-color" >前去配置</a></div>
</div>
</div>
</div>
<div class="layui-card card-common card-brief">
<div class="layui-card-header">
<span class="card-title">密码设置</span>
</div>
<div class="layui-card-body">
<div class="layui-form-item">
<label class="layui-form-label ">密码最小长度:</label>
<div class="layui-input-block">
<input type="number" min="0" name="pwd_len" class="layui-input len-short" lay-verify="pwd_lens" value="{$value.pwd_len}">
</div>
<div class="word-aux">新用户注册时密码最小长度0或不填为不限制</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label ">密码复杂程度设置:</label>
<div class="layui-input-block" id="pwd_complexity">
<input type="checkbox" name="pwd_complexity" value="number" title="数字" lay-skin="primary" {if condition="!empty($value) && in_array('number', $value['pwd_complexity_arr'])"}checked{/if}>
<input type="checkbox" name="pwd_complexity" value="letter" title="小写字母" lay-skin="primary" {if condition="!empty($value) && in_array('letter', $value['pwd_complexity_arr'])"}checked{/if}>
<input type="checkbox" name="pwd_complexity" value="upper_case" title="大写字母" lay-skin="primary" {if condition="!empty($value) && in_array('upper_case', $value['pwd_complexity_arr'])"}checked{/if}>
<input type="checkbox" name="pwd_complexity" value="symbol" title="符号" lay-skin="primary" {if condition="!empty($value) && in_array('symbol', $value['pwd_complexity_arr'])"}checked{/if}>
</div>
<div class="word-aux">根据选项设置密码复杂程度,如果不勾选,则密码无限制</div>
</div>
</div>
</div>
<div class="layui-card card-common card-brief">
<div class="layui-card-header">
<span class="card-title">界面设置</span>
</div>
<div class="layui-card-body">
<div class="layui-form-item" >
<label class="layui-form-label ">是否显示政策协议:</label>
<div class="layui-input-block">
<input type="checkbox" name="agreement_show" value="1" lay-skin="switch" {if condition="$value.agreement_show == 1"} checked {/if} >
</div>
<div class="word-aux">注册与登录页面服务协议和隐私协议是否进行展示</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">手机端背景:</label>
<div class="layui-input-block img-upload">
<div class="upload-img-block">
<div class="upload-img-box {if condition="!empty($value.wap_bg)"}hover{/if} ">
<div class="upload-default" id="wap_bg_upload">
{if condition="!empty($value.wap_bg)"}
<div id="preview_wap_bg_upload" class="preview_img">
<img layer-src src="{:img($value.wap_bg)}" class="img_prev"/>
</div>
{else/}
<div class="upload">
<i class="iconfont iconshangchuan"></i>
<p>点击上传</p>
</div>
{/if}
</div>
<div class="operation">
<div>
<i title="图片预览" class="iconfont iconreview js-preview" style="margin-right: 20px;"></i>
<i title="删除图片" class="layui-icon layui-icon-delete js-delete"></i>
</div>
<div class="replace_img js-replace">点击替换</div>
</div>
<input type="hidden" name="wap_bg" value="{$value.wap_bg}"/>
</div>
</div>
</div>
<div class="word-aux">
<p>手机端统一登录页面使用。建议图片尺寸750*669像素图片格式jpg、png、jpeg</p>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">手机端描述语:</label>
<div class="layui-input-block">
<input type="text" name="wap_desc" autocomplete="off" value="{$value.wap_desc}" class="layui-input len-long">
</div>
<div class="word-aux"><p>手机端统一登录页面使用</p></div>
</div>
</div>
</div>
<div class="form-row">
<button type="button" class="layui-btn" lay-submit lay-filter="save">保存</button>
</div>
</div>
<script>
var repeat_flag = false; //防重复
layui.use(['form','carousel'], function() {
var form = layui.form;
var carousel = layui.carousel;
form.render();
new Upload({
elem: '#wap_bg_upload'
});
form.on('submit(save)', function(data) {
var pwd_complexity_array = [], register = [], login = [];
$("#pwd_complexity input:checked").each(function(){
pwd_complexity_array.push($(this).val())
})
$("[name='register']:checked").each(function(){
register.push($(this).val())
})
$("[name='login']:checked").each(function(){
login.push($(this).val())
})
if (login.length == 0){
layer.msg('请至少启用一种登录方式', {icon: 5})
return false;
}
data.field.register = register.toString();
data.field.login = login.toString();
data.field.pwd_complexity = pwd_complexity_array.toString();
if (repeat_flag) return;
repeat_flag = true;
$.ajax({
url: ns.url("shop/member/regConfig"),
data: data.field,
dataType: 'JSON',
type: 'POST',
success: function(res) {
layer.msg(res.message);
repeat_flag = false;
}
});
});
form.on('switch(third_party)', function(data) {
if($(data.elem).is(':checked')){
$('#bindMobile').removeClass('layui-hide');
} else {
$('#bindMobile').addClass('layui-hide');
}
});
/**
* 表单验证
*/
form.verify({
pwd_lens: function(value, item){
if(!new RegExp("^[0-9]*$").test(value)){
return '密码长度只能是正整数!';
}
}
});
});
function showDemo1(){
layer.open({
title: '查看示例',
type: 1,
area: ['700px', '660px'],
content: '<img style="margin:20px;" src="SHOP_IMG/reg_login.png">'
})
}
function showDemo2(){
layer.open({
title: '查看示例',
type: 1,
area: ['700px', '660px'],
content: '<img style="margin:20px;" src="SHOP_IMG/other_reglogin.png">'
})
}
</script>