【修复】订单分销兼容性

【修改】余额改消费券
【修改】兑换改兑换券
【增加】增加设置
This commit is contained in:
liqianjin 2023-02-17 09:29:05 +08:00
parent 680f1fbd6b
commit 50a1f3e9a4
173 changed files with 20116 additions and 1936 deletions

View File

@ -43,7 +43,7 @@ class BaleOrderCreate extends OrderCreate
private $is_virtual = 0; //是否是虚拟类订单
private $order_name = ''; //订单详情
private $goods_num = 0; //商品种数
private $balance_money = 0;//余额
private $balance_money = 0;//消费券
private $member_balance_money = 0;//会员账户余额(计算过程中会逐次减少)
private $pay_type = 'ONLINE_PAY';//支付方式
private $invoice_delivery_money = 0;

View File

@ -154,7 +154,7 @@
</div>
</div>
<div class="word-aux"><p>红包为储值余额,仅在消费时可用</p></div>
<div class="word-aux"><p>红包为储值消费券,仅在消费时可用</p></div>
</div>
<div class="coupon-wrap layui-hide">

View File

@ -157,7 +157,7 @@
</div>
</div>
<div class="word-aux"><p>红包为储值余额,仅在消费时可用</p></div>
<div class="word-aux"><p>红包为储值消费券,仅在消费时可用</p></div>
</div>
<div class="coupon-wrap {if !in_array('coupon', $info['type']) }layui-hide{/if}">

View File

@ -251,7 +251,7 @@ class BlindboxOrder extends BaseModel
{
$this->pay_type = "BALANCE";
$member_model = new Member();
$balance_money = $data[ "member_account" ][ "balance_money" ]; //现金余额
$balance_money = $data[ "member_account" ][ "balance_money" ]; //现金消费券
$balance = $data[ "member_account" ][ "balance" ]; //储值余额
$member_account_model = new MemberAccount();
$surplus_banance = $data[ "balance_money" ];

View File

@ -99,7 +99,7 @@ return [
],
[
'name' => 'member_modify_balance',
'title' => '调整余额',
'title' => '调整消费券',
'type' => 'api',
'url' => 'cashier/storeapi/member/modifybalance',
],

View File

@ -491,7 +491,7 @@ class CashierOrderPay extends BaseModel
);
$member_info = $member_model->getMemberInfo($member_condition)[ 'data' ] ?? [];
$member_balance = $member_info[ 'balance' ];//储值余额
$member_balance_money = $member_info[ 'balance_money' ];//现金余额
$member_balance_money = $member_info[ 'balance_money' ];//现金消费券
if ($balance_money > 0) {
$order_data = array ();
//优先扣除可不提现余额
@ -503,7 +503,7 @@ class CashierOrderPay extends BaseModel
$surplus -= $temp_balance;
$from_type = 'order';
$relate_tag = '余额抵扣';
$remark = '订单名称:' . $calculate_data[ 'order_name' ] . ',订单编号:' . $calculate_data[ 'out_trade_no' ] ?? '' . ',订单金额:' . $calculate_data[ 'order_money' ] . ',订单余额抵扣,扣除储值余额:' . $temp_balance;
$remark = '订单名称:' . $calculate_data[ 'order_name' ] . ',订单编号:' . $calculate_data[ 'out_trade_no' ] ?? '' . ',订单金额:' . $calculate_data[ 'order_money' ] . ',订单余额抵扣,扣除储值消费券:' . $temp_balance;
$remark = '收银订单余额抵扣';
if ($temp_balance > 0) {
$result = $member_account_model->addMemberAccount($site_id, $member_id, 'balance', -$temp_balance, $from_type, $relate_tag, $remark, $order_id);
@ -512,14 +512,14 @@ class CashierOrderPay extends BaseModel
}
$order_data[ 'balance' ] = $temp_balance;
}
//扣除现金余额
//扣除现金消费券
$temp_balance = $member_balance_money;
if ($member_balance_money > $surplus) {
$temp_balance = $surplus;
}
$from_type = 'order';
$relate_tag = '余额抵扣';
$remark = '订单名称:' . $calculate_data[ 'order_name' ] . ',订单编号:' . $calculate_data[ 'out_trade_no' ] . ',订单金额:' . $calculate_data[ 'order_money' ] . ',订单余额抵扣,扣除储值余额:' . $temp_balance;
$remark = '订单名称:' . $calculate_data[ 'order_name' ] . ',订单编号:' . $calculate_data[ 'out_trade_no' ] . ',订单金额:' . $calculate_data[ 'order_money' ] . ',订单余额抵扣,扣除储值消费券:' . $temp_balance;
$remark = '收银订单余额抵扣';
if ($temp_balance > 0) {
$result = $member_account_model->addMemberAccount($site_id, $member_id, 'balance_money', -$temp_balance, $from_type, $relate_tag, $remark, $order_id);

View File

@ -395,7 +395,7 @@
{/if}
{if $order_detail["balance_money"] > 0}
<div>
<p>余额<span>¥{$order_detail["balance_money"]}</span></p>
<p>消费券<span>¥{$order_detail["balance_money"]}</span></p>
</div>
{/if}

View File

@ -35,7 +35,7 @@
<view class="content-data">
<view class="content-data-item">
<view class="item-title">余额</view>
<view class="item-title">消费券</view>
<view class="item-value">{{ (parseFloat(info.balance_money) + parseFloat(info.balance)) | moneyFormat }}</view>
<view class="item-btn" @click="recharge()">充值</view>
</view>

View File

@ -32,13 +32,13 @@
<view class="data-item-action" @click="memberAction('point_list')">查看</view>
</view>
<view class="content-data-item">
<view class="data-item-title">储值余额()</view>
<view class="data-item-title">储值消费券()</view>
<view class="data-item-value">{{ memberInfo && memberInfo.balance ? memberInfo.balance : '0.00' }}</view>
<view class="data-item-action" @click="memberAction('balance_list')">查看</view>
<!-- <view class="data-item-action" v-if="memberInfo && memberInfo.balance > 0" @click="refundBalance">退储值</view> -->
</view>
<view class="content-data-item">
<view class="data-item-title">现金余额()</view>
<view class="data-item-title">现金消费券()</view>
<view class="data-item-value">{{ memberInfo && memberInfo.balance_money ? memberInfo.balance_money : '0.00' }}</view>
</view>
<view class="content-data-item">
@ -71,7 +71,7 @@
</view>
<view class="content-data-item" @click="memberAction('balance')">
<view class="data-item-icon"><image mode="aspectFit" :src="$util.img('public/uniapp/cashier/icon-member-balance.png')"></image></view>
<view class="data-item-value">余额充值</view>
<view class="data-item-value">消费券充值</view>
</view>
<view class="content-data-item" @click="memberAction('sendCoupon')">
<view class="data-item-icon"><image mode="aspectFit" :src="$util.img('public/uniapp/cashier/icon-member-coupon.png')"></image></view>
@ -252,11 +252,11 @@
</view>
</uni-popup>
<!-- 余额调整 -->
<!-- 消费券调整 -->
<uni-popup ref="balancePop">
<view class="pop-box pointPop-box">
<view class="pop-header">
<view class="pop-header-text">调整余额</view>
<view class="pop-header-text">调整消费券</view>
<view class="pop-header-close" @click="popClose('balance')"><i class="iconguanbi1 iconfont"></i></view>
</view>
@ -265,7 +265,7 @@
<view class="form-item">
<view class="form-label">
<text class="required"></text>
当前余额
当前消费券
</view>
<view class="form-inline">{{ memberInfo && memberInfo.balance ? memberInfo.balance : '0.00' }}</view>
</view>
@ -277,7 +277,7 @@
</view>
<view class="form-inline">
<input class="form-input" type="number" placeholder="请输入调整数额" v-model="balanceData.num" />
<view class="word-aux">调整数额与当前储值余额相加不能小于0</view>
<view class="word-aux">调整数额与当前储值消费券相加不能小于0</view>
</view>
</view>
@ -453,11 +453,11 @@
</view>
</uni-popup>
<!-- 余额列表 -->
<!-- 消费券列表 -->
<uni-popup ref="balanceListPop">
<view class="pop-box couponlistPop-box">
<view class="pop-header">
<view class="pop-header-text">余额</view>
<view class="pop-header-text">消费券</view>
<view class="pop-header-close" @click="popClose('balance_list')"><i class="iconguanbi1 iconfont"></i></view>
</view>
@ -627,7 +627,7 @@ export default {
},
{
width: 15,
title: '余额',
title: '消费券',
align: 'left',
field: 'account_data'
},
@ -1010,7 +1010,7 @@ export default {
}
});
},
//
//
saveBalance() {
this.$api.sendRequest({
url: '/cashier/storeapi/member/modifybalance',

View File

@ -34,7 +34,7 @@
<view class="content-data">
<view class="content-data-item">
<view class="item-title">余额</view>
<view class="item-title">消费券</view>
<view class="item-value">{{ (parseFloat(info.balance_money) + parseFloat(info.balance)) | moneyFormat }}</view>
<view class="item-btn" @click="recharge()">充值</view>
</view>

View File

@ -37,7 +37,7 @@
<view class="phone">手机号{{ item.mobile ? item.mobile : '--' }}</view>
<view class="other">
<!-- <view>类型小程序</view> -->
<view>余额{{ parseFloat(parseFloat(item.balance) + parseFloat(item.balance_money)).toFixed(2) }}</view>
<view>消费券{{ parseFloat(parseFloat(item.balance) + parseFloat(item.balance_money)).toFixed(2) }}</view>
</view>
</view>
</view>

View File

@ -23,7 +23,7 @@
</view>
<view class="head-info-bottom">
<view class="">积分{{ memberInfo.point }}</view>
<view class="">余额{{ (parseFloat(memberInfo.balance_money) + parseFloat(memberInfo.balance)) | moneyFormat }}</view>
<view class="">消费券{{ (parseFloat(memberInfo.balance_money) + parseFloat(memberInfo.balance)) | moneyFormat }}</view>
</view>
</view>

View File

@ -22,7 +22,7 @@
</view>
<view class="head-info-bottom">
<view class="">积分{{ memberInfo.point }}</view>
<view class="">余额{{ (parseFloat(memberInfo.balance_money) + parseFloat(memberInfo.balance)) | moneyFormat }}</view>
<view class="">消费券{{ (parseFloat(memberInfo.balance_money) + parseFloat(memberInfo.balance)) | moneyFormat }}</view>
</view>
</view>

View File

@ -34,7 +34,7 @@
<view class="item-desc">
<view>{{ item.mobile ? item.mobile : '' }}</view>
<view>
余额
消费券
<text>{{ parseFloat(parseFloat(item.balance) + parseFloat(item.balance_money)).toFixed(2) }}</text>
</view>
</view>

View File

@ -194,7 +194,7 @@ export default {
field: 'account_type_name'
}, {
width: 15,
title: '余额',
title: '消费券',
align: 'left',
field: 'account_data'
},

View File

@ -23,7 +23,7 @@
</view>
<view class="head-info-bottom">
<view class="">积分{{ memberInfo.point }}</view>
<view class="">余额{{ (parseFloat(memberInfo.balance_money) + parseFloat(memberInfo.balance)) | moneyFormat }}</view>
<view class="">消费券{{ (parseFloat(memberInfo.balance_money) + parseFloat(memberInfo.balance)) | moneyFormat }}</view>
</view>
</view>

View File

@ -262,7 +262,7 @@ class Member extends BaseStoreApi
}
/**
* 调整余额
* 调整消费券
*/
public function modifyBalance()
{

View File

@ -14,6 +14,8 @@ namespace addon\fenxiao\api\controller;
use app\api\controller\BaseApi;
use addon\fenxiao\model\FenxiaoOrder as FenxiaoOrderModel;
use addon\fenxiao\model\Fenxiao;
use think\Exception;
use think\facade\Log;
/**
* 分销订单
@ -112,4 +114,18 @@ class Order extends BaseApi
return $this->response($list);
}
public function testDaySettlement(){
return $this->response(event("DaySettlement"));
}
public function testOrderPay(){
try{
event("OrderPay",model('order')->getInfo([['order_id','=',220]]));
Log::debug('11111111111111111111111111111');
}catch(Exception $exception){
$this->response($exception->getMessage());
}
return $this->response([]);
}
}

View File

@ -80,6 +80,10 @@ return [
//统计写入
'AddStat' => [
'addon\fenxiao\event\AddStat',
],
//每日结算
'DaySettlement' => [
'addon\fenxiao\event\DaySettlement',
]
],

View File

@ -0,0 +1,30 @@
<?php
/**
* ThinkShop商城系统 - 团队十年电商经验汇集巨献!
* =========================================================
* Copy right 2019-2029 成都云之牛科技有限公司, 保留所有权利。
* ----------------------------------------------
* 官方网址: https://www.cdcloudshop.com
* =========================================================
*/
namespace addon\fenxiao\event;
use addon\fenxiao\model\FenxiaoOrder;
/**
* 每日结算
*/
class DaySettlement
{
/**
* 每日结算
* @param $param
*/
public function handle($param)
{
$fenxiao_order_model = new FenxiaoOrder();
return $fenxiao_order_model->daySettlement();
}
}

View File

@ -37,6 +37,15 @@ class Config extends BaseModel
'self_purchase_rebate' => $data['self_purchase_rebate'],//是否开启分销商自购返佣
'is_apply' => $data['is_apply'],//是否开启分销申请
'is_commission_money' => $data['is_commission_money'],//是否开启商品详情一级佣金
'newuser_points' => $data['newuser_points'],
'order_give_points_ratio' => $data['order_give_points_ratio'],
'order_give_contribution_ratio' => $data['order_give_contribution_ratio'],
'order_give_house_purchase_ratio' => $data['order_give_house_purchase_ratio'],
'order_give_a_points_ratio' => $data['order_give_a_points_ratio'],
'order_give_a_contribution_ratio' => $data['order_give_a_contribution_ratio'],
'order_give_d_points_ratio' => $data['order_give_d_points_ratio'],
'order_give_d_contribution_ratio' => $data['order_give_d_contribution_ratio'],
];
$config->setConfig($basics_data, '分销基本配置', $is_use, [['site_id', '=', $site_id], ['app_module', '=', 'shop'], ['config_key', '=', 'FENXIAO_BASICS_CONFIG']]);
//分销商设置

View File

@ -392,7 +392,7 @@ class Fenxiao extends BaseModel
if (!$count) return $this->error('', '未满足成为分销商的条件');
break;
}
return $this->directlyBecomeFenxiao($member_id);
return $this->directlyBecomeFenxiao($member_id, $basics_config);
} catch (\Exception $e) {
return $this->error();
}
@ -401,7 +401,7 @@ class Fenxiao extends BaseModel
/**
* 会员直接成为分销商
*/
private function directlyBecomeFenxiao($member_id)
private function directlyBecomeFenxiao($member_id, $config = [])
{
//获取用户信息
$member_field = 'member_id,site_id,source_member,fenxiao_id,nickname,headimg,mobile,reg_time,order_money,order_complete_money,order_num,order_complete_num';
@ -426,6 +426,9 @@ class Fenxiao extends BaseModel
'level_id' => $level_info[ 'data' ][ 'level_id' ],
'level_name' => $level_info[ 'data' ][ 'level_name' ]
];
if (isset($config['newuser_points']) && $config['newuser_points'] > 0) {//增加新用户积分
$data['points'] = $config['newuser_points'];
};
$res = $this->addFenxiao($data);
return $res;
}

View File

@ -21,6 +21,9 @@ class FenxiaoAccount extends BaseModel
public $type = [
'withdraw' => '提现',
'order' => '订单结算',
'points' => '积分',
'contribution' => '贡献值',
'house_purchase' => '购房券',
];
/**
@ -32,7 +35,7 @@ class FenxiaoAccount extends BaseModel
* @param $relate_id
* @return array
*/
public function addAccount($fenxiao_id, $fenxiao_name, $type = 'order', $money, $relate_id)
public function addAccount($fenxiao_id, $fenxiao_name, $type = 'order', $money, $relate_id, $from_type = 'account',$remarks='')
{
$account_no = date('YmdHi') . rand(1000, 9999);
$data = array(
@ -44,10 +47,11 @@ class FenxiaoAccount extends BaseModel
'type_name' => $this->type[$type],
'relate_id' => $relate_id,
'create_time' => time(),
'remarks' => $remarks,
);
$res = model('fenxiao_account')->add($data);
model('fenxiao')->setInc([['fenxiao_id', '=', $fenxiao_id]], 'account', $money);
model('fenxiao')->setInc([['fenxiao_id', '=', $fenxiao_id]], $from_type, $money);
return $this->success($res);
}
@ -87,7 +91,7 @@ class FenxiaoAccount extends BaseModel
* @param $relate_id
* @return array
*/
public function addAccountLog($fenxiao_id, $fenxiao_name, $type = 'order', $money, $relate_id)
public function addAccountLog($fenxiao_id, $fenxiao_name, $type = 'order', $money, $relate_id,$remarks='')
{
$account_no = date('YmdHi') . rand(1000, 9999);
$data = array(
@ -99,6 +103,7 @@ class FenxiaoAccount extends BaseModel
'type_name' => $this->type[$type],
'relate_id' => $relate_id,
'create_time' => time(),
'remarks' => $remarks,
);
$res = model('fenxiao_account')->add($data);
return $this->success($res);

View File

@ -11,14 +11,75 @@
namespace addon\fenxiao\model;
use app\model\BaseModel;
use app\model\member\MemberAccount;
use app\model\message\Message;
use app\model\system\Stat;
use think\facade\Log;
/**
* 分销商品
*/
class FenxiaoOrder extends BaseModel
{
/***
* 区域代理结算
* 月结
* @return array
*/
public function areaMonthlySettlement()
{
//本月
$beginThismonth = mktime(0, 0, 0, date('m'), 1, date('Y'));
$endThismonth = mktime(23, 59, 59, date('m'), date('t'), date('Y'));
//上月
$begin_time = strtotime(date('Y-m-01 00:00:00', strtotime('-1 month')));
$end_time = strtotime(date("Y-m-d 23:59:59", strtotime(-date('d') . 'day')));
$fenxiao = Db::name('fenxiao')->where([['is_area_agent', '=', 1],['status','=',1]])->column('fenxiao_id,site_id,member_id,fenxiao_name,agent_level_id,province_id,city_id,district_id,parent', 'fenxiao_id');
//获取分销基础配置
$config_model = new Config();
$fenxiao_basic_config = $config_model->getFenxiaoBasicsConfig(1);
$fenxiao_account = new FenxiaoAccount();
foreach ($fenxiao as $fenxiao_id => $item) {
$fenxiao_agent_level = Db::name('fenxiao_agent_level')->where('level_id', '=', $item['agent_level_id'])->field('type,flower_multiple,status')->find();
$where = [
['fo.create_time', 'BETWEEN', [$begin_time, $end_time]],
// ['fo.create_time', 'BETWEEN', [$beginThismonth, $endThismonth]],
['o.'.$fenxiao_agent_level['type'].'_id', '=', $item[$fenxiao_agent_level['type'].'_id']]
];
$fenxia_area_order_info = Db::name('fenxiao_order')
->alias('fo')
->join('order o','fo.order_id=o.order_id','LEFT')
->where($where)
->field('sum(real_goods_money) as real_goods_money')
->find();
$money = $fenxia_area_order_info['real_goods_money'] * $fenxiao_agent_level['flower_multiple']/100;
$fruit_num = $money * $fenxiao_basic_config['data']['value']['fruit_flower_rate'];
$account_model = new FenxiaoAccount();
//添加茶果
$udata = [
'flower_num' => Db::raw('flower_num -' . $money),
'fruit_num' => Db::raw('fruit_num +' . $fruit_num),
];
Db::name('fenxiao')->where([[ 'fenxiao_id', '=', $fenxiao_id ]])->update($udata);
$account_model->addAccountLog($fenxiao_id, $item['fenxiao_name'], 'fruit', $fruit_num, '', "代理奖励茶果-{$fruit_num}");
$account_model->addAccountLog($fenxiao_id, $item['fenxiao_name'], 'flower', '-' . $money, '', "茶花转茶果{$money}");
if($fenxiao_basic_config['data']['value']['agent_level_parent_rate'] > 0){
$money = $money * $fenxiao_basic_config['data']['value']['agent_level_parent_rate'] / 100;
$fruit_num = $money * $fenxiao_basic_config['data']['value']['fruit_flower_rate'];
//添加茶果
$udata = [
'flower_num' => Db::raw('flower_num -' . $money),
'fruit_num' => Db::raw('fruit_num +'.$fruit_num)
];
$fenxiaoParent = Db::name('fenxiao')->where('fenxiao_id','=',$item['parent'])->alias('fenxiao_name')->find();
Db::name('fenxiao')->where([['fenxiao_id','=',$item['parent']]])->update($udata);
$account_model->addAccountLog($item['parent'],$fenxiaoParent['fenxiao_name'],'fruit',$fruit_num,'',"推荐代理奖励茶果-{$fruit_num}");
$account_model->addAccountLog($item['parent'],$fenxiaoParent['fenxiao_name'], 'flower', '-' . $money, '', "茶花转茶果{$money}");
}
}
return $this->success();
}
/**
* 分销订单计算
@ -199,11 +260,85 @@ class FenxiaoOrder extends BaseModel
'three_fenxiao_name' => empty($grand_parent_fenxiao_info) ? '' : $grand_parent_fenxiao_info[ 'fenxiao_name' ],
'create_time' => time()
];
$this->orderGive($data);
model("fenxiao_order")->add($data);
}
// 分销商检测升级
event('FenxiaoUpgrade', $member_info[ 'fenxiao_id' ]);
return $this->success('Fenxiao');
}
/***
* 下单赠送
* @param $order
* @return array
*/
public function orderGive($order)
{
$id = model('fenxiao_account')->getValue([
'type' => 'points',
'relate_id' => $order['order_id'],
], 'id');//验证下单重复赠送
if (!$id) {
$i_fenxiao = model('fenxiao')->getInfo(['member_id' => $order['member_id'], 'site_id' => $order['site_id']], 'fenxiao_id,fenxiao_name,parent,grand_parent');
if ($i_fenxiao) {
$config_model = new Config();
$basic_config = $config_model->getFenxiaoBasicsConfig($order['site_id'])['data']['value'];
$fenxiao_account = new FenxiaoAccount();
$fenxiao_account->addAccount($i_fenxiao['fenxiao_id'], $i_fenxiao['fenxiao_name'], 'points', $order['real_goods_money'] * $basic_config['order_give_points_ratio'] /100, $order['order_id'],'points', '购物赠送积分');
$fenxiao_account->addAccount($i_fenxiao['fenxiao_id'], $i_fenxiao['fenxiao_name'], 'contribution', $order['real_goods_money'] * $basic_config['order_give_contribution_ratio'] /100, $order['order_id'],'contribution', '购物赠送贡献值');
$fenxiao_account->addAccount($i_fenxiao['fenxiao_id'], $i_fenxiao['fenxiao_name'], 'house_purchase', $order['real_goods_money'] * $basic_config['order_give_house_purchase_ratio'] /100, $order['order_id'],'house_purchase', '购物赠送购房券');
$parent_fenxiao['parent'] = $i_fenxiao['parent'];
for($i = 0;$i < 4;$i++){
if($parent_fenxiao['parent'] <= 0){
break;
}
$parent_fenxiao = model('fenxiao')->getInfo(['fenxiao_id' => $parent_fenxiao['parent']], 'fenxiao_id,fenxiao_name,parent,grand_parent');
if(!$parent_fenxiao){
break;
}
if($i == 0){
$fenxiao_account->addAccount($parent_fenxiao['fenxiao_id'], $parent_fenxiao['fenxiao_name'], 'points', $order['real_goods_money'] * $basic_config['order_give_a_points_ratio'] /100, $order['order_id'],'points', '用户下单分享A位置获赠积分');
$fenxiao_account->addAccount($parent_fenxiao['fenxiao_id'], $parent_fenxiao['fenxiao_name'], 'contribution', $order['real_goods_money'] * $basic_config['order_give_a_contribution_ratio'] /100, $order['order_id'],'contribution', '用户下单分享A位置获赠贡献值');
}
if($i == 3){
$fenxiao_account->addAccount($parent_fenxiao['fenxiao_id'], $parent_fenxiao['fenxiao_name'], 'points', $order['real_goods_money'] * $basic_config['order_give_d_points_ratio'] /100, $order['order_id'],'points', '用户下单分享D位置获赠积分');
$fenxiao_account->addAccount($parent_fenxiao['fenxiao_id'], $parent_fenxiao['fenxiao_name'], 'contribution', $order['real_goods_money'] * $basic_config['order_give_d_contribution_ratio'] /100, $order['order_id'],'contribution', '用户下单分享D位置获赠贡献值');
}
}
}
}
return $this->success();
}
/**
* 每日结算
* @return array
*/
public function daySettlement(){
$fenxiaoList = model('fenxiao')->getList([['status', '=', 1],['points', '>', 0]],'fenxiao_id,fenxiao_name,points,contribution,site_id,member_id');
$menber_account = new MemberAccount();
$fenxiao_account = new FenxiaoAccount();
foreach($fenxiaoList as $fenxiao){
$point_ratio = 0.5;//settlement_points_to_point_ratio
$balance_money_ratio = 0.5;//settlement_points_to_balance_money_ratio
$points_ratio = 0.0005;//no_contribution_points_ratio
if($fenxiao['contribution'] > 0){
$points_ratio = 0.001;//contribution_points_ratio
}
$points = $fenxiao['points'] * $points_ratio;
$point = $points * $point_ratio;
$balance_money = $points * $balance_money_ratio;
$menber_account->addMemberAccount($fenxiao[ 'site_id' ], $fenxiao['member_id'], 'point', $point, 'day_settlement', '每日转换', '每日转换');
$menber_account->addMemberAccount($fenxiao[ 'site_id' ], $fenxiao['member_id'], 'balance_money', $balance_money, 'day_settlement', '每日转换', '每日转换');
$fenxiao_account->addAccount($fenxiao['fenxiao_id'], $fenxiao['fenxiao_name'], 'points', -$points, 0,'points', '每日转换消耗');
if($fenxiao['contribution'] > 0){
$fenxiao_account->addAccount($fenxiao['fenxiao_id'],$fenxiao['fenxiao_name'],'contribution',-$points,0,'contribution','每日转换消耗');
}
}
return $this->success();
}

View File

@ -30,7 +30,7 @@ class FenxiaoWithdraw extends BaseModel
{
//提现类型
public $withdraw_type = [
'balance' => '余额',
'balance' => '消费券',
'weixin' => '微信',
'alipay' => '支付宝',
'bank' => '银行卡',
@ -45,7 +45,7 @@ class FenxiaoWithdraw extends BaseModel
public function getTransferType($site_id){
$pay_model = new Pay();
$transfer_type_list = $pay_model->getTransferType($site_id);
$transfer_type_list['balance'] = '余额';
$transfer_type_list['balance'] = '消费券';
return $transfer_type_list;
}
/**

View File

@ -49,6 +49,14 @@ class Config extends BaseShop
'one_rate' => input('one_rate', 0.00),
'two_rate' => input('two_rate', 0.00),
'three_rate' => input('three_rate', 0.00),
'newuser_points' => input('newuser_points', 0),
'order_give_points_ratio' => input('order_give_points_ratio', 0),
'order_give_contribution_ratio' => input('order_give_contribution_ratio', 0),
'order_give_house_purchase_ratio' => input('order_give_house_purchase_ratio', 0),
'order_give_a_points_ratio' => input('order_give_a_points_ratio', 0),
'order_give_a_contribution_ratio' => input('order_give_a_contribution_ratio', 0),
'order_give_d_points_ratio' => input('order_give_d_points_ratio', 0),
'order_give_d_contribution_ratio' => input('order_give_d_contribution_ratio', 0),
];
$res = $model->setFenxiaoBasicsConfig($data, 1, $this->site_id);
@ -152,7 +160,7 @@ class Config extends BaseShop
$fenxiao_withdraw_model = new FenxiaoWithdraw();
$transfer_type_list = $fenxiao_withdraw_model->getTransferType($this->site_id);
$transfer_type_list[ 'balance' ] = '余额';
$transfer_type_list[ 'balance' ] = '消费券';
$this->assign('transfer_type_list', $transfer_type_list);
$this->forthMenu();
return $this->fetch('config/settlement');

View File

@ -12,7 +12,86 @@
<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">
<div class="layui-input-inline">
<input type="number" name="newuser_points" class="layui-input ns-len-mid" value="{$basics_info.newuser_points??0}" />
</div>
</div>
<div class="word-aux ">新用户赠送积分</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">下单赠送积分:</label>
<div class="layui-input-block">
<div class="layui-input-inline">
<input type="number" name="order_give_points_ratio" class="layui-input ns-len-mid" value="{$basics_info.order_give_points_ratio??0}" />
</div>
<div class="layui-form-mid">%</div>
</div>
<div class="word-aux ">下单赠送积分,得消费额百分比</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">下单赠送贡献值:</label>
<div class="layui-input-block">
<div class="layui-input-inline">
<input type="number" name="order_give_contribution_ratio" class="layui-input ns-len-mid" value="{$basics_info.order_give_contribution_ratio??0}" />
</div>
<div class="layui-form-mid">%</div>
</div>
<div class="word-aux ">下单赠送贡献值,得消费额百分比</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">下单赠送购房券:</label>
<div class="layui-input-block">
<div class="layui-input-inline">
<input type="number" name="order_give_house_purchase_ratio" class="layui-input ns-len-mid" value="{$basics_info.order_give_house_purchase_ratio??0}" />
</div>
<div class="layui-form-mid">%</div>
</div>
<div class="word-aux ">下单赠送购房券,得消费额百分比</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">下单分享A位置得积分</label>
<div class="layui-input-block">
<div class="layui-input-inline">
<input type="number" name="order_give_a_points_ratio" class="layui-input ns-len-mid" value="{$basics_info.order_give_a_points_ratio??0}" />
</div>
<div class="layui-form-mid">%</div>
</div>
<div class="word-aux ">下单分享A位置得积分得消费额百分比</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">下单分享A位置得贡献值</label>
<div class="layui-input-block">
<div class="layui-input-inline">
<input type="number" name="order_give_a_contribution_ratio" class="layui-input ns-len-mid" value="{$basics_info.order_give_a_contribution_ratio??0}" />
</div>
<div class="layui-form-mid">%</div>
</div>
<div class="word-aux ">下单分享A位置得贡献值得消费额百分比</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">下单分享D位置得积分</label>
<div class="layui-input-block">
<div class="layui-input-inline">
<input type="number" name="order_give_d_points_ratio" class="layui-input ns-len-mid" value="{$basics_info.order_give_d_points_ratio??0}" />
</div>
<div class="layui-form-mid">%</div>
</div>
<div class="word-aux ">下单分享D位置得积分得消费额百分比</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">下单分享D位置得贡献值</label>
<div class="layui-input-block">
<div class="layui-input-inline">
<input type="number" name="order_give_d_contribution_ratio" class="layui-input ns-len-mid" value="{$basics_info.order_give_d_contribution_ratio??0}" />
</div>
<div class="layui-form-mid">%</div>
</div>
<div class="word-aux ">下单分享D位置得贡献值得消费额百分比</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">是否开启分销:</label>
<div class="layui-input-block">

View File

@ -379,12 +379,12 @@
}
}, {
field: 'balance',
title: '余额',
title: '消费券',
unresize: 'false',
width: '15%',
},{
field: 'point',
title: '积分',
title: '兑换券',
unresize: 'false',
width: '15%',
},

View File

@ -11,7 +11,7 @@ return [
'addon\form\event\ShowPromotion',
],
'OrderPayment' => [
'addon\form\event\OrderPayment',
//'addon\form\event\OrderPayment',
],
'OrderCreate' => [
'addon\form\event\OrderCreate',

View File

@ -25,8 +25,8 @@ class GiftCard extends BaseModel
private $account_content = [
'point' => [ 'relate_tag' => "兑换积分", 'remark' => "礼品卡兑换" ],
'growth' => [ 'relate_tag' => "兑换成长值", 'remark' => "礼品卡兑换" ],
'balance' => [ 'relate_tag' => "兑换储值余额", 'remark' => "礼品卡兑换" ],
'balance_meney' => [ 'relate_tag' => "兑换现金余额", 'remark' => "礼品卡兑换" ]
'balance' => [ 'relate_tag' => "兑换储值消费券", 'remark' => "礼品卡兑换" ],
'balance_meney' => [ 'relate_tag' => "兑换现金消费券", 'remark' => "礼品卡兑换" ]
];
private $goods_money = 0;//商品金额
private $balance_money = 0;//余额
@ -463,7 +463,7 @@ class GiftCard extends BaseModel
// $message = '优惠卷已领完';
// }
// }
//领取账户有关奖励 积分/成长值/储值余额/现金余额
//领取账户有关奖励 积分/成长值/储值余额/现金消费券
$member_account = [
'point' => $carmichael_record_info[ 'point' ],
'balance' => $carmichael_record_info[ 'balance' ],
@ -567,7 +567,7 @@ class GiftCard extends BaseModel
// $message = '优惠卷已领完';
// }
// }
//领取账户有关奖励 积分/成长值/储值余额/现金余额
//领取账户有关奖励 积分/成长值/储值余额/现金消费券
$member_account = [
'point' => $carmichael_record_info[ 'point' ],
'balance' => $carmichael_record_info[ 'balance' ],
@ -935,7 +935,7 @@ class GiftCard extends BaseModel
// $result = $member_model->checkPayPassword($data["member_id"], $data["pay_password"]);
// if ($result["code"] >= 0) {
$balance_money = $data[ "member_account" ][ "balance_money" ]; //现金余额
$balance_money = $data[ "member_account" ][ "balance_money" ]; //现金消费券
$balance = $data[ "member_account" ][ "balance" ]; //储值余额
$member_account_model = new MemberAccount();
$surplus_banance = $data[ "balance_money" ];

View File

@ -170,7 +170,7 @@
<!--储值-->
<div id="real-balance" class="layui-show">
<div class="layui-form-item">
<label class="layui-form-label">储值余额</label>
<label class="layui-form-label">储值消费券</label>
<div class="layui-input-inline">
<input type="number" min="0" name="balance" onchange="detectionNumType(this,'positiveNumber')" class="layui-input len-short" autocomplete="off" value="0">
</div>

View File

@ -74,7 +74,7 @@
</div>
{if $detail.card_right_type=='balance'}
<div class="promotion-view-item">
<label>储值余额</label>
<label>储值消费券</label>
<span>{$detail.balance}元</span>
</div>
{/if}
@ -164,7 +164,7 @@
<p>礼品卡持卡人兑换时可从按照商品列表中商品数量进行兑换。</p>
{/if}
{else/}
<p>礼品卡持卡人兑换时将储值卡的储值余额充值到持卡人账户余额中</p>
<p>礼品卡持卡人兑换时将储值卡的储值消费券充值到持卡人账户余额中</p>
{/if}
</div>
</div>

View File

@ -135,7 +135,7 @@
<!--储值-->
<div id="card_right_type_balance" class="{if $giftcard_info.card_right_type == 'balance'} layui-show {else/} layui-hide {/if}">
<div class="layui-form-item">
<label class="layui-form-label">储值余额</label>
<label class="layui-form-label">储值消费券</label>
<div class="layui-input-inline">
<input type="number" min="0" name="balance" onchange="detectionNumType(this,'positiveNumber')" class="layui-input len-short" autocomplete="off" value="{$giftcard_info.balance}">
</div>

View File

@ -442,12 +442,12 @@ class Hongbao extends BaseModel
$user_model = new User();
if($data['balance_set'] == 1){
#奖励不可提现余额
$member_account_model->addMemberAccount($data['site_id'], $data['member_id'], 'balance', $data['money'], 'hongbao', 0, '裂变红包发放,不可提现余额:' . $data['money'],$launch_id);
$member_account_model->addMemberAccount($data['site_id'], $data['member_id'], 'balance', $data['money'], 'hongbao', 0, '裂变红包发放,不可提现消费券:' . $data['money'],$launch_id);
}else{
#奖励可提现余额
$member_account_model->addMemberAccount($data['site_id'], $data['member_id'], 'balance_money', $data['money'], 'hongbao', 0, '裂变红包发放,可提现余额:' . $data['money'],$launch_id);
$member_account_model->addMemberAccount($data['site_id'], $data['member_id'], 'balance_money', $data['money'], 'hongbao', 0, '裂变红包发放,可提现消费券:' . $data['money'],$launch_id);
}
$user_model->addUserLog($data['uid'], $data['username'], $data['site_id'], "裂变红包:会员余额调整id:" . $data['member_id'] . "金额" . $data['money']);
$user_model->addUserLog($data['uid'], $data['username'], $data['site_id'], "裂变红包:会员消费券调整id:" . $data['member_id'] . "金额" . $data['money']);
$hongbao_group = model('promotion_hongbao_group')->getInfo(
[

View File

@ -0,0 +1,349 @@
<?php
/**
* SAAS应用系统 --- 十年开发经验汇集巨献!
* ==========================================================
* Copy right 2020-2050 成都众联思索科技有限公司,保留所有权利。
* ----------------------------------------------------------
* 官方网址: https://www.zoomtk.com
* 这不是自由软件!未经允许不得用于商业目或程序代码摘取及修改。
* 任何企业和个人不允许对程序代码以任何形式任何目的再发布传播。
* 唯一发布渠道www.zoomtk.com;非官方渠道统一视为侵权行为。
* ==========================================================
*/
namespace addon\member\api\controller;
use addon\member\model\Login as LoginModel;
use app\model\message\Message;
use addon\member\model\Register as RegisterModel;
use Exception;
use think\facade\Cache;
use addon\member\model\Config as ConfigModel;
use app\model\web\Config;
use app\api\controller\BaseApi;
use app\api\controller\Captcha;
use think\facade\Session;
class Login extends BaseApi
{
/**
* 账号密码登录
*/
public function login()
{
$config = new ConfigModel();
$config_info = $config->getRegisterConfig($this->site_id, 'shop');
if (strstr($config_info['data']['value']['login'], 'username') === false) return $this->response($this->error([], "用户名登录未开启!"));
// $auth_info = Session::get("auth_info");
// if (!empty($auth_info)) {
// $this->params = array_merge($this->params, $auth_info);
// }
// 校验验证码
$config_model = new Config();
$info = $config_model->getCaptchaConfig();
if($info['data']['value']['shop_reception_login'] == 1){
$captcha = new Captcha();
$check_res = $captcha->checkCaptcha();
if ($check_res['code'] < 0) return $this->response($check_res);
}
// 登录
$login = new LoginModel();
if (empty($this->params["password"]))
return $this->response($this->error([], "密码不可为空!"));
$res = $login->login($this->params);
//生成access_token
if ($res['code'] >= 0) {
$token = $this->createToken($res['data']['member_id']);
return $this->response($this->success(['token' => $token]));
}
return $this->response($res);
}
/***
* 第三方登录
* @return array|string|void
*/
public function third_login()
{
$login=new LoginModel();
switch (input('app_type')) {
case 'wechat': //微信公众号
$appType=input('app_type', 'wechat');
$wechat = new \addon\wechat\model\Wechat($this->site_id, $appType);
$weInfo = $wechat->getAuthByCode($this->params);
if($weInfo['code']>=0){
$res=$login->ThirdLogin(array_merge($this->params,$weInfo['data']),$this->site_id);
}else{
return $this->response($this->error($weInfo));
}
break;
case 'weapp'://小程序登录
$appType=input('app_type', 'weapp');
$wechat = new \addon\weapp\model\Weapp($this->site_id, $appType);
$res = $wechat->authCodeToOpenid($this->params);
// $res['data']['openid']='66666666';
// $this->params['source_member']=1;
if($res['code']==0){
$res=$login->ThirdLogin(array_merge($this->params,$res['data']),$this->site_id);
}
break;
case 'toutiao': //抖音头条
$appType=input('app_type', 'toutiao');
$code=input('code');
$toutiao=new \addon\toutiao\model\Toutiao(request()->siteid(), $appType);
$info=$toutiao->getSession($code);
$res=$login->ThirdLogin(array_merge($this->params,$info['data']),$this->site_id);
break;
case 'qq':
$qq_model = new QqminCode($this->params['site_id']);
break;
case 'aliapp':
$memberInfo = [
'openid' => time()
];
break;
default:
$memberInfo = [];
}
if(empty($res['code'])){
$memberInfo['token']=$this->createToken($res['member_id']);
$memberInfo['userInfo']=$res;
if (isset($res['is_register'])) $memberInfo['is_register'] = 1;
return $this->response($this->success($memberInfo));
}else{
return $this->response($this->error($res));
}
}
/**
* 手机号授权登录
*/
public function mobileAuth()
{
$decrypt_data = event('DecryptData', $this->params, true);
if ($decrypt_data[ 'code' ] < 0) return $this->response($decrypt_data);
$this->params[ 'mobile' ] = $decrypt_data[ 'data' ][ 'purePhoneNumber' ];
$register = new RegisterModel();
$exist = $register->mobileExist($this->params[ "mobile" ], $this->site_id);
if ($exist) {
$login = new LoginModel();
$res = $login->mobileLogin($this->params);
if ($res[ 'code' ] >= 0) {
$token = $this->createToken($res[ 'data' ][ 'member_id' ]);
$res = $this->success([ 'token' => $token ]);
}
} else {
$res = $register->mobileRegister($this->params);
if ($res[ 'code' ] >= 0) {
$token = $this->createToken($res[ 'data' ]);
$res = $this->success([ 'token' => $token, 'is_register' => 1 ]);
}
}
return $this->response($res);
}
/**
* 第三方登录
*/
public function auth()
{
$login = new LoginModel();
$res = $login->authLogin($this->params);
//生成access_token
if ($res['code'] >= 0) {
$token = $this->createToken($res['data']['member_id']);
$data = [
'token' => $token
];
if (isset($res['data']['is_register'])) $data['is_register'] = 1;
return $this->response($this->success($data));
}
return $this->response($res);
}
/**
* 检测openid是否存在
*/
public function openidIsExits()
{
$login = new LoginModel();
$res = $login->openidIsExits($this->params);
return $this->response($res);
}
/**
* 手机动态码登录
*/
public function mobile()
{
$config = new ConfigModel();
$config_info = $config->getRegisterConfig($this->site_id, 'shop');
if (strstr($config_info['data']['value']['login'], 'mobile') === false) return $this->response($this->error([], "动态码登录未开启!"));
$key = $this->params['key'];
$verify_data = Cache::get($key);
if ($verify_data["mobile"] == $this->params["mobile"] && $verify_data["code"] == $this->params["code"]) {
$register = new RegisterModel();
$exist = $register->mobileExist($this->params["mobile"], $this->site_id);
if ($exist) {
$login = new LoginModel();
$res = $login->mobileLogin($this->params);
if ($res['code'] >= 0) {
$token = $this->createToken($res['data']['member_id']);
$res = $this->success(['token' => $token]);
}
} else {
$res = $this->error("", "该手机号未注册");
}
} else {
$res = $this->error("", "手机动态码不正确");
}
return $this->response($res);
}
/**
* 获取手机号登录验证码
* @throws Exception
*/
public function mobileCode()
{
// 校验验证码
$config_model = new Config();
$info = $config_model->getCaptchaConfig();
if($info['data']['value']['shop_reception_login'] == 1){
$captcha = new Captcha();
$check_res = $captcha->checkCaptcha(false);
if ($check_res['code'] < 0) return $this->response($check_res);
}
$mobile = $this->params['mobile'];
if (empty($mobile)) return $this->response($this->error([], "手机号不可为空!"));
$mobile_code='login_mobile_code_'.$mobile;
if(Cache::get($mobile_code)) return $this->response($this->error("", "重复发送请稍后再试"));
$register = new RegisterModel();
$exist = $register->mobileExist($this->params["mobile"], $this->site_id);
if (!$exist) return $this->response($this->error([], "该手机号未注册!"));
$code = str_pad(random_int(1, 9999), 4, 0, STR_PAD_LEFT);// 生成4位随机数左侧补0
$message_model = new Message();
$res = $message_model->sendMessage(["mobile" => $mobile, "site_id" => $this->site_id, "support_type" => ['sms'], "code" => $code, "keywords" => "LOGIN_CODE"]);
if ($res["code"] >= 0) {
//将验证码存入缓存
$key = 'login_mobile_code_' . md5(uniqid(null, true));
Cache::tag("login_mobile_code")->set($key, ['mobile' => $mobile, 'code' => $code], 600);
Cache::tag("login_mobile_code")->set('login_mobile_code_'.$mobile, time(), 600);
return $this->response($this->success(["key" => $key]));
} else {
return $this->response($res);
}
}
/**
* 获取第三方首次扫码登录绑定/注册手机号码验证码 手机号码存不存在都可以发送 新增2021.06.18
* captcha_id 验证码id
* captcha_code 验证码
* mobile 手机号码
*/
public function getMobileCode()
{
// 校验验证码 start
$captcha = new Captcha();
$check_res = $captcha->checkCaptcha(false);
if ($check_res['code'] < 0) return $this->response($check_res);
// 校验验证码 end
$mobile = $this->params['mobile'];
if (empty($mobile)) return $this->response($this->error([], "手机号不可为空!"));
$register = new RegisterModel();
$exist = $register->mobileExist($this->params["mobile"], $this->site_id);
//判断该手机号码是否已绑定wx_openid
// $opneid_exist = $register->openidExist($this->params["mobile"], $this->site_id);
// if ($opneid_exist) return $this->response($this->error([], "该手机号已绑定其他微信公众号!"));
if ($exist){
$keywords = 'LOGIN_CODE';
}else{
$keywords = 'REGISTER_CODE';
}
$code = str_pad(random_int(1, 9999), 4, 0, STR_PAD_LEFT);// 生成4位随机数左侧补0
$message_model = new Message();
$res = $message_model->sendMessage(["mobile" => $mobile, "site_id" => $this->site_id, "support_type" => ['sms'], "code" => $code, "keywords" => $keywords]);
// $code = 8888;// 生成4位随机数左侧补0
// $res["code"]=0;
if ($res["code"] >= 0) {
// if ($res["code"]) {
//将验证码存入缓存
$key = 'login_mobile_code_' . md5(uniqid(null, true));
Cache::tag("login_mobile_code")->set($key, ['mobile' => $mobile, 'code' => $code], 600);
return $this->response($this->success(["key" => $key]));
// return $this->response($this->success(["key" => $key,"code"=>$code]));
} else {
return $this->response($res);
}
}
/**
* 验证token有效性
*/
public function verifyToken(){
$token = $this->checkToken();
if ($token['code'] < 0) return $this->response($token);
return $this->response($this->success());
}
/**
* 检测登录
* @return false|string
*/
public function checkLogin()
{
$key = $this->params[ 'key' ];
$cache = Cache::get('wechat_' . $key);
if (!empty($cache)) {
if (isset($cache[ 'openid' ]) && !empty($cache[ 'openid' ])) {
$login = new LoginModel();
$data = [
'wx_openid' => $cache[ 'openid' ],
'site_id' => $this->site_id
];
$is_exits = $login->openidIsExits($data);
if ($is_exits[ 'data' ]) {
// 存在即登录
$res = $login->authLogin($data);
//生成access_token
if ($res[ 'code' ] >= 0) {
$token = $this->createToken($res[ 'data' ][ 'member_id' ]);
// Session::set($this->params[ 'app_type' ] . "_token_" . $this->site_id, $token);
// Session::set($this->params[ 'app_type' ] . "_member_id_" . $this->site_id, $res[ 'data' ][ 'member_id' ]);
return $this->response($this->success([ 'token' => $token ]));
}
return $this->response($res);
} else {
// 将openid存入session
Session::set("auth_info",[
'wx_openid'=>$cache['openid'],
'nickname'=>$cache['nickname'],
'headimg'=>$cache['headimgurl']
]);
Cache::set('wechat_' . $key, null);
return $this->response($this->success());
}
} elseif (time() > $cache[ 'expire_time' ]) {
Cache::set('wechat_' . $key, null);
return $this->response($this->error('', '已失效'));
} else {
return $this->response($this->error('', 'no login'));
}
} else {
return $this->response($this->error('', '已失效'));
}
}
}

View File

@ -0,0 +1,483 @@
<?php
/**
* SAAS应用系统 --- 十年开发经验汇集巨献!
* ==========================================================
* Copy right 2020-2050 成都众联思索科技有限公司,保留所有权利。
* ----------------------------------------------------------
* 官方网址: https://www.zoomtk.com
* 这不是自由软件!未经允许不得用于商业目或程序代码摘取及修改。
* 任何企业和个人不允许对程序代码以任何形式任何目的再发布传播。
* 唯一发布渠道www.zoomtk.com;非官方渠道统一视为侵权行为。
* ==========================================================
*/
namespace addon\member\api\controller;
use addon\member\model\Member as MemberModel;
use addon\member\model\MemberAccount;
use addon\member\model\Register as RegisterModel;
use addon\member\model\MemberLevel as MemberLevelModel;
use app\model\message\Message;
use think\facade\Cache;
use extend\QRcode as QRcodeExtend;
use app\api\controller\BaseApi;
use think\facade\Db;
class Member extends BaseApi
{
/**
* 基础信息
*/
public function info()
{
$token = $this->checkToken();
if ($token['code'] < 0) return $this->response($token);
$member_model = new MemberModel();
$info = $member_model->getMemberInfo([['member_id', '=', $token['data']['member_id'], ['site_id', '=', $this->site_id]]], 'member_id,source_member,username,nickname,mobile,email,password,status,headimg,member_level,member_level_name,member_label,member_label_name,qq,realname,sex,location,birthday,point,balance,balance_money,growth,sign_days_series,password,member_level_type,level_expire_time,is_edit_username,is_fenxiao,rcode');
if (!empty($info['data'])) {
$info['data']['nickname']=emojiDecode($info['data']['nickname']);
$info['data']['password'] = empty($info['data']['password']) ? 0 : 1;
$member_level_model = new MemberLevelModel();
$member_level_result = $member_level_model->getMemberLevelInfo([['level_id', '=', $info['data']['member_level']]]);
$member_level = $member_level_result['data'] ?? [];
$info['data']['member_level_info'] = $member_level;
}
return $this->response($info);
}
/**
* 修改会员头像
* @return string
*/
public function modifyheadimg()
{
$token = $this->checkToken();
if ($token['code'] < 0) return $this->response($token);
$headimg = isset($this->params['headimg']) ? $this->params['headimg'] : '';
$member_model = new MemberModel();
$res = $member_model->editMember(['headimg' => $headimg], [['member_id', '=', $token['data']['member_id'], ['site_id', '=', $this->site_id]]]);
return $this->response($res);
}
/**
* 修改用户名
* @return false|string
*/
public function modifyUsername(){
$token = $this->checkToken();
if ($token['code'] < 0) return $this->response($token);
$username = isset($this->params['username']) ? $this->params['username'] : '';
$member_model = new MemberModel();
$res = $member_model->editUsername($this->member_id, $this->site_id, $username);
return $this->response($res);
}
/**
* 修改昵称
* @return string
*/
public function modifynickname()
{
$token = $this->checkToken();
if ($token['code'] < 0) return $this->response($token);
$nickname = isset($this->params['nickname']) ? $this->params['nickname'] : '';
$member_model = new MemberModel();
$res = $member_model->editMember(['nickname' => $nickname], [['member_id', '=', $token['data']['member_id'], ['site_id', '=', $this->site_id]]]);
return $this->response($res);
}
/**
* 修改手机号
* @return string
*/
public function modifymobile()
{
$token = $this->checkToken();
if ($token['code'] < 0) return $this->response($token);
// 校验验证码
$captcha = new Captcha();
$check_res = $captcha->checkCaptcha(false);
if ($check_res['code'] < 0) return $this->response($check_res);
$register = new RegisterModel();
$exist = $register->mobileExist($this->params['mobile'], $this->site_id);
if ($exist) {
return $this->response($this->error("", "手机号已存在"));
} else {
$key = $this->params['key'];
$verify_data = Cache::get($key);
if ($verify_data["mobile"] == $this->params["mobile"] && $verify_data["code"] == $this->params["code"]) {
$mobile = isset($this->params['mobile']) ? $this->params['mobile'] : '';
$member_model = new MemberModel();
$res = $member_model->editMember(['mobile' => $mobile], [['member_id', '=', $token['data']['member_id'], ['site_id', '=', $this->site_id]]]);
} else {
$res = $this->error("", "验证码不正确");
}
return $this->response($res);
}
}
/**
* 修改密码
* @return string
*/
public function modifypassword()
{
$token = $this->checkToken();
if ($token['code'] < 0) return $this->response($token);
$old_password = isset($this->params['old_password']) ? $this->params['old_password'] : '';
$new_password = isset($this->params['new_password']) ? $this->params['new_password'] : '';
$member_model = new MemberModel();
$info = $member_model->getMemberInfo([['member_id', '=', $token['data']['member_id'], ['site_id', '=', $this->site_id]]], 'password');
// 未设置密码时设置密码需验证身份
if (empty($info['data']['password'])) {
$key = $this->params['key'] ?? '';
$code = $this->params['code'] ?? '';
$verify_data = Cache::get($key);
if (empty($verify_data) || $verify_data["code"] != $code) {
return $this->response($this->error("", "手机验证码不正确"));
}
}
$res = $member_model->modifyMemberPassword($token['data']['member_id'], $old_password, $new_password);
return $this->response($res);
}
/**
* 绑定短信验证码
*/
public function bindmobliecode()
{
// 校验验证码
$captcha = new Captcha();
$check_res = $captcha->checkCaptcha(false);
if ($check_res['code'] < 0) return $this->response($check_res);
$mobile = $this->params['mobile'];//注册手机号
$register = new RegisterModel();
$exist = $register->mobileExist($mobile, $this->site_id);
if ($exist) {
return $this->response($this->error("", "当前手机号已存在"));
} else {
$code = str_pad(random_int(1, 9999), 4, 0, STR_PAD_LEFT);// 生成4位随机数左侧补0
$message_model = new Message();
$res = $message_model->sendMessage(["mobile" => $mobile, "site_id" => $this->site_id, "code" => $code, "support_type" => ["sms"], "keywords" => "MEMBER_BIND"]);
if ($res["code"] >= 0) {
//将验证码存入缓存
$key = 'bind_mobile_code_' . md5(uniqid(null, true));
Cache::tag("bind_mobile_code")->set($key, ['mobile' => $mobile, 'code' => $code], 600);
return $this->response($this->success(["key" => $key]));
} else {
return $this->response($res);
}
}
}
/**
* 设置密码时获取验证码
*/
public function pwdmobliecode()
{
$token = $this->checkToken();
if ($token['code'] < 0) return $this->response($token);
// 校验验证码
$captcha = new Captcha();
$check_res = $captcha->checkCaptcha(false);
if ($check_res['code'] < 0) return $this->response($check_res);
$member_model = new MemberModel();
$info = $member_model->getMemberInfo([['member_id', '=', $token['data']['member_id'], ['site_id', '=', $this->site_id]]], 'mobile');
if (empty($info['data'])) return $this->response($this->error([], '未获取到会员信息!'));
if (empty($info['data']['mobile'])) return $this->response($this->error([], '会员信息尚未绑定手机号!'));
$mobile = $info['data']['mobile'];
$code = str_pad(random_int(1, 9999), 4, 0, STR_PAD_LEFT);// 生成4位随机数左侧补0
$message_model = new Message();
$res = $message_model->sendMessage(["mobile" => $mobile, "site_id" => $this->site_id, "code" => $code, "support_type" => ["sms"], "keywords" => "SET_PASSWORD"]);
if (isset($res["code"]) && $res["code"] >= 0) {
//将验证码存入缓存
$key = 'password_mobile_code_' . md5(uniqid(null, true));
Cache::tag("password_mobile_code_")->set($key, ['mobile' => $mobile, 'code' => $code], 600);
return $this->response($this->success(["key" => $key, 'code' => $code]));
} else {
return $this->response($this->error('', '发送失败'));
}
}
/**
* 验证手机号
* @return string
*/
public function checkmobile()
{
$mobile = isset($this->params['mobile']) ? $this->params['mobile'] : '';
if (empty($mobile)) {
return $this->response($this->error('', 'REQUEST_MOBILE'));
}
$member_model = new MemberModel();
$condition = [
['mobile', '=', $mobile],
['site_id', '=', $this->site_id]
];
$res = $member_model->getMemberCount($condition);
if ($res['data'] > 0) {
return $this->response($this->error('', '当前手机号已存在'));
}
return $this->response($this->success());
}
/**
* 修改支付密码
* @return string
*/
public function modifypaypassword()
{
$token = $this->checkToken();
if ($token['code'] < 0) return $this->response($token);
$key = $this->params['key'] ?? '';
$code = $this->params['code'] ?? '';
$password = isset($this->params['password']) ? trim($this->params['password']) : '';
if (empty($password)) return $this->response($this->error('', '支付密码不可为空'));
$verify_data = Cache::get($key);
if ($verify_data["code"] == $this->params["code"]) {
$member_model = new MemberModel();
$res = $member_model->modifyMemberPayPassword($token['data']['member_id'], $password);
} else {
$res = $this->error("", "验证码不正确");
}
return $this->response($res);
}
/**
* 检测会员是否设置支付密码
*/
public function issetpayaassword()
{
$token = $this->checkToken();
if ($token['code'] < 0) return $this->response($token);
$member_model = new MemberModel();
$res = $member_model->memberIsSetPayPassword($this->member_id);
return $this->response($res);
}
/**
* 检测支付密码是否正确
*/
public function checkpaypassword()
{
$token = $this->checkToken();
if ($token['code'] < 0) return $this->response($token);
$password = isset($this->params['pay_password']) ? trim($this->params['pay_password']) : '';
if (empty($password)) return $this->response($this->error('', '支付密码不可为空'));
$member_model = new MemberModel();
$res = $member_model->checkPayPassword($this->member_id, $password);
return $this->response($res);
}
/**
*
* 修改支付密码发送手机验证码
*/
public function paypwdcode()
{
$token = $this->checkToken();
if ($token['code'] < 0) return $this->response($token);
$code = str_pad(random_int(1, 9999), 4, 0, STR_PAD_LEFT);// 生成4位随机数左侧补0
$message_model = new Message();
$res = $message_model->sendMessage(["member_id" => $this->member_id, "site_id" => $this->site_id, "code" => $code, "support_type" => ["sms"], "keywords" => "MEMBER_PAY_PASSWORD"]);
if ($res["code"] >= 0) {
//将验证码存入缓存
$key = 'pay_password_code_' . md5(uniqid(null, true));
Cache::tag("pay_password_code")->set($key, ['member_id' => $this->member_id, 'code' => $code], 600);
return $this->response($this->success(["key" => $key]));
} else {
return $this->response($res);
}
}
/**
* 验证修改支付密码动态码
*/
public function verifypaypwdcode()
{
$key = isset($this->params['key']) ? trim($this->params['key']) : '';
$verify_data = Cache::get($key);
if ($verify_data["code"] == $this->params["code"]) {
$res = $this->success([]);
} else {
$res = $this->error("", "验证码不正确");
}
return $this->response($res);
}
/**
* 通过token得到会员id
*/
public function id()
{
$token = $this->checkToken();
if ($token['code'] < 0) return $this->response($token);
return $this->response($this->success($this->member_id));
}
/**
* 账户奖励规则说明
* @return false|string
*/
public function accountrule()
{
//积分
$point = event('MemberAccountRule', ['account' => 'point', 'site_id' => $this->site_id]);
//消费券
$balance = event('MemberAccountRule', ['account' => 'balance', 'site_id' => $this->site_id]);
//成长值
$growth = event('MemberAccountRule', ['account' => 'growth', 'site_id' => $this->site_id]);
$res = [
'point' => $point,
'balance' => $balance,
'growth' => $growth
];
return $this->response($this->success($res));
}
/**
* 拉取会员头像
*/
public function pullheadimg()
{
$member_id = input('member_id', '');
$member = new MemberModel();
$member->pullHeadimg($member_id);
}
/**
* 修改真实姓名
*/
public function modifyrealname()
{
$token = $this->checkToken();
if ($token['code'] < 0) return $this->response($token);
$realname = isset($this->params['realname']) ? $this->params['realname'] : '';
$member_model = new MemberModel();
$res = $member_model->editMember(['realname' => $realname], [['member_id', '=', $token['data']['member_id'], ['site_id', '=', $this->site_id]]]);
return $this->response($res);
}
/**
* 修改性别
*/
public function modifysex()
{
$token = $this->checkToken();
if ($token['code'] < 0) return $this->response($token);
$sex = isset($this->params['sex']) ? $this->params['sex'] : 0;
$member_model = new MemberModel();
$res = $member_model->editMember(['sex' => $sex], [['member_id', '=', $token['data']['member_id'], ['site_id', '=', $this->site_id]]]);
return $this->response($res);
}
/**
* 修改生日
*/
public function modifybirthday()
{
$token = $this->checkToken();
if ($token['code'] < 0) return $this->response($token);
$birthday = isset($this->params['birthday']) ? $this->params['birthday'] : '';
$member_model = new MemberModel();
$res = $member_model->editMember(['birthday' => $birthday], [['member_id', '=', $token['data']['member_id'], ['site_id', '=', $this->site_id]]]);
return $this->response($res);
}
/**
* 生成会员二维码
*/
public function membereqrcode()
{
$token = $this->checkToken();
if ($token['code'] < 0) return $this->response($token);
$member_id = $token['data']['member_id'];
$number = date_to_time(date('Y-m-d H:i')).rand(10000000,99999999);
// 二维码
$qrcode_dir = 'upload/qrcode/qrcodereduceaccount';
if (!is_dir($qrcode_dir) && !mkdir($qrcode_dir, intval('0755', 8), true)) {
return $this->error('', '会员码生成失败');
}
$qrcode_name = 'memberqrcode_' . $member_id . '_' . $this->site_id;
$filename = $qrcode_dir . '/' . $qrcode_name . '_' . $this->params['app_type'] . '.png';
QRcodeExtend::png($number, $filename, 'L', 4, 1);
$res = $this->success(['path' => $filename]);
Cache::tag('member_qrcode')->set($number,['member_id'=>$member_id,'is_user'=>0],'60');
// 条形码
Cache::tag('memberqrcode')->set($number,['member_id'=>$member_id,'is_user'=>0],'60');
$bar_code = getBarcode($number);
$res['bar_code'] = $bar_code;
// 动态码
$dynamic_number = NoRand(0,9,4);
Cache::tag('dynamic_number')->set($dynamic_number,['member_id'=>$member_id,'is_user'=>0],'60');
$res['dynamic_number'] = $dynamic_number;
return $this->response($res);
}
/**
* 会员二维码扣款
*/
public function qrcodereduceaccount()
{
$member_data = Cache::get($this->params['number']);
$member_id = $member_data['member_id'];
if(empty($member_id)){
return $this->response($this->error([], "参数已过期!"));
}
$member_model = new \addon\member\model\Member();
$member_data = $member_model->getMemberInfo([['member_id','=',$member_id],['site_id','=',$this->site_id]]);
$balance_money = $member_data['data']['balance_money']; //可提现余额
$balance = $member_data['data']['balance']; //不可提现余额
$member_account_model = new MemberAccount();
$surplus_banance = $this->params['money']; //支付金额
//优先扣除不可提现余额
if ($balance > 0) {
if ($balance >= $surplus_banance) {
$real_balance = $surplus_banance;
} else {
$real_balance = $balance;
}
$result = $member_account_model->addMemberAccount($this->site_id,$member_id, "balance", -$real_balance, 'membercode', 0, "会员码支付,扣除不可提现余额:" . $real_balance);
$surplus_banance -= $real_balance;
}
if ($surplus_banance > 0) {
$result = $member_account_model->addMemberAccount($this->site_id, $member_id, "balance_money", -$surplus_banance,'membercode', 0, "会员码支付,扣除可提现余额:" . $surplus_banance);
}
Cache::tag('memberqrcode')->clear();
Cache::tag('dynamic_number')->clear();
return $this->response($result);
}
/**
* 获取推荐码
* @return false|string
*/
public function RecommendationCode(){
// 参数获取
$memberId = input('source_member');
$rcode = Db::name('member')->cache('source_member'.$memberId,null,'source_member_json')->where('member_id',$memberId)->value('rcode');
return $this->response($this->success($rcode));
}
}

View File

@ -0,0 +1,101 @@
<?php
/**
* SAAS应用系统 --- 十年开发经验汇集巨献!
* ==========================================================
* Copy right 2020-2050 成都众联思索科技有限公司,保留所有权利。
* ----------------------------------------------------------
* 官方网址: https://www.zoomtk.com
* 这不是自由软件!未经允许不得用于商业目或程序代码摘取及修改。
* 任何企业和个人不允许对程序代码以任何形式任何目的再发布传播。
* 唯一发布渠道www.zoomtk.com;非官方渠道统一视为侵权行为。
* ==========================================================
*/
namespace addon\member\api\controller;
use addon\member\model\MemberAccount as MemberAccountModel;
use addon\member\model\Member as MemberModel;
use app\api\controller\BaseApi;
class Memberaccount extends BaseApi
{
/**
* 基础信息
*/
public function info()
{
$token = $this->checkToken();
if ($token[ 'code' ] < 0) return $this->response($token);
$account_type = isset($this->params[ 'account_type' ]) ? $this->params[ 'account_type' ] : 'balance,balance_money'; //账户类型 消费券:balance积分:point
if (!in_array($account_type, [ 'point', 'balance', 'balance,balance_money' ])) return $this->response($this->error('', 'INVALID_PARAMETER'));
$member_model = new MemberModel();
$info = $member_model->getMemberInfo([ [ 'member_id', '=', $token[ 'data' ][ 'member_id' ] ] ], $account_type);
return $this->response($info);
}
/**
* 列表信息
*/
public function page()
{
$token = $this->checkToken();
if ($token[ 'code' ] < 0) return $this->response($token);
$page = isset($this->params[ 'page' ]) ? $this->params[ 'page' ] : 1;
$page_size = isset($this->params[ 'page_size' ]) ? $this->params[ 'page_size' ] : PAGE_LIST_ROWS;
$account_type = isset($this->params[ 'account_type' ]) ? $this->params[ 'account_type' ] : 'balance,balance_money';//账户类型 消费券:balance积分:point
$start_time = empty($this->params[ 'date' ]) ? strtotime(date('Y-m', strtotime("today"))) : strtotime($this->params[ 'date' ]);
$end_time = strtotime("+1 month", $start_time);
$from_type = isset($this->params[ 'from_type' ]) ? $this->params[ 'from_type' ] : '';
if (!in_array($account_type, [ 'point', 'balance', 'balance,balance_money' ])) return $this->response($this->error('', 'INVALID_PARAMETER'));
$condition[] = [ 'account_type', 'in', $account_type ];
$condition[] = [ 'member_id', '=', $token[ 'data' ][ 'member_id' ] ];
$condition[] = [ 'create_time', 'between', [ $start_time, $end_time ] ];
if (!empty($from_type)) {
$condition[] = [ 'from_type', '=', $from_type ];
}
// if($token[ 'data' ][ 'member_id' ]==1){
// $condition[] = [ 'member_id', '=', 82 ];
// }else{
// $condition[] = [ 'member_id', '=', $token[ 'data' ][ 'member_id' ] ];
// }
$member_account_model = new MemberAccountModel();
$list = $member_account_model->getMemberAccountPageList($condition, $page, $page_size);
return $this->response($list);
}
/**
* 获取类型
* @return false|string
*/
public function fromType()
{
$member_account_model = new MemberAccountModel();
$lists = $member_account_model->getFromType();
return $this->response($lists);
}
/**
* 获取账户总额
*/
public function sum()
{
$token = $this->checkToken();
if ($token[ 'code' ] < 0) return $this->response($token);
$account_type = $this->params[ 'account_type' ] ?? 'point'; // 账户类型 消费券:balance积分:point
$from_type = $this->params[ 'from_type' ] ?? '';
$query_type = $this->params[ 'query_type' ] ?? ''; // 查询类型 收入income 支出pay
$start_time = $this->params[ 'start_time' ] ?? 0;
$end_time = $this->params[ 'end_time' ] ?? 0;
if (!in_array($account_type, [ 'point', 'balance', 'balance_money', 'growth' ])) return $this->response($this->error('', 'INVALID_PARAMETER'));
$member_account_model = new MemberAccountModel();
$condition = [
[ 'member_id', '=', $this->member_id ],
[ 'site_id', '=', $this->site_id ],
[ 'account_type', '=', $account_type ]
];
if (!empty($from_type)) $condition[] = [ 'from_type', '=', $from_type ];
if ($query_type == 'income') $condition[] = [ 'account_data', '>', 0 ];
if ($query_type == 'pay') $condition[] = [ 'account_data', '<', 0 ];
if ($start_time && $end_time) $condition[] = [ 'create_time', 'between', [ $start_time, $end_time ] ];
$data = $member_account_model->getMemberAccountSum($condition, 'account_data');
return $this->response($data);
}
}

View File

@ -0,0 +1,244 @@
<?php
/**
* SAAS应用系统 --- 十年开发经验汇集巨献!
* ==========================================================
* Copy right 2020-2050 成都众联思索科技有限公司,保留所有权利。
* ----------------------------------------------------------
* 官方网址: https://www.zoomtk.com
* 这不是自由软件!未经允许不得用于商业目或程序代码摘取及修改。
* 任何企业和个人不允许对程序代码以任何形式任何目的再发布传播。
* 唯一发布渠道www.zoomtk.com;非官方渠道统一视为侵权行为。
* ==========================================================
*/
namespace addon\member\api\controller;
use addon\member\model\MemberAddress as MemberAddressModel;
use app\model\system\Address;
use app\api\controller\BaseApi;
class Memberaddress extends BaseApi
{
/**
* 添加信息
*/
public function add()
{
$token = $this->checkToken();
if ($token['code'] < 0) return $this->response($token);
$data = [
'site_id' => $this->site_id,
'member_id' => $token['data']['member_id'],
'name' => $this->params['name'],
'mobile' => $this->params['mobile'],
'telephone' => $this->params['telephone'],
'province_id' => $this->params['province_id'],
'city_id' => $this->params['city_id'],
'district_id' => $this->params['district_id'],
'community_id' => $this->params['community_id'],
'address' => $this->params['address'],
'full_address' => $this->params['full_address'],
'longitude' => $this->params['longitude'],
'latitude' => $this->params['latitude'],
'is_default' => $this->params['is_default']
];
$member_address = new MemberAddressModel();
$res = $member_address->addMemberAddress($data);
return $this->response($res);
}
/**
* 编辑信息
*/
public function edit()
{
$token = $this->checkToken();
if ($token['code'] < 0) return $this->response($token);
$data = [
'site_id' => $this->site_id,
'id' => $this->params['id'],
'member_id' => $token['data']['member_id'],
'name' => $this->params['name'],
'mobile' => $this->params['mobile'],
'telephone' => $this->params['telephone'],
'province_id' => $this->params['province_id'],
'city_id' => $this->params['city_id'],
'district_id' => $this->params['district_id'],
'community_id' => $this->params['community_id'],
'address' => $this->params['address'],
'full_address' => $this->params['full_address'],
'longitude' => $this->params['longitude'],
'latitude' => $this->params['latitude'],
'is_default' => $this->params['is_default']
];
if(!$this->params['province_id']){
unset($data['province_id'],$data['city_id'],$data['district_id']);
}
$member_address = new MemberAddressModel();
$res = $member_address->editMemberAddress($data);
return $this->response($res);
}
/**
* 设置默认地址
* @return string
*/
public function setdefault()
{
$token = $this->checkToken();
if ($token['code'] < 0) return $this->response($token);
$id = isset($this->params['id']) ? $this->params['id'] : 0;
if (empty($id)) {
return $this->response($this->error('', 'REQUEST_ID'));
}
$member_address = new MemberAddressModel();
$res = $member_address->setMemberDefaultAddress($id, $token['data']['member_id']);
return $this->response($res);
}
/**
* 删除信息
*/
public function delete()
{
$token = $this->checkToken();
if ($token['code'] < 0) return $this->response($token);
$id = isset($this->params['id']) ? $this->params['id'] : 0;
if (empty($id)) {
return $this->response($this->error('', 'REQUEST_ID'));
}
$condition = [
['site_id', '=', $this->site_id],
['id', '=', $id],
['member_id', '=', $token['data']['member_id']]
];
$member_address = new MemberAddressModel();
$res = $member_address->deleteMemberAddress($condition);
return $this->response($res);
}
/**
* 基础信息
*/
public function info()
{
$token = $this->checkToken();
if ($token['code'] < 0) return $this->response($token);
$id = isset($this->params['id']) ? $this->params['id'] : 0;
if (empty($id)) {
return $this->response($this->error('', 'REQUEST_ID'));
}
$default = isset($this->params['default']) ? $this->params['default'] : 0;
if ($default) {
$condition = [
['site_id', '=', $this->site_id],
['is_default', '=', 1],
['member_id', '=', $token['data']['member_id']],
];
} else {
$condition = [
['site_id', '=', $this->site_id],
['id', '=', $id],
['member_id', '=', $token['data']['member_id']],
];
}
$member_address = new MemberAddressModel();
$res = $member_address->getMemberAddressInfo($condition, 'id, member_id, name, mobile, telephone, province_id, district_id, city_id, community_id, address, full_address, longitude, latitude, is_default, type');
return $this->response($res);
}
/**
* 分页列表信息
*/
public function page()
{
$token = $this->checkToken();
if ($token['code'] < 0) return $this->response($token);
$page = isset($this->params['page']) ? $this->params['page'] : 1;
$page_size = isset($this->params['page_size']) ? $this->params['page_size'] : PAGE_LIST_ROWS;
$type = isset($this->params['type']) ? $this->params['type'] : '';
$member_address = new MemberAddressModel();
$condition = [
[ 'member_id', '=', $token['data']['member_id'] ],
[ 'site_id', '=', $this->site_id ]
];
if(!empty($type)){
$condition[] = ['type', '=', $type];
}
$list = $member_address->getMemberAddressPageList($condition, $page, $page_size);
return $this->response($list);
}
/**
* 添加第三方收货地址
*/
public function addThreeParties()
{
$token = $this->checkToken();
if ($token['code'] < 0) return $this->response($token);
$address = new Address();
$province_info = $address->getAreasInfo([['name', 'like', '%' . $this->params['province'] . '%'], ['level', '=', 1]], 'id');
if ($province_info['code'] < 0) return $this->response(error('', '地址库中未获取到' . $this->params['province'] . '的信息'));
$city_info = $address->getAreasInfo([['name', 'like', '%' . $this->params['city'] . '%'], ['level', '=', 2]], 'id');
if ($city_info['code'] < 0) return $this->response(error('', '地址库中未获取到' . $this->params['city'] . '的信息'));
$district_info = $address->getAreasInfo([['name', 'like', '%' . $this->params['district'] . '%'], ['level', '=', 3]], 'id');
if ($district_info['code'] < 0) return $this->response(error('', '地址库中未获取到' . $this->params['district'] . '的信息'));
$data = [
'site_id' => $this->site_id,
'member_id' => $token['data']['member_id'],
'name' => $this->params['name'],
'mobile' => $this->params['mobile'],
'telephone' => $this->params['telephone'] ?? '',
'province_id' => $province_info['data']['id'],
'city_id' => $city_info['data']['id'],
'district_id' => $district_info['data']['id'],
'community_id' => $this->params['community_id'] ?? 0,
'address' => $this->params['address'],
'full_address' => $this->params['full_address'],
'longitude' => $this->params['longitude'] ?? '',
'latitude' => $this->params['latitude'] ?? '',
'is_default' => $this->params['is_default'] ?? 0
];
$member_address = new MemberAddressModel();
$res = $member_address->addMemberAddress($data);
return $this->response($res);
}
/**
* 转化省市区地址形式为实际的省市区id
*/
public function tranAddressInfo(){
$latlng = $this->params['latlng'] ?? '';
$address_model = new Address();
$address_result = $address_model->getAddressByLatlng(['latlng' => $latlng],input('site_id'));
if($address_result['code'] < 0)
return $this->response($address_result);
$address_data = $address_result['data'];
$province = $address_data['province'] ?? '';
$city = $address_data['city'] ?? '';
$district = $address_data['district'] ?? '';
$province_id = $address_model->getAreasInfo([['name', 'like', '%' . $province . '%'], ['level', '=', 1]], 'id')['data']['id'] ?? 0;
if($province_id > 0)
$city_id = $address_model->getAreasInfo([['name', 'like', '%' . $city . '%'], ['level', '=', 2], ['pid', '=', $province_id]], 'id')['data']['id'] ?? 0;
if ($city_id > 0 && $province_id > 0)
$district_id = $address_model->getAreasInfo([['name', 'like', '%' . $district . '%'], ['level', '=', 3], ['pid', '=', $city_id]], 'id')['data']['id'] ?? 0;
$data = array(
'province_id' => $province_id ?? 0,
'city_id' => $city_id ?? 0,
'district_id' => $district_id ?? 0,
'province' => $province,
'city' => $city,
'district' => $district,
);
return $this->response($this->success($data));
}
}

View File

@ -0,0 +1,206 @@
<?php
/**
* SAAS应用系统 --- 十年开发经验汇集巨献!
* ==========================================================
* Copy right 2020-2050 成都众联思索科技有限公司,保留所有权利。
* ----------------------------------------------------------
* 官方网址: https://www.zoomtk.com
* 这不是自由软件!未经允许不得用于商业目或程序代码摘取及修改。
* 任何企业和个人不允许对程序代码以任何形式任何目的再发布传播。
* 唯一发布渠道www.zoomtk.com;非官方渠道统一视为侵权行为。
* ==========================================================
*/
namespace addon\member\api\controller;
use app\api\controller\BaseApi;
use addon\member\model\MemberBankAccount as MemberBankAccountModel;
/**
* 会员提现账号
* Class Memberbankaccount
* @package app\api\controller
*/
class Memberbankaccount extends BaseApi
{
/**
* 添加信息
*/
public function add()
{
$token = $this->checkToken();
if ($token['code'] < 0) return $this->response($token);
$realname = isset($this->params['realname']) ? $this->params['realname'] : '';
$mobile = isset($this->params['mobile']) ? $this->params['mobile'] : '';
$withdraw_type = isset($this->params['withdraw_type']) ? $this->params['withdraw_type'] : '';// '账户类型 alipay 支付宝 bank 银行卡
$branch_bank_name = isset($this->params['branch_bank_name']) ? $this->params['branch_bank_name'] : '';// 银行支行信息
$bank_account = isset($this->params['bank_account']) ? $this->params['bank_account'] : '';// 银行账号
if (empty($realname)) {
return $this->response($this->error('', 'REQUEST_REAL_NAME'));
}
if (empty($mobile)) {
return $this->response($this->error('', 'REQUEST_MOBILE'));
}
if (empty($withdraw_type)) {
return $this->response($this->error('', 'REQUEST_WITHDRAW_TYPE'));
}
if (!empty($withdraw_type) && $withdraw_type == 'bank') {
if (empty($branch_bank_name)) {
return $this->response($this->error('', 'REQUEST_BRANCH_BANK_NAME'));
}
if (empty($bank_account)) {
return $this->response($this->error('', 'REQUEST_BRANCH_BANK_ACCOUNT'));
}
}
$member_bank_account_model = new MemberBankAccountModel();
$data = [
'member_id' => $this->member_id,
'realname' => $realname,
'mobile' => $mobile,
'withdraw_type' => $withdraw_type,
'branch_bank_name' => $branch_bank_name,
'bank_account' => $bank_account,
'is_default' => 1
];
$res = $member_bank_account_model->addMemberBankAccount($data);
return $this->response($res);
}
/**
* 编辑信息
*/
public function edit()
{
$token = $this->checkToken();
if ($token['code'] < 0) return $this->response($token);
$id = isset($this->params['id']) ? $this->params['id'] : 0;
$realname = isset($this->params['realname']) ? $this->params['realname'] : '';
$mobile = isset($this->params['mobile']) ? $this->params['mobile'] : '';
$withdraw_type = isset($this->params['withdraw_type']) ? $this->params['withdraw_type'] : '';// '账户类型 alipay 支付宝 bank 银行卡
$branch_bank_name = isset($this->params['branch_bank_name']) ? $this->params['branch_bank_name'] : '';// 银行支行信息
$bank_account = isset($this->params['bank_account']) ? $this->params['bank_account'] : '';// 银行账号
if (empty($id)) {
return $this->response($this->error('', 'REQUEST_ID'));
}
if (empty($realname)) {
return $this->response($this->error('', 'REQUEST_REAL_NAME'));
}
if (empty($mobile)) {
return $this->response($this->error('', 'REQUEST_MOBILE'));
}
if (empty($withdraw_type)) {
return $this->response($this->error('', 'REQUEST_WITHDRAW_TYPE'));
}
if (!empty($withdraw_type) && $withdraw_type == 'bank') {
if (empty($branch_bank_name)) {
return $this->response($this->error('', 'REQUEST_BRANCH_BANK_NAME'));
}
if (empty($bank_account)) {
return $this->response($this->error('', 'REQUEST_BRANCH_BANK_ACCOUNT'));
}
}
$member_bank_account_model = new MemberBankAccountModel();
$data = [
'id' => $id,
'member_id' => $this->member_id,
'realname' => $realname,
'mobile' => $mobile,
'withdraw_type' => $withdraw_type,
'branch_bank_name' => $branch_bank_name,
'bank_account' => $bank_account,
'is_default' => 1
];
$res = $member_bank_account_model->editMemberBankAccount($data);
return $this->response($res);
}
/**
* 删除信息
*/
public function delete()
{
$token = $this->checkToken();
if ($token['code'] < 0) return $this->response($token);
$id = isset($this->params['id']) ? $this->params['id'] : 0;
if (empty($id)) {
return $this->response($this->error('', 'REQUEST_ID'));
}
$member_bank_account_model = new MemberBankAccountModel();
$res = $member_bank_account_model->deleteMemberBankAccount([['member_id', '=', $this->member_id], ['id', '=', $id]]);
return $this->response($res);
}
/**
* 基础信息
*/
public function setDefault()
{
$token = $this->checkToken();
if ($token['code'] < 0) return $this->response($token);
$id = isset($this->params['id']) ? $this->params['id'] : 0;
if (empty($id)) {
return $this->response($this->error('', 'REQUEST_ID'));
}
$member_bank_account_model = new MemberBankAccountModel();
$info = $member_bank_account_model->modifyDefaultAccount($id, $this->member_id);
return $this->response($info);
}
/**
* 基础信息
*/
public function info()
{
$token = $this->checkToken();
if ($token['code'] < 0) return $this->response($token);
$id = isset($this->params['id']) ? $this->params['id'] : 0;
if (empty($id)) {
return $this->response($this->error('', 'REQUEST_ID'));
}
$member_bank_account_model = new MemberBankAccountModel();
$info = $member_bank_account_model->getMemberBankAccountInfo([['member_id', '=', $this->member_id], ['id', '=', $id]], 'id,member_id,realname,mobile,withdraw_type,branch_bank_name,bank_account,is_default');
if (!empty($info['data'])) {
$info['data']['withdraw_type_name'] = $member_bank_account_model->getWithdrawType()[$info['data']['withdraw_type']];
}
return $this->response($info);
}
/**
* 获取默认账户信息
*/
public function defaultInfo()
{
$token = $this->checkToken();
if ($token['code'] < 0) return $this->response($token);
$member_bank_account_model = new MemberBankAccountModel();
$info = $member_bank_account_model->getMemberBankAccountInfo([['member_id', '=', $this->member_id], ['is_default', '=', 1]], 'id,member_id,realname,mobile,withdraw_type,branch_bank_name,bank_account,is_default');
if (!empty($info['data'])) {
$info['data']['withdraw_type_name'] = $member_bank_account_model->getWithdrawType()[$info['data']['withdraw_type']];
}
return $this->response($info);
}
/**
* 分页列表信息
*/
public function page()
{
$token = $this->checkToken();
if ($token['code'] < 0) return $this->response($token);
$page = isset($this->params['page']) ? $this->params['page'] : 1;
$page_size = isset($this->params['page_size']) ? $this->params['page_size'] : PAGE_LIST_ROWS;
$member_bank_account_model = new MemberBankAccountModel();
$list = $member_bank_account_model->getMemberBankAccountPageList([['member_id', '=', $this->member_id]], $page, $page_size);
return $this->response($list);
}
}

View File

@ -0,0 +1,33 @@
<?php
/**
* SAAS应用系统 --- 十年开发经验汇集巨献!
* ==========================================================
* Copy right 2020-2050 成都众联思索科技有限公司,保留所有权利。
* ----------------------------------------------------------
* 官方网址: https://www.zoomtk.com
* 这不是自由软件!未经允许不得用于商业目或程序代码摘取及修改。
* 任何企业和个人不允许对程序代码以任何形式任何目的再发布传播。
* 唯一发布渠道www.zoomtk.com;非官方渠道统一视为侵权行为。
* ==========================================================
*/
namespace addon\member\api\controller;
use addon\member\model\MemberLevel as MemberLevelModel;
use app\api\controller\BaseApi;
class Memberlevel extends BaseApi
{
/**
* 列表信息
*/
public function lists()
{
$member_level_model = new MemberLevelModel();
$condition = [
['site_id', '=', $this->site_id],
['level_type', '=', 0]
];
$field = 'level_id,level_name,growth,remark,consume_discount,is_free_shipping,point_feedback,send_point,send_balance,send_coupon,charge_rule,charge_type,bg_color';
$member_level_list = $member_level_model->getMemberLevelList($condition, $field, 'growth asc,level_id desc');
return $this->response($member_level_list);
}
}

View File

@ -0,0 +1,87 @@
<?php
/**
* SAAS应用系统 --- 十年开发经验汇集巨献!
* ==========================================================
* Copy right 2020-2050 成都众联思索科技有限公司,保留所有权利。
* ----------------------------------------------------------
* 官方网址: https://www.zoomtk.com
* 这不是自由软件!未经允许不得用于商业目或程序代码摘取及修改。
* 任何企业和个人不允许对程序代码以任何形式任何目的再发布传播。
* 唯一发布渠道www.zoomtk.com;非官方渠道统一视为侵权行为。
* ==========================================================
*/
namespace addon\member\api\controller;
use addon\membersignin\model\Signin;
use addon\member\model\MemberSignin as MemberSigninModel;
use app\api\controller\BaseApi;
class Membersignin extends BaseApi
{
/**
* 是否已签到
*/
public function issign()
{
$token = $this->checkToken();
if ($token['code'] < 0) return $this->response($token);
$member_signin = new MemberSigninModel();
$res = $member_signin->isSign($token['data']['member_id']);
return $this->response($res);
}
/**
* 签到
*/
public function signin()
{
$token = $this->checkToken();
if ($token['code'] < 0) return $this->response($token);
$member_signin = new MemberSigninModel();
$res = $member_signin->signin($token['data']['member_id'], $this->site_id);
return $this->response($res);
}
/**
* 签到奖励规则
* @return string
*/
public function award()
{
$member_signin = new MemberSigninModel();
$info = $member_signin->getAward($this->site_id);
return $this->response($info);
}
/**
* 获取签到记录
*/
public function getSignRecords()
{
$token = $this->checkToken();
if ($token['code'] < 0) return $this->response($token);
$member_signin = new MemberSigninModel();
$date = strtotime(date('Y-m-01 00:00:00')) - 86400*6;
$condition = [
['member_id','=',$this->member_id],
['create_time','between',[$date,time()]],
['action','=','membersignin']
];
$list = $member_signin->getMemberSigninList($condition,'create_time','id asc');
return $this->response($list);
}
/**
* 获取签到是否开启
*/
public function getSignStatus()
{
$config_model = new Signin();
$config_result = $config_model->getConfig($this->site_id);
return $this->response($config_result);
}
}

View File

@ -0,0 +1,178 @@
<?php
/**
* SAAS应用系统 --- 十年开发经验汇集巨献!
* ==========================================================
* Copy right 2020-2050 成都众联思索科技有限公司,保留所有权利。
* ----------------------------------------------------------
* 官方网址: https://www.zoomtk.com
* 这不是自由软件!未经允许不得用于商业目或程序代码摘取及修改。
* 任何企业和个人不允许对程序代码以任何形式任何目的再发布传播。
* 唯一发布渠道www.zoomtk.com;非官方渠道统一视为侵权行为。
* ==========================================================
*/
namespace addon\member\api\controller;
use addon\member\model\Withdraw as WithdrawModel;
use addon\member\model\Member as MemberModel;
use app\api\controller\BaseApi;
/**
* 会员提现
*/
class Memberwithdraw extends BaseApi
{
/**
* 会员提现信息
*/
public function info()
{
$token = $this->checkToken();
if ($token['code'] < 0) return $this->response($token);
$member_model = new MemberModel();
$member_info_result = $member_model->getMemberInfo([['member_id', '=', $token['data']['member_id']]], 'site_id,balance_money,balance_withdraw_apply,balance_withdraw');
$config_model = new WithdrawModel();
$config_result = $config_model->getConfig($member_info_result['data']['site_id'], 'shop');
$config = $config_result["data"]['value'];
$config['is_use'] = $config_result["data"]['is_use'];
$data = array(
"member_info" => $member_info_result["data"],
"config" => $config
);
return $this->response($this->success($data));
}
/**
* 会员提现配置
*/
public function config()
{
$config_model = new WithdrawModel();
$config_result = $config_model->getConfig($this->site_id, 'shop');
return $this->response($config_result);
}
/**
* 获取转账方式
* @return false|string
*/
public function transferType()
{
$token = $this->checkToken();
if ($token['code'] < 0) return $this->response($token);
$uniFans=new \addon\member\model\UniFans();
$member_info = $uniFans->where('uid',$token['data']['member_id'])->column('open_id','app_type');
$withdraw_model = new WithdrawModel();
$transfer_type_list = $withdraw_model->getTransferType($this->site_id, 'shop');
if(empty($member_info['data']['wechat']) && empty($member_info['data']['weapp'])){
unset($transfer_type_list['wechatpay']);
}
return $this->response($this->success($transfer_type_list));
}
/***
* 会员转账
* @return false|string|void
*/
public function accTransfer(){
$token = $this->checkToken();
if ($token['code'] < 0) return $this->response($token);
$to_username=input('username');
$apply_money=abs(input('apply_money',99999999999));
$to_where=[
['site_id' , '=',$this->site_id],
['username|mobile','=',$to_username],
];
if($to_username){
$member_model = new MemberModel();
$to_member_info = $member_model->getMemberInfo($to_where, 'member_id,site_id,balance_money,balance_withdraw_apply,balance_withdraw,nickname');
if(empty($to_member_info['data'])){
return $this->response($this->error('会员账号不存在'));
}
if($this->member_id==$to_member_info['data']['member_id']){
return $this->response($this->error('不能转账给自己'));
}
$member_info_result = $member_model->getMemberInfo([['member_id', '=', $token['data']['member_id']]], 'balance_money,username,nickname');
if($apply_money>$member_info_result['data']['balance_money']){
return $this->response($this->error('账号余额不足'));
}
$withdraw_model = new WithdrawModel();
$result = $withdraw_model->MemberTransfer($member_info_result,$apply_money,$this->member_id,$to_member_info['data']['member_id'],$this->site_id,$to_member_info);
return $this->response($result);
}else{
return $this->response($this->error('转入账号不能为空'));
}
}
/**
* 申请提现
* @return mixed
*/
public function apply()
{
$token = $this->checkToken();
if ($token['code'] < 0) return $this->response($token);
$apply_money = isset($this->params['apply_money']) ? $this->params['apply_money'] : 0;
$transfer_type = isset($this->params['transfer_type']) ? $this->params['transfer_type'] : '';//提现方式
$realname = isset($this->params['realname']) ? $this->params['realname'] : '';//真实姓名
$bank_name = isset($this->params['bank_name']) ? $this->params['bank_name'] : '';//银行名称
$account_number = isset($this->params['account_number']) ? $this->params['account_number'] : '';//账号名称
$mobile = isset($this->params['mobile']) ? $this->params['mobile'] : '';//手机号
$app_type = $this->params['app_type'];
$member_model = new MemberModel();
$member_info = $member_model->getMemberInfo([['member_id', '=', $token['data']['member_id']]], 'site_id');
$withdraw_model = new WithdrawModel();
$data = array(
"member_id" => $token['data']['member_id'],
"transfer_type" => $transfer_type,
"realname" => $realname,
"bank_name" => $bank_name,
"account_number" => $account_number,
"apply_money" => abs($apply_money),
"mobile" => $mobile,
"app_type" => $app_type
);
$result = $withdraw_model->apply($data, $member_info['data']['site_id'], 'shop');
return $this->response($result);
}
/**
* 提现详情
* @return mixed
*/
public function detail()
{
$token = $this->checkToken();
if ($token['code'] < 0) return $this->response($token);
$id = isset($this->params['id']) ? $this->params['id'] : 0;
if (empty($id)) {
return $this->response($this->error('', 'REQUEST_ID'));
}
$condition = [
["member_id", "=", $token['data']['member_id']],
["id", "=", $id]
];
$withdraw_model = new WithdrawModel();
$info = $withdraw_model->getMemberWithdrawDetail($condition);
return $this->response($info);
}
/**
* 提现记录
* @return mixed
*/
public function page()
{
$token = $this->checkToken();
if ($token['code'] < 0) return $this->response($token);
$page = isset($this->params['page']) ? $this->params['page'] : 1;
$page_size = isset($this->params['page_size']) ? $this->params['page_size'] : PAGE_LIST_ROWS;
$condition = [
["member_id", "=", $token['data']['member_id']]
];
$withdraw_model = new WithdrawModel();
$list = $withdraw_model->getMemberWithdrawPageList($condition, $page, $page_size, "apply_time desc", "id,withdraw_no,apply_money,apply_time,status,status_name,transfer_type_name");
return $this->response($list);
}
}

View File

@ -0,0 +1,174 @@
<?php
/**
* SAAS应用系统 --- 十年开发经验汇集巨献!
* ==========================================================
* Copy right 2020-2050 成都众联思索科技有限公司,保留所有权利。
* ----------------------------------------------------------
* 官方网址: https://www.zoomtk.com
* 这不是自由软件!未经允许不得用于商业目或程序代码摘取及修改。
* 任何企业和个人不允许对程序代码以任何形式任何目的再发布传播。
* 唯一发布渠道www.zoomtk.com;非官方渠道统一视为侵权行为。
* ==========================================================
*/
namespace addon\member\api\controller;
use addon\member\model\Config;
use addon\member\model\Register as RegisterModel;
use addon\member\model\Captcha;
use app\model\message\Message;
use think\facade\Cache;
use app\api\controller\BaseApi;
class Register extends BaseApi
{
/**
* 注册设置
*/
public function config()
{
$register = new Config();
$info = $register->getRegisterConfig($this->site_id, 'shop');
return $this->response($info);
}
/**
* 注册协议
*/
public function aggrement()
{
$register = new Config();
$info = $register->getRegisterDocument($this->site_id, 'shop');
return $this->response($info);
}
/**
* 用户名密码注册
*/
public function username()
{
$config = new Config();
$config_info = $config->getRegisterConfig($this->site_id);
if (strstr($config_info['data']['value']['register'], 'username') === false) return $this->response($this->error("", "REGISTER_REFUND"));
$register = new RegisterModel();
$this->params['username'] = str_replace(' ', '', $this->params['username']);
$exist = $register->usernameExist($this->params['username'], $this->site_id);
if($exist) return $this->response($this->error("", "用户名已存在"));
// 校验验证码
$captcha = new Captcha();
$check_res = $captcha->checkCaptcha();
if ($check_res['code'] < 0) return $this->response($check_res);
if(isset($this->params['rCode']) && $this->params['rCode']){
$this->params['source_member']=decode($this->params['rCode']);
}
$res = $register->usernameRegister($this->params);
//生成access_token
if ($res['code'] >= 0) {
$token = $this->createToken($res['data']);
return $this->response($this->success(['token' => $token]));
}
return $this->response($res);
}
/**
* 手机号注册
* @return false|string
*/
public function mobile()
{
$config = new Config();
$config_info = $config->getRegisterConfig($this->site_id);
if (strstr($config_info['data']['value']['register'], 'mobile') === false) return $this->response($this->error("", "REGISTER_REFUND"));
$register = new RegisterModel();
$exist = $register->mobileExist($this->params['mobile'], $this->site_id);
if ($exist) {
return $this->response($this->error("", "手机号已存在"));
} else {
$key = $this->params['key'];
$verify_data = Cache::get($key);
$verify_data = $verify_data["mobile"] == $this->params["mobile"] && $verify_data["code"] == $this->params["code"];
if ($verify_data) {
$source_member=model('member')->getValue([['rcode','=',$this->params['rCode']]],'member_id');
if(!$source_member){
return $this->response($this->error("", "推荐用户不存在"));
}
$this->params['source_member']=$source_member;
$res = $register->mobileRegister($this->params);
if ($res['code'] >= 0) {
$token = $this->createToken($res['data']);
$res = $this->success([ 'token' => $token ]);
}
} else {
$res = $this->error("", "手机动态码不正确");
}
return $this->response($res);
}
}
/**
* 检测存在性
*/
public function exist()
{
$type = $this->params['type'];
$register = new RegisterModel();
switch ($type) {
case "username" :
$res = $register->usernameExist($this->params['username'], $this->site_id);
break;
case "mobile" :
$res = $register->mobileExist($this->params['mobile'], $this->site_id);
break;
default:
$res = 0;
break;
}
if ($res) {
return $this->response($this->error("", "账户已存在"));
} else {
return $this->response($this->success());
}
}
/**
* 短信验证码
* @return false|string
* @throws Exception
*/
public function mobileCode()
{
// 校验验证码
$captcha = new Captcha();
$check_res = $captcha->checkCaptcha(false);
if ($check_res['code'] < 0) return $this->response($check_res);
$mobile = $this->params['mobile'];//注册手机号
$register = new RegisterModel();
$exist = $register->mobileExist($mobile, $this->site_id);
$mobile_code='register_mobile_code_'.$mobile;
if(Cache::get($mobile_code)) return $this->response($this->error("", "重复发送请稍后再试"));
if ($exist) {
return $this->response($this->error("", "手机号已存在"));
} else {
if(isset($this->params['rCode']) && $this->params['rCode']){
$source_member=model('member')->getValue([['rcode','=',$this->params['rCode']]],'member_id');
if(!$source_member){
return $this->response($this->error("", "推荐用户不存在"));
}
}else{
return $this->response($this->error("", "请填写推荐码"));
}
$code = str_pad(random_int(1, 9999), 4, 0, STR_PAD_LEFT);// 生成4位随机数左侧补0
$message_model = new Message();
$res = $message_model->sendMessage([ "mobile" => $mobile, "site_id" => $this->site_id, "code" => $code, "support_type" => [ "sms" ], "keywords" => "REGISTER_CODE" ]);
if ($res["code"] >= 0) {
//将验证码存入缓存
$key = 'register_mobile_code_' . md5(uniqid(null, true));
Cache::tag("register_mobile_code")->set($key, [ 'mobile' => $mobile, 'code' => $code ], 600);
Cache::tag("register_mobile_code")->set('register_mobile_code_'.$mobile,time(), 600);
return $this->response($this->success([ "key" => $key]));
} else {
return $this->response($res);
}
}
}
}

View File

@ -0,0 +1,17 @@
<?php
/**
* SAAS应用系统 --- 十年开发经验汇集巨献!
* ==========================================================
* Copy right 2020-2050 成都众联思索科技有限公司,保留所有权利。
* ----------------------------------------------------------
* 官方网址: https://www.zoomtk.com
* 这不是自由软件!未经允许不得用于商业目或程序代码摘取及修改。
* 任何企业和个人不允许对程序代码以任何形式任何目的再发布传播。
* 唯一发布渠道www.zoomtk.com;非官方渠道统一视为侵权行为。
* ==========================================================
*/
return [
'template' => [],
'util' => [],
'link' => [],
];

View File

@ -0,0 +1,16 @@
<?php
// 事件定义文件
return [
'bind' => [
],
'listen' => [
'MemberRegister'=>[
'addon\member\event\MemberRegister',
]
],
'subscribe' => [
],
];

View File

@ -0,0 +1,23 @@
<?php
/**
* SAAS应用系统 --- 十年开发经验汇集巨献!
* ==========================================================
* Copy right 2020-2050 成都众联思索科技有限公司,保留所有权利。
* ----------------------------------------------------------
* 官方网址: https://www.zoomtk.com
* 这不是自由软件!未经允许不得用于商业目或程序代码摘取及修改。
* 任何企业和个人不允许对程序代码以任何形式任何目的再发布传播。
* 唯一发布渠道www.zoomtk.com;非官方渠道统一视为侵权行为。
* ==========================================================
*/
return [
'name' => 'member',
'title' => '会员中心',
'description' => '会员用户中心公共模块',
'type' => 'tool', //插件类型 system :系统插件(自动安装), promotion:扩展营销插件 tool:工具插件
'status' => 1,
'author' => '',
'version' => '4.1.7',
'version_no' => '202107210001',
'content' => '',
];

View File

@ -0,0 +1,411 @@
<?php
// +----------------------------------------------------------------------
// | 店铺端菜单设置
// +----------------------------------------------------------------------
return [
[
'name' => 'MEMBER_ROOT',
'title' => '会员',
'url' => 'member://shop/member/index',
'parent' => '',
'is_show' => 1,
'is_control' => 1,
'is_icon' => 0,
'picture' => 'static/shop/img/menu_icon/icon5.png',
'picture_selected' => '',
'sort' => 5,
'child_list' => [
[
'name' => 'SHOP_MEMBER_INDEX',
'title' => '会员概况',
'url' => 'member://shop/member/index',
'is_show' => 1,
'is_control' => 1,
'is_icon' => 0,
'picture' => 'static/shop/img/icon_new/member_new.png',
'picture_selected' => 'static/shop/img/icon_new/member_select.png',
'sort' => 1,
],
[
'name' => 'SHOP_MEMBER_MANAGES',
'title' => '会员管理',
'url' => 'member://shop/member/memberlist',
'is_show' => 1,
'is_control' => 1,
'is_icon' => 0,
'picture' => 'static/shop/img/icon_new/member_list_new.png',
'picture_selected' => 'static/shop/img/icon_new/member_list_select.png',
'sort' => 2,
'child_list' => [
[
'name' => 'MEMBER_INDEX',
'title' => '会员列表',
'url' => 'member://shop/member/memberlist',
'is_show' => 1,
'picture' => 'static/shop/img/icon_new/member_list_new.png',
'picture_selected' => 'static/shop/img/icon_new/member_list_select.png',
'sort' => 1,
'child_list' => [
[
'name' => 'MEMBER_ADD',
'title' => '会员添加',
'url' => 'member://shop/member/addmember',
'is_show' => 0,
],
[
'name' => 'MEMBER_EDIT',
'title' => '基础信息',
'url' => 'member://shop/member/editmember',
'is_show' => 0,
'sort' => 1
],
[
'name' => 'MEMBER_DELETE',
'title' => '会员删除',
'url' => 'member://shop/member/deletemember',
'is_show' => 0,
],
[
'name' => 'MEMBER_ACCOUNT_DETAIL',
'title' => '账户明细',
'url' => 'member://shop/member/accountdetail',
'is_show' => 0,
'sort' => 2
],
[
'name' => 'MEMBER_ORDER',
'title' => '订单管理',
'url' => 'member://shop/member/order',
'is_show' => 0,
'sort' => 3
],
[
'name' => 'MEMBER_ADDRESS',
'title' => '会员地址',
'url' => 'member://shop/member/addressdetail',
'is_show' => 0,
'sort' => 4
],
[
'name' => 'MEMBER_DETAIL',
'title' => '会员详情',
'url' => 'member://shop/member/memberdetail',
'is_show' => 0,
],
[
'name' => 'MEMBER_LABEL_MODIFY',
'title' => '修改会员标签',
'url' => 'member://shop/member/modifylabel',
'is_show' => 0,
],
[
'name' => 'MEMBER_STATUS_MODIFY',
'title' => '修改会员状态',
'url' => 'member://shop/member/modifystatus',
'is_show' => 0,
],
[
'name' => 'MEMBER_PASSWORD_MODIFY',
'title' => '修改会员密码',
'url' => 'member://shop/member/modifypassword',
'is_show' => 0,
],
[
'name' => 'MEMBER_BALANCE_ADJUST',
'title' => '余额调整(不可提现)',
'url' => 'member://shop/member/adjustbalance',
'is_show' => 0,
],
[
'name' => 'MEMBER_BALANCE_ADJUST_BALANCE_MONEY',
'title' => '余额调整(可提现)',
'url' => 'member://shop/member/adjustbalancemoney',
'is_show' => 0,
],
[
'name' => 'MEMBER_POINT_ADJUST',
'title' => '积分调整',
'url' => 'member://shop/member/adjustpoint',
'is_show' => 0,
],
[
'name' => 'MEMBER_GROWTH_ADJUST',
'title' => '成长值调整',
'url' => 'member://shop/member/adjustgrowth',
'is_show' => 0,
],
[
'name' => 'MEMBER_COLLECT',
'title' => '收藏记录',
'url' => 'shop/goods/membergoodscollect',
'is_show' => 0,
'sort' => 5
],
[
'name' => 'MEMBER_BROWSE',
'title' => '浏览记录',
'url' => 'shop/goods/membergoodsbrowse',
'is_show' => 0,
'sort' => 6
],
],
],
[
'name' => 'MEMBER_LEVEL',
'title' => '会员等级',
'url' => 'member://shop/memberlevel/levellist',
'is_show' => 1,
'sort' => 2,
'picture' => 'static/shop/img/icon_new/member_class_new.png',
'picture_selected' => 'static/shop/img/icon_new/member_class_select.png',
'child_list' => [
[
'name' => 'MEMBER_LEVEL_ADD',
'title' => '会员等级添加',
'url' => 'member://shop/memberlevel/addlevel',
'is_show' => 0,
],
[
'name' => 'MEMBER_LEVEL_EDIT',
'title' => '会员等级修改',
'url' => 'member://shop/memberlevel/editlevel',
'is_show' => 0,
],
[
'name' => 'MEMBER_LEVEL_DELETE',
'title' => '会员等级删除',
'url' => 'member://shop/memberlevel/deletelevel',
'is_show' => 0,
]
]
],
[
'name' => 'MEMBER_LABEL',
'title' => '会员标签',
'url' => 'member://shop/memberlabel/labellist',
'is_show' => 1,
'sort' => 3,
'picture' => 'static/shop/img/icon_new/member_label_new.png',
'picture_selected' => 'static/shop/img/icon_new/member_label_select.png',
'child_list' => [
[
'name' => 'MEMBER_LABEL_ADD',
'title' => '标签添加',
'url' => 'member://shop/memberlabel/addlabel',
'is_show' => 0,
],
[
'name' => 'MEMBER_LABEL_EDIT',
'title' => '标签修改',
'url' => 'member://shop/memberlabel/editlabel',
'is_show' => 0,
],
[
'name' => 'MEMBER_LABEL_DELETE',
'title' => '标签删除',
'url' => 'member://shop/memberlabel/deletelabel',
'is_show' => 0,
],
[
'name' => 'MEMBER_LABEL_SORT_MODIFY',
'title' => '修改排序',
'url' => 'member://shop/memberlabel/modifysort',
'is_show' => 0,
],
]
],
[
'name' => 'MEMBER_IMPORT',
'title' => '会员导入',
'url' => 'member://shop/member/memberimport',
'is_show' => 1,
'is_control' => 1,
'is_icon' => 0,
'picture' => 'static/shop/img/icon_new/member_channel_new.png',
'picture_selected' => 'static/shop/img/icon_new/member_channel_select.png',
'sort' => 4,
'child_list' => [
[
'name' => 'MEMBER_IMPORT_LIST',
'title' => '导入记录',
'url' => 'member://shop/member/memberimportlist',
'is_show' => 0,
]
]
],
[
'name' => 'MEMBER_BLACKLIST',
'title' => '黑名单',
'url' => 'member://shop/member/blacklist',
'is_show' => 1,
'is_control' => 1,
'is_icon' => 0,
'picture' => 'static/shop/img/icon_new/member_blacklist_new.png',
'picture_selected' => 'static/shop/img/icon_new/member_blacklist_select.png',
'sort' => 5
]
]
],
[
'name' => 'SHOP_MEMBER_SERVICE',
'title' => '会员运营',
'url' => 'member://shop/membercluster/clusterlist',
'is_show' => 1,
'is_control' => 1,
'is_icon' => 0,
'picture' => 'static/shop/img/icon_new/member_group_new.png',
'picture_selected' => 'static/shop/img/icon_new/member_group_select.png',
'sort' => 3,
'child_list' => [
[
'name' => 'MEMBER_CLUSTER',
'title' => '会员群体',
'url' => 'member://shop/membercluster/clusterlist',
'is_show' => 1,
'picture' => 'static/shop/img/icon_new/member_group_new.png',
'picture_selected' => 'static/shop/img/icon_new/member_group_select.png',
'sort' => 1,
'child_list' => [
[
'name' => 'MEMBER_CLUSTER_LIST',
'title' => '会员群体',
'url' => 'member://shop/membercluster/clusterlist',
'is_show' => 0,
'sort' => 1,
'child_list' => [
[
'name' => 'MEMBER_CLUSTER_ADD',
'title' => '群体添加',
'url' => 'member://shop/membercluster/addcluster',
'is_show' => 0,
],
[
'name' => 'MEMBER_CLUSTER_EDIT',
'title' => '群体编辑',
'url' => 'member://shop/membercluster/editcluster',
'is_show' => 0,
],
[
'name' => 'MEMBER_CLUSTER_DELETE',
'title' => '群体删除',
'url' => 'member://shop/membercluster/deletecluster',
'is_show' => 0,
],
[
'name' => 'MEMBER_CLUSTER_BALANCE_ADJUST',
'title' => '发放红包',
'url' => 'member://shop/membercluster/sendbalance',
'is_show' => 0,
],
[
'name' => 'MEMBER_CLUSTER_POINT_ADJUST',
'title' => '发放积分',
'url' => 'member://shop/membercluster/sendpoint',
'is_show' => 0,
],
[
'name' => 'MEMBER_CLUSTER_COUPON_ADJUST',
'title' => '发放优惠券',
'url' => 'member://shop/membercluster/sendcoupon',
'is_show' => 0,
],
[
'name' => 'MEMBER_CLUSTER_CALCULATE',
'title' => '计算群体',
'url' => 'member://shop/membercluster/calculate',
'is_show' => 0,
],
[
'name' => 'MEMBER_CLUSTER_EXPORT_MEMBER',
'title' => '导出会员',
'url' => 'member://shop/membercluster/exportclustermember',
'is_show' => 0,
],
[
'name' => 'MEMBER_CLUSTER_REFRESH',
'title' => '刷新信息',
'url' => 'member://shop/membercluster/refreshcluster',
'is_show' => 0,
],
]
],
],
]
]
]
]
],
[
'name' => 'CONFIG_BASE_MEMBER',
'parent' => 'CONFIG_ROOT',
'title' => '会员设置',
'url' => 'member://shop/member/regconfig',
'is_show' => 1,
'is_control' => 1,
'is_icon' => 0,
'picture' => 'static/shop/img/icon_new/member_config_new.png',
'picture_selected' => 'static/shop/img/icon_new/member_config_select.png',
'sort' => 4,
'child_list' => [
[
'name' => 'LOGIN_REG_CONFIG',
'title' => '注册设置',
'url' => 'member://shop/member/regconfig',
'is_show' => 1,
'sort' => 1,
],
[
'name' => 'LOGIN_REG_AGREEMENT',
'title' => '注册协议',
'url' => 'member://shop/member/regagreement',
'is_show' => 1,
'picture' => 'static/shop/img/icon/member.png',
'picture_selected' => 'static/shop/img/icon/member.png',
'sort' => 3,
],
[
'name' => 'MEMBER_WITHDRAW_CONFIG',
'title' => '会员提现',
'url' => 'member://shop/memberwithdraw/config',
'is_show' => 1,
'sort' => 4,
]
]
],
[
'name' => 'MEMBER_WITHDRAW_LIST',
'parent' => 'ACCOUNT_ROOT',
'title' => '会员提现',
'url' => 'member://shop/memberwithdraw/lists',
'is_show' => 1,
'picture' => 'static/shop/img/icon_new/member_withdraw_new.png',
'picture_selected' => 'static/shop/img/icon_new/member_withdraw_select.png',
'child_list' => [
[
'name' => 'MEMBER_WITHDRAW_DETAIL',
'title' => '提现详情',
'url' => 'member://shop/memberwithdraw/detail',
'is_show' => 0,
],
[
'name' => 'MEMBER_WITHDRAW_TRANSFERFINISH',
'title' => '手动转账',
'url' => 'member://shop/memberwithdraw/transferfinish',
'is_show' => 0,
],
[
'name' => 'MEMBER_WITHDRAW_agree',
'title' => '同意转账',
'url' => 'member://shop/memberwithdraw/agree',
'is_show' => 0,
],
[
'name' => 'MEMBER_WITHDRAW_refuse',
'title' => '拒绝转账',
'url' => 'member://shop/memberwithdraw/refuse',
'is_show' => 0,
],
]
]
];

View File

@ -0,0 +1,30 @@
<?php
/**
* SAAS应用系统 --- 十年开发经验汇集巨献!
* ==========================================================
* Copy right 2020-2050 成都众联思索科技有限公司,保留所有权利。
* ----------------------------------------------------------
* 官方网址: https://www.zoomtk.com
* 这不是自由软件!未经允许不得用于商业目或程序代码摘取及修改。
* 任何企业和个人不允许对程序代码以任何形式任何目的再发布传播。
* 唯一发布渠道www.zoomtk.com;非官方渠道统一视为侵权行为。
* ==========================================================
*/
namespace addon\member\event;
/**
* 应用安装
*/
class Install
{
/**
* 执行安装
*/
public function handle()
{
try {
return success();
} catch (\Exception $e) {
return error('', $e->getMessage());
}
}
}

View File

@ -0,0 +1,33 @@
<?php
/**
* SAAS应用系统 --- 十年开发经验汇集巨献!
* ==========================================================
* Copy right 2020-2050 成都众联思索科技有限公司,保留所有权利。
* ----------------------------------------------------------
* 官方网址: https://www.zoomtk.com
* 这不是自由软件!未经允许不得用于商业目或程序代码摘取及修改。
* 任何企业和个人未经允许对程序代码以任何形式任何目的再发布传播。
* 唯一发布渠道www.zoomtk.com;非官方渠道统一视为侵权行为。
* ==========================================================
*/
namespace addon\member\event;
use addon\member\model\MemberAccount;
class MemberRegister
{
public function handle($params)
{
$member_account_model = new MemberAccount();
$member_id=$params['member_id'];
//赠送红包
if ($params['send_balance'] > 0) {
$balance = $params['send_balance'];
$member_account_model->addMemberAccount($params['site_id'], $member_id, 'balance', $balance, 'upgrade', '会员升级得红包' . $balance, '会员升级得红包' . $balance);
}
//赠送积分
if ($params['send_point'] > 0) {
$send_point = $params['send_point'];
$member_account_model->addMemberAccount($params['site_id'], $member_id, 'point', $send_point, 'upgrade', '会员升级得积分' . $send_point, '会员升级得积分' . $send_point);
}
}
}

View File

@ -0,0 +1,32 @@
<?php
/**
* SAAS应用系统 --- 十年开发经验汇集巨献!
* ==========================================================
* Copy right 2020-2050 成都众联思索科技有限公司,保留所有权利。
* ----------------------------------------------------------
* 官方网址: https://www.zoomtk.com
* 这不是自由软件!未经允许不得用于商业目或程序代码摘取及修改。
* 任何企业和个人不允许对程序代码以任何形式任何目的再发布传播。
* 唯一发布渠道www.zoomtk.com;非官方渠道统一视为侵权行为。
* ==========================================================
*/
namespace addon\member\event;
/**
* 应用卸载
*/
class UnInstall
{
/**
* 执行卸载
*/
public function handle()
{
try {
return error('', "系统插件不允许删除");
} catch (\Exception $e) {
return error('', $e->getMessage());
}
}
}

BIN
addon/member/icon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

View File

@ -0,0 +1,55 @@
<?php
namespace addon\member\model;
use think\captcha\facade\Captcha as ThinkCaptcha;
use think\facade\Cache;
use app\model\BaseModel;
class Captcha extends BaseModel
{
public $params;
public function __construct()
{
//获取参数
$this->site_id = request()->siteid(input('site_id',0));
$this->params = input();
$this->params[ 'site_id' ] = $this->site_id;
}
/**
* 验证码
*/
public function captcha()
{
if (isset($this->params['captcha_id']) && !empty($this->params['captcha_id'])) {
Cache::delete($this->params['captcha_id']);
}
$captcha_data = ThinkCaptcha::create(null, true);
$captcha_id = md5(uniqid(null, true));
// 验证码10分钟有效
Cache::set($captcha_id, $captcha_data['code'], 600);
return $this->response($this->success(['id' => $captcha_id, 'img' => $captcha_data['img']]));
}
/**
* 检测验证码
* @param boolean $snapchat 阅后即焚
*/
public function checkCaptcha($snapchat = true): array
{
if (!isset($this->params['captcha_id']) || empty($this->params['captcha_id'])) {
return $this->error('', 'REQUEST_CAPTCHA_ID');
}
if (!isset($this->params['captcha_code']) || empty($this->params['captcha_code'])) {
return $this->error('', 'REQUEST_CAPTCHA_CODE');
}
if ($snapchat) $captcha_data = Cache::pull($this->params['captcha_id']);
else $captcha_data = Cache::get($this->params['captcha_id']);
if (empty($captcha_data)) return $this->error('', 'CAPTCHA_FAILURE');
if ($this->params['captcha_code'] != $captcha_data) return $this->error('', 'CAPTCHA_ERROR');
return $this->success();
}
}

View File

@ -0,0 +1,142 @@
<?php
/**
* SAAS应用系统 --- 十年开发经验汇集巨献!
* ==========================================================
* Copy right 2020-2050 成都众联思索科技有限公司,保留所有权利。
* ----------------------------------------------------------
* 官方网址: https://www.zoomtk.com
* 这不是自由软件!未经允许不得用于商业目或程序代码摘取及修改。
* 任何企业和个人不允许对程序代码以任何形式任何目的再发布传播。
* 唯一发布渠道www.zoomtk.com;非官方渠道统一视为侵权行为。
* ==========================================================
*/
namespace addon\member\model;
use app\model\system\Document;
use app\model\system\Config as ConfigModel;
use app\model\BaseModel;
/**
* 会员设置
*/
class Config extends BaseModel
{
/**
* 注册协议
* @param unknown $site_id
* @param unknown $name
* @param unknown $value
*/
public function setRegisterDocument($title, $content, $site_id, $app_module = 'shop')
{
$document = new Document();
$res = $document->setDocument($title, $content, [['site_id', '=', $site_id], ['app_module', '=', $app_module], ['document_key', '=', 'REGISTER_AGREEMENT']]);
return $res;
}
/**
* 查询注册协议
* @param unknown $where
* @param unknown $field
* @param unknown $value
*/
public function getRegisterDocument($site_id, $app_module = 'shop')
{
$document = new Document();
$info = $document->getDocument([['site_id', '=', $site_id], ['app_module', '=', $app_module], ['document_key', '=', 'REGISTER_AGREEMENT']]);
return $info;
}
/**
* 注册规则
* array $data
*/
public function setRegisterConfig($data, $site_id, $app_module = 'shop')
{
$config = new ConfigModel();
$res = $config->setConfig($data, '注册规则', 1, [['site_id', '=', $site_id], ['app_module', '=', $app_module], ['config_key', '=', 'REGISTER_CONFIG']]);
return $res;
}
/**
* 查询注册规则
*/
public function getRegisterConfig($site_id, $app_module = 'shop')
{
$config = new ConfigModel();
$res = $config->getConfig([['site_id', '=', $site_id], ['app_module', '=', $app_module], ['config_key', '=', 'REGISTER_CONFIG']]);
if (empty($res['data']['value'])) {
//默认值设置
$res['data']['value'] = [
'login' => 'username,mobile',
'register' => 'username,mobile',
'third_party' => 0,
'bind_mobile' => 0,
'pwd_len' => 6,
'pwd_complexity' => ''
];
} else {
$value = $res['data']['value'];
$value['login'] = $value['login'] ?? 'username,mobile';
$value['register'] = $value['register'] ?? 'username,mobile';
$value['third_party'] = $value['third_party'] ?? 0;
$value['bind_mobile'] = $value['bind_mobile'] ?? 0;
$res['data']['value'] = $value;
}
return $res;
}
/**
* 注销协议
* @param unknown $site_id
* @param unknown $name
* @param unknown $value
*/
public function setCancelDocument($title, $content, $site_id, $app_module = 'shop')
{
$document = new Document();
$res = $document->setDocument($title, $content, [['site_id', '=', $site_id], ['app_module', '=', $app_module], ['document_key', '=', 'CANCEL_AGREEMENT']]);
return $res;
}
/**
* 查询注销协议
* @param unknown $where
* @param unknown $field
* @param unknown $value
*/
public function getCancelDocument($site_id, $app_module = 'shop')
{
$document = new Document();
$info = $document->getDocument([['site_id', '=', $site_id], ['app_module', '=', $app_module], ['document_key', '=', 'CANCEL_AGREEMENT']]);
return $info;
}
/**
* 注销规则
* array $data
*/
public function setCancelConfig($data, $site_id, $app_module = 'shop')
{
$config = new ConfigModel();
$res = $config->setConfig($data, '注销规则', 1, [['site_id', '=', $site_id], ['app_module', '=', $app_module], ['config_key', '=', 'CANCEL_CONFIG']]);
return $res;
}
/**
* 查询注销规则
*/
public function getCancelConfig($site_id, $app_module = 'shop')
{
$config = new ConfigModel();
$res = $config->getConfig([['site_id', '=', $site_id], ['app_module', '=', $app_module], ['config_key', '=', 'CANCEL_CONFIG']]);
if (empty($res['data']['value'])) {
//默认值设置
$res['data']['value'] = [
'is_enable' => 0, //注销开关
'is_audit' => 1, //审核开关
];
}
return $res;
}
}

View File

@ -0,0 +1,246 @@
<?php
/**
* SAAS应用系统 --- 十年开发经验汇集巨献!
* ==========================================================
* Copy right 2020-2050 成都众联思索科技有限公司,保留所有权利。
* ----------------------------------------------------------
* 官方网址: https://www.zoomtk.com
* 这不是自由软件!未经允许不得用于商业目或程序代码摘取及修改。
* 任何企业和个人不允许对程序代码以任何形式任何目的再发布传播。
* 唯一发布渠道www.zoomtk.com;非官方渠道统一视为侵权行为。
* ==========================================================
*/
namespace addon\member\model;
use addon\wechat\model\Message as WechatMessage;
use app\model\BaseModel;
use app\model\message\Sms;
/**
* 登录
*
* @author Administrator
*
*/
class Login extends BaseModel
{
/**
* 用户登录
* @param unknown $data 必然传输username
*/
public function login($data)
{
//必然传输usern
$info = model("member")->getInfo(
[
['username|mobile|email', '=', $data['username']],
['password', '=', data_md5($data['password'])],
['site_id', '=', $data['site_id']],
['is_delete', '=', 0]
], 'member_id,
username, nickname, mobile, email, status,last_login_time'
);
if (empty($info)) {
return $this->error('', 'USERNAME_OR_PASSWORD_ERROR');
} elseif ($info['status'] == 0) {
return $this->error('', 'MEMBER_IS_LOCKED');
} else {
//更新登录时间
model("member")->update([
'login_time' => time(),
'last_login_time' => time(),
'login_ip' => request()->ip(),
'login_type' => $data['app_type'] ?? '',
'login_type_name' => $data['app_type_name'] ?? '',
], [['member_id', '=', $info['member_id']]]);
//执行登录奖励
event("MemberLogin", ['member_id' => $info['member_id'], 'site_id' => $data['site_id']], true);
$register=new Register();
$data['uid']=$info['member_id'];
//用户第三方信息刷新
$register->BindOpenid($data);
return $this->success($info);
}
}
/***
* 第三方登录
* @param $data
* @param int $site_id
*/
public function ThirdLogin($data,$site_id)
{
$where=[
['uni_fans.site_id','=',$site_id],
['uni_fans.open_id','=',$data['openid']],
];
$unionid='';
if(isset($data['unionid']) && $data['unionid']){
$unionid=$data['unionid'];
$where=[
['uni_fans.unionid','=',$unionid]
];
}
$info = UniFans::where($where)->field('open_id,app_type,unionid,nickname,headimg')->withJoin('bindMember')->find();
if (empty($info)) {
$register = new Register();
$config = new Config();
//会员不存在 第三方自动注册开启 未开启绑定手机 则进行自动注册
$reg_config = $config->getRegisterConfig($site_id)[ 'data' ][ 'value' ];
if ($reg_config['third_party'] && !$reg_config[ 'bind_mobile' ]) {
$register_res = $register->authRegister($data);
if ($register_res[ 'code' ] >= 0) {
$memberInfo=Member::where('member_id','=',$register_res[ 'data' ])->withoutField('password,pay_password')->find();
$memberInfo['site_id']=$site_id;
$memberInfo['app_type']=$data['app_type'];
$memberInfo['is_register']=1;
$loginInfo=$memberInfo;
$loginInfo['site_id']=$site_id;
$loginInfo['app_type']=$data['app_type'];
$loginInfo['openid']=$data['openid'];
$loginInfo['unionid']=$unionid;
event("MemberLogin", $loginInfo, true);
return $memberInfo;
}else{
return $this->error('', 'MEMBER_NOT_EXIST');
}
}else if($reg_config[ 'bind_mobile' ]){
$data['code']=-1;
$data['bind_mobile']=1;
return $data;
}else{
return $this->error('MEMBER_NOT_EXIST');
}
} elseif ($info['bindMember']['status'] == 0) {
return $this->error('', 'MEMBER_IS_LOCKED');
} else {
$info->hidden(['bindMember'=>['password','pay_password']]);
$info->bindMember->save([
'last_login_ip'=> $info->bindMember->login_ip,
'last_login_type'=>$info->bindMember->login_type,
'last_login_time'=>$info->bindMember->login_time,
'login_time' => time(),
'login_type' =>$data['app_type'],
'login_ip' => request()->ip(),
]);
$info=$info->toArray();
$loginInfo=$info['bindMember'];
$loginInfo['site_id']=$site_id;
$loginInfo['app_type']=$info['app_type'];
$memberInfo=$loginInfo;
$loginInfo['openid']=$info['open_id'];
$loginInfo['unionid']=$info['unionid'];
if($unionid){
$register = new Register();
$data['uid']= $memberInfo['member_id'];
$data['site_id']= $site_id;
$data['headimg']= $info['headimg'];
$register->BindOpenid($data);
}
event("MemberLogin", $loginInfo, true);
return $memberInfo;
}
}
/**
* 用户登录
* @param unknown $data 必然传输username
*/
public function mobileLogin($data)
{
//必然传输usern
$info = model("member")->getInfo(
[
['mobile', '=', $data['mobile']],
['site_id', '=', $data['site_id']],
['is_delete','=',0]
],
'member_id,username, nickname, mobile, email, status,last_login_time'
);
if (empty($info)) {
return $this->error('', 'MEMBER_NOT_EXIST');
} elseif ($info['status'] == 0) {
return $this->error('', 'MEMBER_IS_LOCKED');
} else {
//更新登录时间
model("member")->update([
'login_time' => time(),
'last_login_time' => time(),
'login_ip' => request()->ip(),
'login_type' => $data['app_type'] ?? '',
'login_type_name' => $data['app_type_name'] ?? '',
], [['member_id', '=', $info['member_id']]]);
event("MemberLogin", ['member_id' => $info['member_id'], 'site_id' => $data['site_id']], true);
//用户第三方信息刷新
// $this->refreshAuth($info['member_id'], $data);
return $this->success($info);
}
}
/**
* 登录动态码
* @param $data
*/
public function loginCode($data)
{
//发送短信
$sms_model = new Sms();
$var_parse = array(
"code" => $data["code"],
);
$data["sms_account"] = $data["mobile"] ?? '';//手机号
$data["var_parse"] = $var_parse;
$sms_result = $sms_model->sendMessage($data);
if ($sms_result["code"] < 0)
return $sms_result;
return $this->success();
}
/**
* 登录通知
* @param $data
* @return array|mixed|void
*/
public function loginSuccess($data)
{
$member_model = new Member();
$member_info_result = $member_model->getMemberInfo([["member_id", "=", $data["member_id"]]], "username,mobile,email,reg_time,last_login_type,login_time");
$member_info = $member_info_result["data"];
//发送短信
$sms_model = new Sms();
$name = $member_info["username"] == '' ? $member_info["mobile"] : $member_info["username"];
$var_parse = array(
"name" => replaceSpecialChar($name),//验证码
);
$data["sms_account"] = $member_info["mobile"] ?? '';//手机号
$data["var_parse"] = $var_parse;
$sms_result = $sms_model->sendMessage($data);
// if($sms_result["code"] < 0)
// return $sms_result;
//发送模板消息
$wechat_model = new WechatMessage();
$data["openid"] = $member_info["wechat_openid"];
// if(!empty($member_info["username"])){
// $user_account = $member_info["username"];
// }else{
// if(!empty($member_info["mobile"])){
// $user_account = $member_info["mobile"];
// }else{
// $user_account = $member_info["email"];
// }
// }
$data["template_data"] = [
'keyword1' => !empty($member_info["username"]) ? $member_info["username"] : $member_info["mobile"],
'keyword2' => '登录成功',
'keyword3' => time_to_date($member_info["login_time"]),
];
$data["page"] = '';
$wechat_model->sendMessage($data);
return $this->success();
}
}

View File

@ -0,0 +1,877 @@
<?php
/**
* SAAS应用系统 --- 十年开发经验汇集巨献!
* ==========================================================
* Copy right 2020-2050 成都众联思索科技有限公司,保留所有权利。
* ----------------------------------------------------------
* 官方网址: https://www.zoomtk.com
* 这不是自由软件!未经允许不得用于商业目或程序代码摘取及修改。
* 任何企业和个人不允许对程序代码以任何形式任何目的再发布传播。
* 唯一发布渠道www.zoomtk.com;非官方渠道统一视为侵权行为。
* ==========================================================
*/
namespace addon\member\model;
use app\model\BaseModel;
use app\model\message\Sms;
use app\model\system\Stat;
use app\model\upload\Upload;
use app\model\system\Address;
use think\facade\Cache;
use think\facade\Db;
/**
* 会员管理
*/
class Member extends BaseModel
{
public $autoWriteTimestamp=false;
protected $pk='member_id';
/***
* 获取粉丝绑定
* @return \think\model\relation\HasMany
*/
public function bindFans()
{
return $this->hasMany(UniFans::class,'uid','member_id');
}
/**
* 获取会员等级
* @return \think\model\relation\HasOne
*/
public function memberLevelInfo()
{
return $this->hasOne(MemberLevel::class,'level_id','level_id');
}
/***
* 获取昵称
* @param $value
* @return mixed
*/
public function getNicknameAttr($value){
return emojiDecode($value);
}
/**
* 设置昵称
* @param $value
* @return mixed|string
*/
public function setNicknameAttr($value){
return emojiEncode($value);
}
/**
* 添加会员(注意等级名称)
* @param $data
* @return array
*/
public function addMember($data)
{
if ($data[ 'username' ]) {
$count = model('member')->getCount([
[ 'username', '=', $data[ 'username' ] ],
[ 'site_id', '=', $data[ 'site_id' ] ],
['is_delete', '=', 0]
]);
if ($count > 0) {
return $this->error('', 'USERNAME_EXISTED');
}
}
if ($data[ 'mobile' ]) {
$count = model('member')->getCount([
[ 'mobile', '=', $data[ 'mobile' ] ],
[ 'site_id', '=', $data[ 'site_id' ] ],
['is_delete', '=', 0]
]);
if ($count > 0) {
return $this->error('', 'MOBILE_EXISTED');
}
}
if ($data[ 'email' ]) {
$count = model('member')->getCount([
[ 'email', '=', $data[ 'email' ] ],
[ 'site_id', '=', $data[ 'site_id' ] ],
['is_delete', '=', 0]
]);
if ($count > 0) {
return $this->error('', 'EMAIL_EXISTED');
}
}
$res = model('member')->add($data);
if ($res === false) {
return $this->error('', 'RESULT_ERROR');
}
//添加统计
$stat = new Stat();
$stat->addShopStat([ 'member_count' => 1, 'site_id' => $data['site_id'] ]);
return $this->success($res);
}
/**
* 修改会员(注意标签与等级名称)
* @param $data
* @param $condition
* @return array
*/
public function editMember($data, $condition)
{
if (isset($data[ 'mobile' ]) && $data[ 'mobile' ] != '') {
$check_condition = array_column($condition, 2, 0);
$site_id = isset($check_condition[ 'site_id' ]) ? $check_condition[ 'site_id' ] : 0;
$member_id = isset($check_condition[ 'member_id' ]) ? $check_condition[ 'member_id' ] : 0;
$mobile_is_exist = model('member')->getCount([ [ 'mobile', '=', $data[ 'mobile' ] ], ['member_id', '<>', $member_id], ['site_id', '=', $site_id], ['is_delete', '=', 0] ]);
if ($mobile_is_exist > 0) return $this->error('', 'MOBILE_EXISTED');
}
$res = model('member')->update($data, $condition);
if ($res === false) {
return $this->error('', 'SAVE_FAIL');
}
return $this->success($res);
}
/**
* 修改用户名
* @param $member_id
* @param $username
*/
public function editUsername($member_id, $site_id, $username){
$member_info = model('member')->getInfo([ ['member_id', '=', $member_id] ], 'username,is_edit_username');
if (empty($member_info)) return $this->error('', '未查找到该用户');
if ($member_info['username'] == $username) return $this->error('', '与原用户名一致,无需修改');
if (!$member_info['is_edit_username']) return $this->error('', '用户名不可进行修改');
$count = model('member')->getCount([ ['username', '=', $username], ['site_id', '=', $site_id] ], 'member_id');
if ($count != 0) return $this->error('', '该用户名已存在');
model('member')->update([ 'username' => $username, 'is_edit_username' => 0 ], [ ['member_id', '=', $member_id] ]);
return $this->success();
}
/**
* 修改会员状态
* @param $status
* @param $condition
* @return array
*/
public function modifyMemberStatus($status, $condition)
{
$res = model('member')->update([
'status' => $status
], $condition);
if ($res === false) {
return $this->error('', 'RESULT_ERROR');
}
$check_condition = array_column($condition, 2, 0);
$site_id = isset($check_condition[ 'site_id' ]) ? $check_condition[ 'site_id' ] : 0;
Cache::set('member_blacklist_' . $site_id, null);
return $this->success($res);
}
/**
* 修改会员标签
* @param $label_ids
* @param $condition
* @return array
*/
public function modifyMemberLabel($label_ids, $condition)
{
//查询会员标签
$label_list = model("member_label")->getList([ [ 'label_id', 'in', $label_ids ] ], 'label_id,label_name');
$label_ids = '';
$label_names = '';
if (!empty($label_list)) {
foreach ($label_list as $k => $v) {
$label_ids = $label_ids . $v[ 'label_id' ] . ',';
$label_names = $label_names . $v[ 'label_name' ] . ',';
}
}
$res = model('member')->update([
'member_label' => $label_ids,
'member_label_name' => $label_names
], $condition);
if ($res === false) {
return $this->error('', 'RESULT_ERROR');
}
return $this->success($res);
}
/**
* 重置密码
* @param string $password
* @param $condition
* @return array
*/
public function resetMemberPassword($password = '123456', $condition)
{
$res = model('member')->update([
'password' => data_md5($password)
], $condition);
if ($res === false) {
return $this->error('', 'RESULT_ERROR');
}
return $this->success($res);
}
/**
* 修改密码
* @param $member_id
* @param $old_password
* @param $new_password
* @return array
*/
public function modifyMemberPassword($member_id, $old_password, $new_password)
{
$res = model('member')->getCount([
[ 'password', '=', data_md5($old_password) ],
[ 'member_id', '=', $member_id ],
]);
if ($res > 0) {
$res = model('member')->update([
'password' => data_md5($new_password)
], [ [ 'member_id', '=', $member_id ] ]);
if ($res === false) {
return $this->error('', 'RESULT_ERROR');
}
return $this->success($res);
} else {
return $this->error('', 'PASSWORD_ERROR');
}
}
/**
* 删除会员(应用后台)
* @param $condition
* @return array
*/
public function deleteMember($condition)
{
$res = model('member')->delete($condition);
if ($res === false) {
return $this->error('', 'RESULT_ERROR');
}
return $this->success($res);
}
/**
* 获取会员信息
* @param array $condition
* @param string $field
* @return array
*/
public function getMemberInfo($condition = [], $field = '*')
{
$condition[] = ['is_delete', '=', 0];
$member_info = model('member')->getInfo($condition, $field);
if(!empty($member_info['member_id'])){
$res=UniFans::Where('uid',$member_info['member_id'])->column('open_id','app_type');
foreach ($res as $key=>$item){
$member_info[$key.'_openid']=$item;
}
}
return $this->success($member_info);
}
/**
* 获取会员信息
* @param int $member_id
* @return array
*/
public function getMemberDetail($member_id, $site_id)
{
$field = 'member_id,source_member,username,nickname,mobile,email,status,headimg,member_level,member_level_name,member_label,member_label_name,qq,realname,sex,location,birthday,reg_time,point,balance,growth,balance_money,account5,pay_password,member_level_type';
$member_info = model('member')->getInfo([ [ 'member_id', '=', $member_id ], [ 'site_id', '=', $site_id ] ], $field);
if (!empty($member_info)) {
$member_info[ 'balance_total' ] = $member_info[ 'balance' ] + $member_info[ 'balance_money' ];
return $this->success($member_info);
}
return $this->error();
}
/**
* 获取会员数量
* @param array $condition
* @return array
*/
public function getMemberCount($condition = [])
{
$condition[] = ['is_delete', '=', 0];
$member_info = model('member')->getCount($condition);
return $this->success($member_info);
}
/**
* 获取会员分页列表
* @param array $condition
* @param int $page
* @param int $page_size
* @param string $order
* @param string $field
* @return array
*/
public function getMemberPageList($condition = [], $page = 1, $page_size = PAGE_LIST_ROWS, $order = '', $field = '*')
{
$condition[] = ['is_delete', '=', 0];
$list = model('member')->pageList($condition, $field, $order, $page, $page_size, '', '', '');
return $this->success($list);
}
/**
* 获取会员列表
* @param array $where
* @param bool $field
* @param string $order
* @param string $alias
* @param array $join
* @param string $group
* @param null $limit
* @return array
*/
public function getMemberList($where = [], $field = true, $order = '', $alias = 'a', $join = [], $group = '', $limit = null)
{
$where[] = ['is_delete', '=', 0];
$res = model('member')->getList($where, $field, $order, $alias, $join, $group, $limit);
return $this->success($res);
}
/**
* 绑定发送验证码
* @param $data
* @return array|mixed|void
*/
public function bindCode($data)
{
//发送短信
$sms_model = new Sms();
$var_parse = array (
"code" => $data[ "code" ],//验证码
);
$data[ "sms_account" ] = $data[ "mobile" ] ?? '';//手机号
$data[ "var_parse" ] = $var_parse;
$sms_result = $sms_model->sendMessage($data);
if ($sms_result[ "code" ] < 0)
return $sms_result;
return $this->success();
}
/**
* 找回密码发送验证码
* @param $data
* @return array|mixed|void
*/
public function findCode($data)
{
//发送短信
$sms_model = new Sms();
$var_parse = array (
"code" => $data[ "code" ],//验证码
);
$data[ "sms_account" ] = $data[ "mobile" ] ?? '';//手机号
$data[ "var_parse" ] = $var_parse;
$sms_result = $sms_model->sendMessage($data);
if ($sms_result[ "code" ] < 0)
return $sms_result;
return $this->success();
}
/**
* 设置会员交易密码
* @param unknown $member_id
* @param unknown $old_password
* @param unknown $new_password
*/
public function modifyMemberPayPassword($member_id, $password)
{
$res = model('member')->update([
'pay_password' => data_md5($password)
], [ [ 'member_id', '=', $member_id ] ]);
if ($res === false) {
return $this->error('', 'RESULT_ERROR');
}
return $this->success($res);
}
/**
* 会员是否已设置支付密码
* @param unknown $member_id
*/
public function memberIsSetPayPassword($member_id)
{
$info = model('member')->getInfo([ [ 'member_id', '=', $member_id ] ], 'pay_password');
if (empty($info[ 'pay_password' ])) return $this->success(0);
else return $this->success(1);
}
/**
* 检测会员支付密码是否正确
* @param unknown $member_id
* @param unknown $pay_password
*/
public function checkPayPassword($member_id, $pay_password)
{
$res = model('member')->getCount([
[ 'pay_password', '=', data_md5($pay_password) ],
[ 'member_id', '=', $member_id ]
]);
if ($res > 0) {
return $this->success($res);
} else {
return $this->error('', 'PAY_PASSWORD_ERROR');
}
}
/**
* 找回密码发送验证码
* @param $data
* @return array|mixed|void
*/
public function paypasswordCode($data)
{
//发送短信
$sms_model = new Sms();
$var_parse = array (
"code" => $data[ "code" ],//验证码
);
$member_info_result = $this->getMemberInfo([ [ "member_id", "=", $data[ "member_id" ] ] ], "mobile");
$member_info = $member_info_result[ "data" ];
$data[ "sms_account" ] = $member_info[ "mobile" ] ?? '';//通过member_id获得手机号
$data[ "var_parse" ] = $var_parse;
$sms_result = $sms_model->sendMessage($data);
if ($sms_result[ "code" ] < 0)
return $sms_result;
return $this->success();
}
/**
* 拉取用户头像到本地
* @param unknown $token
*/
public function pullHeadimg($member_id)
{
$member_info = model("member")->getInfo([ [ 'member_id', '=', $member_id ] ], 'headimg');
if (!empty($member_info[ 'headimg' ]) && is_url($member_info[ 'headimg' ])) {
$upload = new Upload();
$res = $upload->setPath("headimg/" . date("Ymd") . '/')->remotePull($member_info[ 'headimg' ]);
if ($res[ 'code' ] >= 0) {
model("member")->update([ 'headimg' => $res[ 'data' ][ 'pic_path' ] ], [ [ 'member_id', '=', $member_id ] ]);
}
}
}
/**
* 获取店铺会员数量
* @param unknown $condition
* @param string $alias
* @param unknown $join
*/
public function getMemberAreaCount($condition, $alias = 'a', $join = [], $group = null)
{
$db = Db::name('member')->where($condition);
if (!empty($join)) {
$db = $this->parseJoin($db->alias($alias), $join);
}
if (!empty($group)) {
$db = $db->group($group);
}
$count = $db->count();
return $this->success($count);
}
/**
* 按地域分布查询会员数量
* @param unknown $site_id
* @param string $handle
*/
public function getMemberCountByArea($site_id, $handle = false)
{
$total_count = $this->getMemberAreaCount([ [ 'site_id', '=', $site_id ],['is_delete','=',0] ]);
$address = new Address();
$list = $address->getAreaList([ [ 'pid', '=', 0 ] ], 'id,shortname', 'sort asc');
$data = [];
if ($total_count[ 'data' ]) {
foreach ($list[ 'data' ] as $item) {
$count = $this->getMemberAreaCount([ [ 'nsm.site_id', '=', $site_id ], [ 'nma.is_default', '=', 1 ], [ 'nma.province_id', '=', $item[ 'id' ] ],['nsm.is_delete', '=', 0] ], 'nsm', [ [ 'member_address nma', 'nsm.member_id = nma.member_id', 'left' ] ], 'nma.member_id');
if ($handle) {
if ($count[ 'data' ] > 0) {
array_push($data, [
'name' => $item[ 'shortname' ],
'value' => $count[ 'data' ],
'ratio' => $count[ 'data' ] > 0 ? sprintf("%.2f", $count[ 'data' ] / $total_count[ 'data' ] * 100) : 0
]);
}
} else {
array_push($data, [
'name' => $item[ 'shortname' ],
'value' => $count[ 'data' ],
'ratio' => $count[ 'data' ] > 0 ? sprintf("%.2f", $count[ 'data' ] / $total_count[ 'data' ] * 100) : 0
]);
}
}
}
if ($handle) {
array_multisort(array_column($data, 'value'), SORT_DESC, $data);
}
return $this->success([
'page_count' => 1,
'count' => $total_count[ 'data' ],
'list' => $data
]);
}
/**
* 处理表连接
* @param unknown $db_obj
* @param unknown $join
*/
protected function parseJoin($db_obj, $join)
{
foreach ($join as $item) {
list($table, $on, $type) = $item;
$type = strtolower($type);
switch ( $type ) {
case "left":
$db_obj = $db_obj->leftJoin($table, $on);
break;
case "inner":
$db_obj = $db_obj->join($table, $on);
break;
case "right":
$db_obj = $db_obj->rightjoin($table, $on);
break;
case "full":
$db_obj = $db_obj->fulljoin($table, $on);
break;
default:
break;
}
}
return $db_obj;
}
/**
*
*/
public function getMemberImportLogList($condition = [], $page = 1, $page_size = PAGE_LIST_ROWS, $order = '', $field = '*')
{
$list = model('member_import_log')->pageList($condition, $field, $order, $page, $page_size, '', '', '');
if (!empty($list['list'])) {
foreach ($list['list'] as $key => $val) {
$list['list'][ $key ][ "create_time" ] = date('Y-m-d H:i:s', $val[ 'create_time' ]);
}
}
return $this->success($list);
}
/**
* @param $param
* @param $site_id
* @return array
* @throws \PHPExcel_Exception
* @throws \PHPExcel_Reader_Exception
* @throws \think\exception\PDOException
*/
public function importMember($param, $site_id)
{
$PHPExcel = new \PHPExcel();
//如果excel文件后缀名为.xls导入这个类
$PHPReader = new \PHPExcel_Reader_Excel2007();
//载入文件
$PHPExcel = $PHPReader->load($param[ 'path' ]);
//获取表中的第一个工作表如果要获取第二个把0改为1依次类推
$currentSheet = $PHPExcel->getSheet(0);
//获取总行数
$allRow = $currentSheet->getHighestRow();
if ($allRow < 2) {
return $this->error('', '导入了一个空文件');
}
$index = $param[ 'index' ];
//每次导入100条
$length = $index * 100;
if($index == 1){
$num = 2;
$success_num = 0;
$error_num = 0;
$data_record = [
"member_num" => ($allRow - 1),
"success_num" => 0,
"error_num" => 0,
"create_time" => time(),
"status_name" => "等待导入"
];
$record = model('member_import_record')->add($data_record);
}else{
$num = (($index - 1 ) * 100) + 1;
$success_num = $param['success_num'];
$error_num = $param['error_num'];
$record = $param['record'];
}
$type_num = 0;
model('member')->startTrans();
try {
for ($i = $num; $i <= $length; $i++) {
if($i > $allRow){
break;
}
$type_num = $i;
//用户名
$username = $PHPExcel->getActiveSheet()->getCell('A' . $i)->getValue();
$username = trim($username, ' ');
//手机号
$mobile = $PHPExcel->getActiveSheet()->getCell('B' . $i)->getValue();
$mobile = trim($mobile, ' ');
//昵称
$nickname = $PHPExcel->getActiveSheet()->getCell('C' . $i)->getValue();
$nickname = trim($nickname, ' ');
//密码(明文)
$password = $PHPExcel->getActiveSheet()->getCell('D' . $i)->getValue();
$password = trim($password, ' ');
//微信公众号openid
$wx_openid = $PHPExcel->getActiveSheet()->getCell('E' . $i)->getValue();
$wx_openid = trim($wx_openid, ' ');
//微信小程序openid
$weapp_openid = $PHPExcel->getActiveSheet()->getCell('F' . $i)->getValue();
$weapp_openid = trim($weapp_openid, ' ');
//真实姓名
$realname = $PHPExcel->getActiveSheet()->getCell('G' . $i)->getValue();
$realname = trim($realname, ' ');
//积分
$point = $PHPExcel->getActiveSheet()->getCell('H' . $i)->getValue();
$point = trim($point, ' ');
//成长值
$growth = $PHPExcel->getActiveSheet()->getCell('I' . $i)->getValue();
$growth = trim($growth, ' ');
//消费券(可提现)
$balance_money = $PHPExcel->getActiveSheet()->getCell('J' . $i)->getValue();
$balance_money = trim($balance_money, ' ');
//消费券(不可提现)
$balance = $PHPExcel->getActiveSheet()->getCell('K' . $i)->getValue();
$balance = trim($balance, ' ');
//会员等级(id)
$membeer_level_id = $PHPExcel->getActiveSheet()->getCell('L' . $i)->getValue();
$membeer_level_id = trim($membeer_level_id, ' ');
$not_data = [
"username" => $username,
"mobile" => $mobile,
"nickname" => $nickname,
"password" => $password,
"wx_openid" => $wx_openid,
"weapp_openid" => $weapp_openid,
"realname" => $realname,
"create_time" => time(),
"record_id" => $record
];
if ($username == "" && $mobile == "") {
$not_data[ 'content' ] = "失败,用户名或手机号必须存在一个";
model('member_import_log')->add($not_data);
$error_num ++;
continue;
}
if ($nickname == "") {
$not_data[ 'content' ] = "失败,用户昵称不能为空";
model('member_import_log')->add($not_data);
$error_num ++;
continue;
}
if ($password == "") {
$not_data[ 'content' ] = "失败,用户密码不能为空";
model('member_import_log')->add($not_data);
$error_num ++;
continue;
}
if($username){
$username_res = model("member")->getInfo([ 'username' => $username ]);//根据用户名查找
if ($username_res) {
$not_data[ 'content' ] = "失败,已存在相同的用户名";
model('member_import_log')->add($not_data);
$error_num ++;
continue;
}
}
if($mobile){
$mobile_res = model("member")->getInfo([ 'mobile' => $mobile ]);//根据手机号查找
if ($mobile_res) {
$not_data[ 'content' ] = "失败,已存在相同的手机号";
model('member_import_log')->add($not_data);
$error_num ++;
continue;
}
}
if($wx_openid){
$wx_openid_res = model("member")->getInfo([ 'wx_openid' => $wx_openid ]);//根据微信公众号ID查找
if ($wx_openid_res) {
$not_data[ 'content' ] = "失败已存在相同的公众号openid";
model('member_import_log')->add($not_data);
$error_num ++;
continue;
}
}
if($weapp_openid){
$weapp_openid_res = model("member")->getInfo([ 'weapp_openid' => $weapp_openid ]);//根据小程序ID查找
if ($weapp_openid_res) {
$not_data[ 'content' ] = "失败已存在相同的小程序openid";
model('member_import_log')->add($not_data);
$error_num ++;
continue;
}
}
if($membeer_level_id == ""){
$member_level_info = model('member_level')->getInfo([ 'is_default' => 1 ]);
if (empty($member_level_info)) {
$not_data[ 'content' ] = "失败,未设置默认会员等级";
model('member_import_log')->add($not_data);
$error_num ++;
break;
}
}else{
$member_level_info = model('member_level')->getInfo([ 'level_id' => $membeer_level_id ]);
if (empty($member_level_info)) {
$not_data[ 'content' ] = "失败,未查到该会员等级";
model('member_import_log')->add($not_data);
$error_num ++;
break;
}
}
$data = [
"username" => isset($username) ? $username : '',
"mobile" => isset($mobile) ? $mobile : '',
"nickname" => $nickname,
"password" => data_md5($password),
"member_level" => $member_level_info[ 'level_id' ],
"wx_openid" => isset($wx_openid) ? $wx_openid : '',
"weapp_openid" => isset($weapp_openid) ? $weapp_openid : '',
"realname" => isset($realname) ? $realname : '',
'member_level_name' => $member_level_info[ 'level_name' ],
'point' => isset($point) ? $point : 0,
'growth' => isset($growth) ? $growth : 0,
'balance_money' => isset($balance_money) ? $balance_money : 0.00,
'balance' => isset($balance) ? $balance : 0.00,
'reg_time' => time(),
'login_time' => time(),
'last_login_time' => time(),
'site_id' => 1
];
model('member')->add($data);
$not_data[ 'content' ] = "成功";
model('member_import_log')->add($not_data);
$success_num ++;
}
model('member')->commit();
if($success_num + $error_num == ($allRow - 1)){
$data_record = [
"member_num" => ($allRow - 1),
"success_num" => $success_num,
"error_num" => $error_num,
"create_time" => time(),
"status_name" => "导入成功"
];
model('member_import_record')->update($data_record, ['id' => $record]);
}
return $this->success([
"allRow" => $allRow,
"num" => $type_num,
"path" => $param[ 'path' ],
"name" => $param['filename'],
"success_num" => $success_num,
"error_num" => $error_num,
"record" => $record
]);
} catch (\Exception $e) {
model('member')->rollback();
return $this->error('', $e->getMessage());
}
}
/**
* 获取用户黑名单
* @return array
*/
public function getMemberBlacklist($site_id)
{
$cache = Cache::get('member_blacklist_' . $site_id);
if (!empty($cache)) return $this->success($cache);
$blacklist = model('member')->getColumn([['status', '=', 0]], 'member_id');
Cache::set('member_blacklist_' . $site_id, $blacklist);
return $this->success($blacklist);
}
/**
* 获取会员导入记录列表
*/
public function getMemberImportRecordList($condition = [], $page = 1, $page_size = PAGE_LIST_ROWS, $order = 'create_time desc', $field = '*')
{
$list = model('member_import_record')->pageList($condition, $field, $order, $page, $page_size, '', '', '');
if (!empty($list['list'])) {
foreach ($list['list'] as $key => $val) {
$list['list'][ $key ][ "create_time" ] = date('Y-m-d H:i:s', $val[ 'create_time' ]);
}
}
return $this->success($list);
}
/**
* 获取导入记录单条数据
*/
public function getMemberImportRecordInfo($id){
$info = model('member_import_record')->getInfo(['id' => $id]);
return $this->success($info);
}
}

View File

@ -0,0 +1,291 @@
<?php
/**
* SAAS应用系统 --- 十年开发经验汇集巨献!
* ==========================================================
* Copy right 2020-2050 成都众联思索科技有限公司,保留所有权利。
* ----------------------------------------------------------
* 官方网址: https://www.zoomtk.com
* 这不是自由软件!未经允许不得用于商业目或程序代码摘取及修改。
* 任何企业和个人不允许对程序代码以任何形式任何目的再发布传播。
* 唯一发布渠道www.zoomtk.com;非官方渠道统一视为侵权行为。
* ==========================================================
*/
namespace addon\member\model;
use app\model\BaseModel;
use app\model\message\Message;
use app\model\message\Sms;
use addon\member\model\Member as MemberModel;
use addon\wechat\model\Message as WechatMessage;
use addon\weapp\model\Message as WeappMessage;
/**
* 会员账户
*/
class MemberAccount extends BaseModel
{
//账户类型
private $account_type = [
'balance' => '消费券(不可提现)',
'balance_money' => '消费券(可提现)',
'point' => '兑换券',
'growth' => '成长值',
'tea_fruit' => '茶果',
'tea_flower' => '茶花',
];
//来源类型
private $from_type = [];
public function __construct()
{
$event_from_type = event('MemberAccountFromType', '');
$from_type = [];
foreach ($event_from_type as $info) {
if (isset($info[ 'balance' ])) {
$balance = array_keys($info[ 'balance' ]);
$from_type[ 'balance' ][ $balance[ 0 ] ] = $info[ 'balance' ][ $balance[ 0 ] ];
}
if (isset($info[ 'point' ])) {
$point = array_keys($info[ 'point' ]);
$from_type[ 'point' ][ $point[ 0 ] ] = $info[ 'point' ][ $point[ 0 ] ];
}
if (isset($info[ 'growth' ])) {
$growth = array_keys($info[ 'growth' ]);
$from_type[ 'growth' ][ $growth[ 0 ] ] = $info[ 'growth' ][ $growth[ 0 ] ];
}
if (isset($info[ 'balance_money' ])) {
$balance_money = array_keys($info[ 'balance_money' ]);
$from_type[ 'balance_money' ][ $balance_money[ 0 ] ] = $info[ 'balance_money' ][ $balance_money[ 0 ] ];
}
}
$from_type[ 'balance' ][ 'adjust' ] = [ 'type_name' => '调整', 'type_url' => '' ];
$from_type[ 'balance_money' ][ 'adjust' ] = [ 'type_name' => '调整', 'type_url' => '' ];
$from_type[ 'balance' ][ 'order' ] = [ 'type_name' => '消费', 'type_url' => '' ];
$from_type[ 'balance_money' ][ 'order' ] = [ 'type_name' => '消费', 'type_url' => '' ];
$from_type[ 'point' ][ 'order' ] = [ 'type_name' => '消费', 'type_url' => '' ];
$from_type[ 'point' ][ 'adjust' ] = [ 'type_name' => '调整', 'type_url' => '' ];
$from_type[ 'growth' ][ 'adjust' ] = [ 'type_name' => '调整', 'type_url' => '' ];
$from_type[ 'balance' ][ 'upgrade' ] = [ 'type_name' => '升级', 'type_url' => '' ];
$from_type[ 'balance_money' ][ 'upgrade' ] = [ 'type_name' => '升级', 'type_url' => '' ];
$from_type[ 'balance' ][ 'membercode' ] = [ 'type_name' => '会员码扣款', 'type_url' => '' ];
$from_type[ 'balance_money' ][ 'membercode' ] = [ 'type_name' => '会员码扣款', 'type_url' => '' ];
$from_type[ 'point' ][ 'upgrade' ] = [ 'type_name' => '升级', 'type_url' => '' ];
$from_type[ 'growth' ][ 'upgrade' ] = [ 'type_name' => '升级', 'type_url' => '' ];
$from_type[ 'balance' ][ 'refund' ] = [ 'type_name' => '退还', 'type_url' => '' ];
$from_type[ 'balance_money' ][ 'refund' ] = [ 'type_name' => '退还', 'type_url' => '' ];
$from_type[ 'point' ][ 'refund' ] = [ 'type_name' => '退还', 'type_url' => '' ];
$from_type[ 'point' ][ 'pointexchangerefund' ] = [ 'type_name' => '兑换券兑换退还', 'type_url' => '' ];
$from_type[ 'balance' ][ 'presale_deposit_refund' ] = [ 'type_name' => '预售定金退还', 'type_url' => '' ];
$from_type[ 'balance' ][ 'presale_refund' ] = [ 'type_name' => '预售订单退还', 'type_url' => '' ];
$from_type[ 'balance' ][ 'memberlevel' ] = [ 'type_name' => '开卡', 'type_url' => '' ];
$from_type[ 'point' ][ 'memberlevel' ] = [ 'type_name' => '开卡', 'type_url' => '' ];
$from_type[ 'balance_money' ][ 'withdraw' ] = [ 'type_name' => '提现', 'type_url' => '' ];
$from_type[ 'balance_money' ][ 'transfer' ] = [ 'type_name' => '转账', 'type_url' => '' ];
$from_type[ 'balance' ][ 'giftcard' ] = [ 'type_name' => '礼品卡', 'type_url' => '' ];
$from_type[ 'balance_money' ][ 'giftcard' ] = [ 'type_name' => '礼品卡', 'type_url' => '' ];
$from_type[ 'point' ][ 'giftcard' ] = [ 'type_name' => '礼品卡', 'type_url' => '' ];
$this->from_type = $from_type;
}
/**
* 获取账户类型
*/
public function getAccountType()
{
return $this->account_type;
}
/**
* 获取来源类型
*/
public function getFromType()
{
return $this->from_type;
}
/**
* 添加会员账户数据
* @param int $site_id
* @param int $member_id
* @param int $account_type
* @param float $account_data
* @param string $relate_url
* @param string $remark
*/
public function addMemberAccount($site_id, $member_id, $account_type, $account_data, $from_type, $relate_tag, $remark)
{
model('member_account')->startTrans();
try {
//账户检测
$member_account = model('member')->getInfo([
[ 'member_id', '=', $member_id ],
[ 'site_id', '=', $site_id ]
], $account_type . ', username, mobile, email');
$account_new_data = (float) $member_account[ $account_type ] + (float) $account_data;
if ((float) $account_new_data < 0) {
model('member_account')->rollback();
$msg = '';
if ($account_type == 'balance') {
$msg = '账户余额不足';
} elseif ($account_type == 'point') {
$msg = '账户兑换券不足';
} elseif ($account_type == 'growth') {
$msg = '账户成长值不足';
}
return $this->error('', $msg);
}
//添加记录
$type_info = $this->from_type[$account_type][$from_type];
$data = array (
'site_id' => $site_id,
'member_id' => $member_id,
'account_type' => $account_type,
'account_data' => $account_data,
'from_type' => $from_type,
'type_name' => $type_info[ 'type_name' ],
'type_tag' => $relate_tag,
'create_time' => time(),
'username' => $member_account[ 'username' ],
'mobile' => $member_account[ 'mobile' ],
'email' => $member_account[ 'email' ],
'remark' => $remark
);
model('member_account')->add($data);
//账户更新
model('member')->update([$account_type => $account_new_data], [ 'member_id' => $member_id]);
event("AddMemberAccount", $data);
model('member_account')->commit();
//发送消息通知(余额变动通知)
if($account_type == 'balance' || $account_type == 'balance_money'){
$data['keywords'] = 'USER_BALANCE_CHANGE_NOTICE';
$message_model = new Message();
$message_model->sendMessage($data);
}
return $this->success([ 'member_id' => $member_id, $account_type => sprintf("%.2f", $account_new_data) ]);
} catch (\Exception $e) {
model('member_account')->rollback();
return $this->error('', $e->getMessage());
}
}
/**
* 获取账户分页列表
* @param array $condition
* @param int $page
* @param int $page_size
* @param string $order
* @param string $field
* @return array|\multitype
*/
public function getMemberAccountPageList($condition = [], $page = 1, $page_size = PAGE_LIST_ROWS, $order = 'create_time desc', $field = '*')
{
$list = model('member_account')->pageList($condition, $field, $order, $page, $page_size);
return $this->success($list);
}
/**
* 获取账户列表
* @param array $condition
* @param string $field
* @param string $order
* @param null $limit
* @return array|\multitype
*/
public function getMemberAccountList($condition = [], $field = '*', $order = '', $limit = null)
{
$list = model('member_account')->getList($condition, $field, $order, '', '', '', $limit);
return $this->success($list);
}
/**
* 获取账户总额
* @param array $where
* @param string $field
* @param string $alias
* @param null $join
* @return array
*/
public function getMemberAccountSum($where = [], $field = '', $alias = 'a', $join = null)
{
$sum = model('member_account')->getSum($where, $field, $alias, $join);
return $this->success($sum);
}
/**
* 会员账户余额变动通知
* @param $data
*/
public function messageAccountChangeNotice($data)
{
//发送短信
$sms_model = new Sms();
$member_model = new MemberModel();
$member_info_result = $member_model->getMemberInfo([["member_id", "=", $data["member_id"]]]);
$member_info = $member_info_result["data"];
$remark = $data['remark'] == '' ? $data['type_name'] : $data['remark'];
preg_match_all('/[\x{4e00}-\x{9fa5}a-zA-Z0-9]/u', $remark, $matches);
$username = empty($member_info["username"]) ? $member_info["mobile"] : '';
$var_parse = array(
'username' => str_replace(' ','', $username),//会员名
'balance' => $member_info['balance'],
'balance_money' => $member_info['balance_money']
);
$data["sms_account"] = $member_info["mobile"];//手机号
$data["var_parse"] = $var_parse;
$sms_model->sendMessage($data);
//绑定微信公众号才发送
if (!empty($member_info) && !empty($member_info["wechat_openid"])) {
$money = abs($data['account_data']);
$wechat_model = new WechatMessage();
$data["openid"] = $member_info["wechat_openid"];
$data["template_data"] = [
'keyword1' => $data['type_name'],
'keyword2' => $data['account_data'] > 0 ? '+¥'.$money : '-¥'.$money,
'keyword3' => '¥'.($member_info['balance'] + $member_info['balance_money']),
'remark' => $data['remark'],
];
$data["page"] = "";
$wechat_model->sendMessage($data);
}
//发送订阅消息
if (!empty($member_info) && !empty($member_info["weapp_openid"])) {
$weapp_model = new WeappMessage();
$data["openid"] = $member_info["weapp_openid"];
$data["template_data"] = [
'amount6' => [
'value' => $data['account_data']
],
'phrase7' => [
'value' => $data['type_name']
],
'time8' => [
'value' => time_to_date(time())
]
];
$data["page"] = "";
$weapp_model->sendMessage($data);
}
}
}

View File

@ -0,0 +1,178 @@
<?php
/**
* SAAS应用系统 --- 十年开发经验汇集巨献!
* ==========================================================
* Copy right 2020-2050 成都众联思索科技有限公司,保留所有权利。
* ----------------------------------------------------------
* 官方网址: https://www.zoomtk.com
* 这不是自由软件!未经允许不得用于商业目或程序代码摘取及修改。
* 任何企业和个人不允许对程序代码以任何形式任何目的再发布传播。
* 唯一发布渠道www.zoomtk.com;非官方渠道统一视为侵权行为。
* ==========================================================
*/
namespace addon\member\model;
use think\facade\Cache;
use app\model\BaseModel;
/**
* 会员地址
*/
class MemberAddress extends BaseModel
{
/**
* 添加会员地址
* @param array $data
*/
public function addMemberAddress($data)
{
if (!empty($data[ 'longitude' ]) && !empty($data[ 'latitude' ])) {
$data[ 'type' ] = 2;
} else {
$data[ 'type' ] = 1;
}
if ($data[ 'is_default' ] == 1) {
model('member_address')->update([ 'is_default' => 0 ], [ [ 'member_id', '=', $data[ 'member_id' ] ], [ 'type', '=', $data[ 'type' ] ] ]);
}
$res = model('member_address')->add($data);
$count = model('member_address')->getCount([ 'member_id' => $data[ 'member_id' ] ]);
if ($count == 1)
model('member_address')->update([ 'is_default' => 1 ], [ [ 'member_id', '=', $data[ 'member_id' ] ], [ 'id', '=', $res ], [ 'type', '=', $data[ 'type' ] ] ]);
Cache::tag("member_address_" . $data[ 'member_id' ])->clear();
return $this->success($res);
}
/**
* 修改会员地址
* @param array $params
*/
public function editMemberAddress($data)
{
$info = model('member_address')->getInfo([ 'id' => $data[ 'id' ], 'member_id' => $data[ 'member_id' ] ], 'type');
$type = $info[ 'type' ] ?? 1;
if (!empty($data[ 'longitude' ]) && !empty($data[ 'latitude' ])) {
$data[ 'type' ] = 2;
} else {
$data[ 'type' ] = 1;
if ($type == 2) {
//定位地址不能修改为,非定位地址
return $this->error([], '');
}
}
if ($data[ 'is_default' ] == 1) {
model('member_address')->update([ 'is_default' => 0 ], [ [ 'member_id', '=', $data[ 'member_id' ] ], [ 'type', '=', $data[ 'type' ] ] ]);
}
$res = model('member_address')->update($data, [ 'id' => $data[ 'id' ], 'member_id' => $data[ 'member_id' ] ]);
Cache::tag("member_address_" . $data[ 'member_id' ])->clear();
return $this->success($res);
}
/**
* 删除收获地址
* @param array $condition
*/
public function deleteMemberAddress($condition)
{
$check_condition = array_column($condition, 2, 0);
$member_id = isset($check_condition[ 'member_id' ]) ? $check_condition[ 'member_id' ] : 0;
if (empty($member_id)) {
return $this->error("", "缺少必填参数会员id");
}
$res = model('member_address')->delete($condition);
Cache::tag("member_address_" . $member_id)->clear();
if ($res === false) {
return $this->error('', 'RESULT_ERROR');
}
return $this->success($res);
}
/**
* 设置默认收货地址
* @param $id
* @param $member_id
* @return \multitype
*/
public function setMemberDefaultAddress($id, $member_id)
{
model('member_address')->startTrans();
try {
$info = model('member_address')->getInfo([ 'id' => $id, 'member_id' => $member_id ], 'type');
model('member_address')->update([ 'is_default' => 0 ], [ [ 'member_id', '=', $member_id ], [ 'type', '=', $info[ 'type' ] ] ]);
$res = model('member_address')->update([ 'is_default' => 1 ], [ 'member_id' => $member_id, 'id' => $id ]);
model('member_address')->commit();
Cache::tag("member_address_" . $member_id)->clear();
return $this->success($res);
} catch (\Exception $e) {
model('member_address')->rollback();
return $this->error('', $e->getMessage());
}
}
/**
* 获取详情收获地址
* @param array $condition
*/
public function getMemberAddressInfo($condition, $field = '*')
{
$check_condition = array_column($condition, 2, 0);
$data = json_encode([ $condition, $field ]);
$cache = Cache::get("member_address_getMemberAddressInfo_" . $data);
if (!empty($cache)) {
return $this->success($cache);
}
$res = model('member_address')->getInfo($condition, $field);
Cache::tag("member_address_" . $check_condition[ 'member_id' ])->set("member_address_getMemberAddressInfo_" . $data, $res);
return $this->success($res);
}
/**
* 获取收获地址列表
* @param array $condition
* @param string $field
* @param string $order
* @param string $limit
* @return multitype:string mixed
*/
public function getMemberAddressList($condition = [], $field = '*', $order = 'is_default desc', $limit = null)
{
$check_condition = array_column($condition, 2, 0);
$data = json_encode([ $condition, $field, $order, $limit ]);
$cache = Cache::get("member_address_getMemberAddressList_" . $data);
if (!empty($cache)) {
return $this->success($cache);
}
$list = model('member_address')->getList($condition, $field, $order, '', '', '', $limit);
Cache::tag("member_address_" . $check_condition[ 'member_id' ])->set("member_address_getMemberAddressList_" . $data, $list);
return $this->success($list);
}
/**
* 获取收获地址分页列表
* @param array $condition
* @param int $page
* @param int $page_size
* @param string $order
* @param string $field
* @return \multitype
*/
public function getMemberAddressPageList($condition = [], $page = 1, $page_size = PAGE_LIST_ROWS, $order = 'is_default desc,id desc', $field = 'id, member_id, name, mobile, telephone, address, full_address, is_default, type')
{
$check_condition = array_column($condition, 2, 0);
$data = json_encode([ $condition, $page, $page_size, $order, $field ]);
$cache = Cache::get("member_address_getMemberAddressList_" . $data);
if (!empty($cache)) {
return $this->success($cache);
}
$list = model('member_address')->pageList($condition, $field, $order, $page, $page_size);
Cache::tag("member_address_" . $check_condition[ 'member_id' ])->set("member_address_getMemberAddressPageList_" . $data, $list);
return $this->success($list);
}
//获取默认地址
public function getMemberDefault($member_id)
{
return model('member_address')->getInfo(['member_id'=>$member_id,'is_default'=>1,'type'=>1], 'id');
}
}

View File

@ -0,0 +1,162 @@
<?php
/**
* SAAS应用系统 --- 十年开发经验汇集巨献!
* ==========================================================
* Copy right 2020-2050 成都众联思索科技有限公司,保留所有权利。
* ----------------------------------------------------------
* 官方网址: https://www.zoomtk.com
* 这不是自由软件!未经允许不得用于商业目或程序代码摘取及修改。
* 任何企业和个人不允许对程序代码以任何形式任何目的再发布传播。
* 唯一发布渠道www.zoomtk.com;非官方渠道统一视为侵权行为。
* ==========================================================
*/
namespace addon\member\model;
use app\model\BaseModel;
/**
* 实名认证
*/
class MemberAuth extends BaseModel
{
//申请状态
private $status = [
1 => '审核通过',
0 => '待审核',
-1 => '审核失败',
];
/**
* 获取实名认证分页列表
*
* @param array $condition
* @param number $page
* @param string $page_size
* @param string $order
* @param string $field
*/
public function getMemberAuthPageList($condition = [], $page = 1, $page_size = PAGE_LIST_ROWS, $order = '', $field = '*')
{
$list = model('member_auth')->pageList($condition, $field, $order, $page, $page_size, '', '', '');
return $this->success($list);
}
/**
* 获取实名认证列表
*
* @param array $condition
* @param number $page
* @param string $page_size
* @param string $order
* @param string $field
*/
public function getMemberAuthList($where = [], $field = true, $order = '', $alias = 'a', $join = [], $group = '', $limit = null)
{
$res = model('member_auth')->getList($where, $field, $order, $alias, $join, $group, $limit);
return $this->success($res);
}
/**
* 获取实名认证信息
* @param array $condition
* @param string $field
* @return unknown
*/
public function getMemberAuthInfo($condition = [], $field = '*')
{
$member_info = model('member_auth')->getInfo($condition, $field);
return $this->success($member_info);
}
/**
* 添加实名认证
* @param $data
*/
public function add($data)
{
$member_id = isset($data['member_id']) ? $data['member_id'] : '';
if ($member_id === '') {
return $this->error('', 'REQUEST_SITE_ID');
}
$data["create_time"] = time();
$result = model("member_auth")->add($data);
if ($result === false) {
return $this->error('', 'UNKNOW_ERROR');
}
return $this->success($result);
}
/**
* 编辑实名认证
* @param $data
* @param $condition
*/
public function edit($data, $condition)
{
$check_condition = array_column($condition, 2, 0);
$member_id = isset($check_condition['member_id']) ? $check_condition['member_id'] : '';
$auth_id = isset($check_condition['auth_id']) ? $check_condition['auth_id'] : '';
if ($member_id === '') {
return $this->error('', '会员ID不能为空');
}
if ($auth_id === '') {
return $this->error('', '实名认证ID不能为空');
}
$res = model("member_auth")->update($data, $condition);
if ($res === false) {
return $this->error('', 'UNKNOW_ERROR');
}
return $this->success($res);
}
/**
* 实名认证 审核通过 后台审核
* @param unknown $auth_id
*/
public function authPass($auth_id)
{
// 开启事务
model('member_auth')->startTrans();
try {
//获取实名认证 信息
$member_auth_info = model('member_auth')->getInfo([['auth_id', '=', $auth_id]]);
//获取会员id
$member_id = $member_auth_info['member_id'];
// 会员用户实名修改
model('member')->update(['is_auth' => 1], [['member_id', '=', $member_id]]);
// 会员实名认证通过修改
$res = model('member_auth')->update(['status' => 1, 'audit_time' => time()], [['auth_id', '=', $auth_id]]);
// 事务提交
model('member_auth')->commit();
return $this->success($res);
} catch (\Exception $e) {
// 事务回滚
model('member_auth')->rollback();
return $this->error('', $e->getMessage());
}
}
/**
* 审核拒绝
* @param unknown $auth_id
* @param unknown $reason
*/
public function authReject($auth_id, $reason)
{
$res = model('member_auth')->update(['status' => -1, 'remark' => $reason], [['auth_id', '=', $auth_id]]);
return $this->success($res);
}
/**
* 获取实名审核状态
*/
public function getAuthStatus()
{
return $this->status;
}
}

View File

@ -0,0 +1,212 @@
<?php
/**
* SAAS应用系统 --- 十年开发经验汇集巨献!
* ==========================================================
* Copy right 2020-2050 成都众联思索科技有限公司,保留所有权利。
* ----------------------------------------------------------
* 官方网址: https://www.zoomtk.com
* 这不是自由软件!未经允许不得用于商业目或程序代码摘取及修改。
* 任何企业和个人不允许对程序代码以任何形式任何目的再发布传播。
* 唯一发布渠道www.zoomtk.com;非官方渠道统一视为侵权行为。
* ==========================================================
*/
namespace addon\member\model;
use app\model\BaseModel;
use think\facade\Cache;
/**
* 会员提现账号
*/
class MemberBankAccount extends BaseModel
{
private $withdraw_type = [
'alipay' => '支付宝',
'bank' => '银行卡',
'wechatpay' => '微信'
];
public function getWithdrawType()
{
return $this->withdraw_type;
}
/**
* 添加会员提现账号
* @param $data
* @return array
*/
public function addMemberBankAccount($data)
{
//获取提现设置
$config_model = new Withdraw();
$config_result = $config_model->getConfig(1, 'shop');
$config = $config_result['data']['value'];
if (!empty($config)) {
//提现方式为微信的时候 判断用户是否已关注公众号
if ($data['withdraw_type'] == 'wechatpay') {
//获取会员信息
$uniFans=new \addon\member\model\UniFans();
$member_info = $uniFans->where('uid',$data["member_id"])->column('open_id','app_type');
if (empty($member_info['wechat']) && empty($member_info['weapp'])) {
return $this->error('', '请先绑定微信');
}
}
model('member_bank_account')->startTrans();
try {
if ($data['is_default'] == 1) {
model('member_bank_account')->update(['is_default' => 0], ['member_id' => $data['member_id']]);
}
$data['create_time'] = time();
$id = model('member_bank_account')->add($data);
$count = model('member_bank_account')->getCount(['member_id' => $data['member_id']]);
if ($count == 1)
model('member_bank_account')->update(['is_default' => 1], ['member_id' => $data['member_id'], 'id' => $id]);
Cache::tag("member_bank_account_" . $data['member_id'])->clear();
model('member_bank_account')->commit();
return $this->success($id);
} catch (\Exception $e) {
model('member_bank_account')->rollback();
return $this->error('', $e->getMessage());
}
} else {
return $this->error('', '平台未开启会员提现');
}
}
/**
* 修改会员提现账号
* @param $data
* @return array
*/
public function editMemberBankAccount($data)
{
//获取提现设置
$config_model = new Withdraw();
$config_result = $config_model->getConfig(1, 'shop');
$config = $config_result['data']['value'];
if (!empty($config)) {
//提现方式为微信的时候 判断用户是否已关注公众号
if ($data['withdraw_type'] == 'wechatpay') {
//获取会员信息
$uniFans=new \addon\member\model\UniFans();
$member_info = $uniFans->where('uid',$data["member_id"])->column('open_id','app_type');
if (empty($member_info['wechat']) && empty($member_info['weapp'])) {
return $this->error('', '请先绑定微信');
}
}
model('member_bank_account')->startTrans();
try {
if ($data['is_default'] == 1) {
model('member_bank_account')->update(['is_default' => 0], ['member_id' => $data['member_id']]);
}
$data['modify_time'] = time();
$res = model('member_bank_account')->update($data, ['id' => $data['id']]);
Cache::tag("member_bank_account_" . $data['member_id'])->clear();
model('member_bank_account')->commit();
return $this->success($res);
} catch (\Exception $e) {
model('member_bank_account')->rollback();
return $this->error('', $e->getMessage());
}
} else {
return $this->error('', '平台未开启会员提现');
}
}
/**
* 删除会员提现账号
* @param array $condition
*/
public function deleteMemberBankAccount($condition)
{
$check_condition = array_column($condition, 2, 0);
$res = model('member_bank_account')->delete($condition);
Cache::tag("member_bank_account_" . $check_condition['member_id'])->clear();
if ($res === false) {
return $this->error('', 'RESULT_ERROR');
}
return $this->success($res);
}
/**
* 设置默认会员提现账号
* @param $id
* @param $member_id
* @return \multitype
*/
public function modifyDefaultAccount($id, $member_id)
{
model('member_bank_account')->startTrans();
try {
model('member_bank_account')->update(['is_default' => 0], ['member_id' => $member_id]);
$res = model('member_bank_account')->update(['is_default' => 1], ['member_id' => $member_id, 'id' => $id]);
model('member_bank_account')->commit();
Cache::tag("member_bank_account_" . $member_id)->clear();
return $this->success($res);
} catch (\Exception $e) {
model('member_bank_account')->rollback();
return $this->error('', $e->getMessage());
}
}
/**
* 获取会员提现账号信息
* @param $condition
* @param string $field
* @return array
*/
public function getMemberBankAccountInfo($condition, $field = '*')
{
$check_condition = array_column($condition, 2, 0);
$data = json_encode([$condition, $field]);
$cache = Cache::get("member_bank_account_getMemberBankAccountInfo_" . $data);
if (!empty($cache)) {
return $this->success($cache);
}
$res = model('member_bank_account')->getInfo($condition, $field);
Cache::tag("member_bank_account_" . $check_condition['member_id'])->set("member_bank_account_getMemberBankAccountInfo_" . $data, $res);
return $this->success($res);
}
/**
* 获取会员提现账号分页列表
* @param array $condition
* @param int $page
* @param int $page_size
* @param string $order
* @param string $field
* @return array|\multitype
*/
public function getMemberBankAccountPageList($condition = [], $page = 1, $page_size = PAGE_LIST_ROWS, $order = 'create_time desc', $field = '*')
{
$check_condition = array_column($condition, 2, 0);
$data = json_encode([$condition, $field, $order, $page, $page_size]);
$cache = Cache::get("member_bank_account_getMemberBankAccountPageList_" . $data);
if (!empty($cache)) {
return $this->success($cache);
}
$list = model('member_bank_account')->pageList($condition, $field, $order, $page, $page_size);
Cache::tag("member_bank_account_" . $check_condition['member_id'])->set("member_bank_account_getMemberBankAccountPageList_" . $data, $list);
return $this->success($list);
}
}

View File

@ -0,0 +1,428 @@
<?php
/**
* SAAS应用系统 --- 十年开发经验汇集巨献!
* ==========================================================
* Copy right 2020-2050 成都众联思索科技有限公司,保留所有权利。
* ----------------------------------------------------------
* 官方网址: https://www.zoomtk.com
* 这不是自由软件!未经允许不得用于商业目或程序代码摘取及修改。
* 任何企业和个人不允许对程序代码以任何形式任何目的再发布传播。
* 唯一发布渠道www.zoomtk.com;非官方渠道统一视为侵权行为。
* ==========================================================
*/
namespace addon\member\model;
use app\model\BaseModel;
use think\facade\Db;
use addon\coupon\model\Coupon;
use app\model\system\Cron;
/**
* 会员群体
*/
class MemberCluster extends BaseModel
{
public $basic = [
'member_level' => '会员等级',
'member_label' => '会员标签',
'sex' => '性别',
'birthday' => '生日',
'reg_time' => '注册时间',
'point' => '当前积分',
'balance' => '当前余额',
'growth' => '当前成长值',
'sign_days_series' => '连续签到次数',
'mobile' => '会员手机',
];
public $consume = [
'order_money' => '付款金额',
'order_complete_money' => '消费金额',
'order_num' => '付款次数',
'order_complete_num' => '消费次数',
'recharge_total' => '累计充值',
'recharge_time' => '充值次数',
];
public $promotion = [
'coupon_num' => '优惠券数',
];
/**
* 查询规则
*/
public $rule = [
'member_level' => ['field' => "member_level",'query_method' => "FIND_IN_SET", "table" => "member"],
'member_label' => ['field' => "member_label",'query_method' => "FIND_IN_SET", "table" => "member"],
'sex' => ['field' => "sex",'query_method' => "in", "table" => "member"],
'birthday' => ['field' => "birthday",'query_method' => "between time", "table" => "member"],
'reg_time' => ['field' => "reg_time",'query_method' => "between time", "table" => "member"],
'point' => ['field' => "point",'query_method' => "between", "table" => "member"],
'balance' => ['field' => "balance",'query_method' => "between", "table" => "member"],
'growth' => ['field' => "growth",'query_method' => "between", "table" => "member"],
'sign_days_series' => ['field' => "sign_days_series",'query_method' => "between", "table" => "member"],
'mobile' => ['field' => "mobile",'query_method' => "like", "table" => "member"],
'order_money' => ['field' => "order_money",'query_method' => "between", "table" => "member"],
'order_complete_money' => ['field' => "order_complete_money",'query_method' => "between", "table" => "member"],
'order_num' => ['field' => "order_num",'query_method' => "between", "table" => "member"],
'order_complete_num' => ['field' => "order_complete_num",'query_method' => "between", "table" => "member"],
'recharge_total' => ['field' => "recharge_total",'query_method' => "between", "table" => "member_recharge_order"],
'recharge_time' => ['field' => "recharge_time",'query_method' => "between", "table" => "member_recharge_order"],
'coupon_num' => ['field' => "coupon_num",'query_method' => "between", "table" => "promotion_coupon"]
];
/**
* 添加会员群体
* @param $data
* @return array
*/
public function addMemberCluster($data)
{
//重新计算符合会员群体的会员
$calculate_data = $this->calculate($data);
$data['member_num'] = $calculate_data['data']['member_num'];
$data['member_ids'] = $calculate_data['data']['member_ids'];
$res = model('member_cluster')->add($data);
return $this->success($res);
}
/**
* 编辑会员群体
* @param $data
* @param $condition
* @return array
*/
public function editMemberCluster($data, $condition)
{
//重新计算符合会员群体的会员
$calculate_data = $this->calculate($data);
$data['member_num'] = $calculate_data['data']['member_num'];
$data['member_ids'] = $calculate_data['data']['member_ids'];
$res = model('member_cluster')->update($data, $condition);
return $this->success($res);
}
/**
* 删除会员群体
* @param $condition
* @return array
*/
public function deleteMemberCluster($condition)
{
$res = model('member_cluster')->delete($condition);
return $this->success($res);
}
/**
* 会员群体信息
* @param array $condition
* @param string $field
* @return array
*/
public function getMemberClusterInfo($condition = [], $field = '*')
{
$info = model('member_cluster')->getInfo($condition, $field);
return $this->success($info);
}
/**
* 会员群体详情
* @param array $condition
* @param string $field
* @return array
*/
public function getMemberClusterDetail($condition = [], $field = '*')
{
$info = model('member_cluster')->getInfo($condition, $field);
$info['rule_arr'] = json_decode($info['rule_json'],true);
//获取标签
$member_label_content = $info['rule_arr']['basic']['member_label']['content'];
$info['rule_arr']['basic']['member_label']['content_name'] = '';
if(!empty($member_label_content)){
$member_label_list = model('member_label')->getColumn([ ["label_id", "in", $member_label_content] ],'label_name');
$info['rule_arr']['basic']['member_label']['content_name'] = implode(",",$member_label_list);
}
//获取等级
$member_level_content = $info['rule_arr']['basic']['member_level']['content'];
$info['rule_arr']['basic']['member_level']['content_name'] = '';
if(!empty($member_level_content)) {
$member_level_list = model('member_level')->getColumn([ ["level_id", "in", $member_level_content] ],'level_name');
$info['rule_arr']['basic']['member_level']['content_name'] = implode(",", $member_level_list);
}
//获取性别
$member_sex_content = $info['rule_arr']['basic']['sex']['content'];
$info['rule_arr']['basic']['sex']['content_arr'] = [];
if(!empty($member_sex_content)) {
$info['rule_arr']['basic']['sex']['content_arr'] = explode(",", $member_sex_content);
}
return $this->success($info);
}
/**
* 会员群体列表
* @param array $condition
* @param string $field
* @param string $order
* @param null $limit
* @return array
*/
public function getMemberClusterList($condition = [], $field = '*', $order = 'cluster_id asc', $limit = null)
{
$list = model('member_cluster')->getList($condition, $field, $order, '', '', '', $limit);
return $this->success($list);
}
/**
* 会员群体分页列表
* @param array $condition
* @param int $page
* @param int $page_size
* @param string $order
* @param string $field
* @return array
*/
public function getMemberClusterPageList($condition = [], $page = 1, $page_size = PAGE_LIST_ROWS, $order = 'cluster_id asc', $field = '*')
{
$list = model('member_cluster')->pageList($condition, $field, $order, $page, $page_size);
return $this->success($list);
}
/**
* 计算人数
* @param $data
* @return array
*/
public function calculate($data)
{
//根据规则获得条件
$condition = $this->handleRule($data['rule_json']);
$condition[] = ["site_id",'=',$data['site_id']];
//只查询正常用户
$condition[] = ['is_delete', '=', 0];
$member_arr = model('member')->getColumn($condition,'member_id');
$member_ids = implode(',',$member_arr);
$member_num = model('member')->getCount($condition);
return $this->success(["member_num" => $member_num, "member_ids" => $member_ids]);
}
/**
* 处理规则条件
* @param $rule_json
* @return array
*/
public function handleRule($rule_json)
{
$rule_arr = json_decode($rule_json,true);
$all_field = array_merge($this->basic,$this->consume,$this->promotion);
$condition = [];
foreach ($rule_arr as $key => $value){
//获取键
$keys = array_keys($value);
foreach ($keys as $key) {
if (array_key_exists($key, $all_field)) {
$values = $value[$key];
$query_method = $this->rule[$key]['query_method'];
$start = isset($values['start']) ? $values['start'] : '';
$end = isset($values['end']) ? $values['end'] : '';
$content = isset($values['content']) ? $values['content'] : '';
$include = $values['include'] == 2 ? "not " : "";
$is_show = $values['is_show'];
if($is_show == 1){
switch ($query_method) {
case "between":
$condition[] = [$key, $include.'between', [$start,$end]];
break;
case "between time":
if($values['include'] == 1){
//注册时间
if ($start != '' && $end != '') {
$condition[] = [ $key, 'between', [ strtotime($start), strtotime($end) ] ];
} else if ($start != '' && $end == '') {
$condition[] = [ $key, '>=', strtotime($start) ];
} else if ($start == '' && $end != '') {
$condition[] = [ $key, '<=', strtotime($end) ];
}
}else if($values['include'] == 2){
//注册时间
if ($start != '' && $end != '') {
$condition[] = [ $key, $include.'between', [ strtotime($start), strtotime($end) ] ];
} else if ($start != '' && $end == '') {
$condition[] = [ $key, '<', strtotime($start) ];
} else if ($start == '' && $end != '') {
$condition[] = [ $key, '>', strtotime($end) ];
}
}
break;
case "in":
$condition[] = [$key, $include.'in', $content];
break;
case "like":
$condition[] = [$key, $include.'like', "%" . $content . "%"];
break;
case "FIND_IN_SET":
//使用like搜索 暂不使用find_in_set 不可用包含不包含
// $content_arr = explode(",",$content);
// $temp_sql = '';
// foreach ($content_arr as $content_value){
// if(empty($temp_sql)){
// $temp_sql .= "FIND_IN_SET({$content_value}, member_label)";
// }else{
// $temp_sql .= " or FIND_IN_SET({$content_value}, member_label)";
// }
// }
// $condition[] = [ "", 'exp', Db::raw($temp_sql) ];
$content_arr = explode(",",$content);
if($values['include'] == 1){
$find_in_set = "or";
$find_in_set_method = "like";
}else if($values['include'] == 2){
$find_in_set = "and";
$find_in_set_method = "not like";
}
$temp_arr = [];
foreach ($content_arr as $content_value){
$content_condition = [ $content_value, '%' . $content_value . ',%', '%' . $content_value, '%,' . $content_value . ',%' ];
$temp_arr = array_merge($content_condition,$temp_arr);
}
$condition[] = [ $key, $find_in_set_method, $temp_arr, $find_in_set ];
break;
case 4://其他表数据
break;
}
}
}
}
}
return $condition;
}
/**
* 自动定时刷新数据
* @return array
*/
public function refreshMemberCluster()
{
$list = model('member_cluster')->getList([],'rule_json,site_id,cluster_id');
//循环刷新事件
foreach ($list as $value){
$calculate_data = $this->calculate($value)['data'];
model("member_cluster")->update(["member_num" => $calculate_data['member_num'], "member_ids" => $calculate_data['member_ids'], "update_time" => time()],["cluster_id" => $value['cluster_id']]);
}
return $this->success();
}
/**
* 发放积分
* @param $point
* @param $cluster_id
* @param $remark
* @return array
*/
public function sendPoint($point, $cluster_id, $remark)
{
$member_cluster_info = model("member_cluster")->getInfo(["cluster_id" => $cluster_id],"member_ids");
$member_list = model("member")->getList([ ["member_id", "in", $member_cluster_info["member_ids"]] ],'site_id,member_id');
$member_account_model = new MemberAccount();
model('member_account')->startTrans();
try {
foreach ($member_list as $value){
$member_account_model->addMemberAccount($value[ 'site_id' ], $value['member_id'], 'point', $point, 'adjust', '会员群体发放积分' . $point, $remark);
}
model('member_account')->commit();
return $this->success();
} catch (\Exception $e) {
model('member_account')->rollback();
return $this->error('', $e->getMessage());
}
}
/**
* 发放余额
* @param $balance
* @param $cluster_id
* @param $remark
* @return array
*/
public function sendBalance($balance, $cluster_id, $remark)
{
$member_cluster_info = model("member_cluster")->getInfo(["cluster_id" => $cluster_id],"member_ids");
$member_list = model("member")->getList([ ["member_id", "in", $member_cluster_info["member_ids"]] ],'site_id,member_id');
$member_account_model = new MemberAccount();
model('member_account')->startTrans();
try {
foreach ($member_list as $value){
$member_account_model->addMemberAccount($value[ 'site_id' ], $value['member_id'], 'balance', $balance, 'adjust', '会员群体发放红包' . $balance, $remark);
}
model('member_account')->commit();
return $this->success();
} catch (\Exception $e) {
model('member_account')->rollback();
return $this->error('', $e->getMessage());
}
}
/**
* 发放优惠券
* @param $coupon
* @param $cluster_id
* @return array
*/
public function sendCoupon($coupon, $cluster_id)
{
$member_cluster_info = model("member_cluster")->getInfo(["cluster_id" => $cluster_id],"member_ids");
$member_list = model("member")->getList([ ["member_id", "in", $member_cluster_info["member_ids"]] ],'site_id,member_id');
model('promotion_coupon')->startTrans();
try {
foreach ($member_list as $value){
$coupon_model = new Coupon();
$coupon_array = explode(',', $coupon);
foreach ($coupon_array as $k => $v) {
$coupon_model->receiveCoupon($v, $value[ 'site_id' ], $value['member_id'], 3);
}
}
model('promotion_coupon')->commit();
return $this->success();
} catch (\Exception $e) {
model('promotion_coupon')->rollback();
return $this->error('', $e->getMessage());
}
}
/**
* 店铺初始化的时候添加定时任务
*/
public function addMemberClusterCronRefresh()
{
//添加会员群体刷新时间
$cron_model = new Cron();
$execute_time = time() + 60;
$res = $cron_model->addCron(2, 1, "会员群体定时刷新", "CronMemberClusterRefresh", $execute_time, 0);
return $this->success($res);
}
}

View File

@ -0,0 +1,140 @@
<?php
/**
* SAAS应用系统 --- 十年开发经验汇集巨献!
* ==========================================================
* Copy right 2020-2050 成都众联思索科技有限公司,保留所有权利。
* ----------------------------------------------------------
* 官方网址: https://www.zoomtk.com
* 这不是自由软件!未经允许不得用于商业目或程序代码摘取及修改。
* 任何企业和个人不允许对程序代码以任何形式任何目的再发布传播。
* 唯一发布渠道www.zoomtk.com;非官方渠道统一视为侵权行为。
* ==========================================================
*/
namespace addon\member\model;
use think\facade\Cache;
use app\model\BaseModel;
/**
* 会员标签
*/
class MemberLabel extends BaseModel
{
/**
* 添加会员标签
*
* @param array $data
*/
public function addMemberLabel($data)
{
$res = model('member_label')->add($data);
Cache::tag("member_label")->clear();
return $this->success($res);
}
/**
* 修改会员标签
*
* @param array $data
* @param array $condition
*/
public function editMemberLabel($data, $condition)
{
$res = model('member_label')->update($data, $condition);
Cache::tag("member_label")->clear();
return $this->success($res);
}
/**
* 删除会员标签
* @param array $condition
*/
public function deleteMemberLabel($condition)
{
$res = model('member_label')->delete($condition);
Cache::tag("member_label")->clear();
return $this->success($res);
}
/**
* 修改标签排序
* @param int $sort
* @param int $label_id
*/
public function modifyMemberLabelSort($sort, $label_id)
{
$res = model('member_label')->update(['sort' => $sort], [['label_id', '=', $label_id]]);
Cache::tag("member_label")->clear();
return $this->success($res);
}
/**
* 获取会员标签信息
*
* @param array $condition
* @param string $field
*/
public function getMemberLabelInfo($condition = [], $field = '*')
{
$data = json_encode([$condition, $field]);
$cache = Cache::get("member_label_getMemberLabelInfo_" . $data);
if (!empty($cache)) {
return $this->success($cache);
}
$info = model('member_label')->getInfo($condition, $field);
Cache::tag("member_label")->set("member_label_getMemberLabelInfo_" . $data, $info);
return $this->success($info);
}
/**
* 获取会员标签列表
*
* @param array $condition
* @param string $field
* @param string $order
* @param string $limit
*/
public function getMemberLabelList($condition = [], $field = '*', $order = 'sort asc, label_id asc', $limit = null)
{
$data = json_encode([$condition, $field, $order, $limit]);
$cache = Cache::get("member_label_getMemberLabelList_" . $data);
if (!empty($cache)) {
return $this->success($cache);
}
$list = model('member_label')->getList($condition, $field, $order, '', '', '', $limit);
Cache::tag("member_label")->set("member_label_getMemberLabelList_" . $data, $list);
return $this->success($list);
}
/**
* 获取会员标签分页列表
*
* @param array $condition
* @param number $page
* @param string $page_size
* @param string $order
* @param string $field
*/
public function getMemberLabelPageList($condition = [], $page = 1, $page_size = PAGE_LIST_ROWS, $order = 'sort asc, level_id asc', $field = '*')
{
$data = json_encode([$condition, $field, $order, $page, $page_size]);
$cache = Cache::get("member_label_getMemberLabelPageList_" . $data);
if (!empty($cache)) {
return $this->success($cache);
}
$list = model('member_label')->pageList($condition, $field, $order, $page, $page_size);
Cache::tag("member_label")->set("member_label_getMemberLabelPageList_" . $data, $list);
return $this->success($list);
}
}

View File

@ -0,0 +1,329 @@
<?php
/**
* SAAS应用系统 --- 十年开发经验汇集巨献!
* ==========================================================
* Copy right 2020-2050 成都众联思索科技有限公司,保留所有权利。
* ----------------------------------------------------------
* 官方网址: https://www.zoomtk.com
* 这不是自由软件!未经允许不得用于商业目或程序代码摘取及修改。
* 任何企业和个人不允许对程序代码以任何形式任何目的再发布传播。
* 唯一发布渠道www.zoomtk.com;非官方渠道统一视为侵权行为。
* ==========================================================
*/
namespace addon\member\model;
use addon\coupon\model\Coupon;
use app\model\system\Cron;
use think\facade\Cache;
use app\model\BaseModel;
use addon\coupon\model\CouponType;
/**
* 会员等级
*/
class MemberLevel extends BaseModel
{
public $level_change_type = [
'upgrade' => '自动升级',
'buy' => '付费购卡',
'adjust' => '商家调整',
'expire' => '到期降级'
];
public $level_time = [
'week' => '一周',
'month' => '一月',
'quarter' => '一季',
'year' => '一年',
];
/**
* 添加会员等级
*
* @param array $data
*/
public function addMemberLevel($data)
{
$res = model('member_level')->add($data);
Cache::tag("member_level")->clear();
return $this->success($res);
}
/**
* 修改会员等级(不允许批量处理)
*
* @param array $data
* @param array $condition
*/
public function editMemberLevel($data, $condition)
{
$res = model('member_level')->update($data, $condition);
$check_condition = array_column($condition, 2, 0);
$level_id = isset($check_condition[ 'level_id' ]) ? $check_condition[ 'level_id' ] : 0;
if (!empty($level_id) && isset($data['level_name'])) {
model('member')->update([ 'member_level_name' => $data['level_name'] ], [ ['member_level', '=', $level_id] ]);
}
Cache::tag("member_level")->clear();
return $this->success();
}
/**
* 刷新会员等级排序
*/
private function refreshSort($site_id)
{
$list = model('member_level')->getList([['site_id', '=', $site_id]], 'level_id, growth', 'growth asc');
foreach ($list as $k => $v) {
model('member_level')->update(['sort' => $k], [['level_id', '=', $v['level_id']]]);
}
}
/**
* 刷新会员等级
*/
private function refreshLevel($site_id)
{
model('member_level')->update(['is_default' => 0], [['is_default', '=', 1], ['site_id', '=', $site_id]]);
}
/**
* 删除会员等级
* @param array $condition
*/
public function deleteMemberLevel($level_id, $site_id)
{
$count = model('member')->getCount([ ['member_level', '=', $level_id], ['is_delete', '=', 0] ]);
if ($count > 0) return $this->error('', '有会员正持有该卡不可删除');
$condition = [
['level_id', '=', $level_id],
['site_id', '=', $site_id],
];
$res = model('member_level')->delete($condition);
Cache::tag("member_level")->clear();
return $this->success($res);
}
/**
* 获取一条等级
* @param $condition
* @param string $field
* @param string $order
* @return array
*/
public function getFirstMemberLevel($condition, $field = '*', $order = ""){
$data = model('member_level')->getFirstData($condition, $field, $order);
return $this->success($data);
}
/**
* 获取会员等级信息
*
* @param array $condition
* @param string $field
*/
public function getMemberLevelInfo($condition = [], $field = '*')
{
$data = json_encode([$condition, $field]);
$cache = Cache::get("member_level_getMemberLevelInfo_" . $data);
if (!empty($cache)) {
return $this->success($cache);
}
$info = model('member_level')->getInfo($condition, $field);
if ($info) {
//获取优惠券信息
if (isset($info['send_coupon']) && !empty($info['send_coupon'])) {
//优惠券字段
$coupon_field = 'coupon_type_id,type,coupon_name,image,money,discount,validity_type,fixed_term,status,is_limit,at_least,count,lead_count,end_time';
$model = new CouponType();
$coupon = $model->getCouponTypeList([['coupon_type_id', 'in', $info['send_coupon']]], $coupon_field);
$info['coupon_list'] = $coupon;
}
}
Cache::tag("member_level")->set("member_level_getMemberLevelInfo_" . $data, $info);
return $this->success($info);
}
/**
* 获取会员等级列表
*
* @param array $condition
* @param string $field
* @param string $order
* @param string $limit
*/
public function getMemberLevelList($condition = [], $field = '*', $order = 'sort asc, level_id asc', $limit = null)
{
$data = json_encode([$condition, $field, $order, $limit]);
$cache = Cache::get("member_level_getMemberLevelList_" . $data);
if (!empty($cache)) {
return $this->success($cache);
}
$list = model('member_level')->getList($condition, $field, $order, '', '', '', $limit);
Cache::tag("member_level")->set("member_level_getMemberLevelList_" . $data, $list);
return $this->success($list);
}
/**
* 获取会员等级分页列表
*
* @param array $condition
* @param number $page
* @param string $page_size
* @param string $order
* @param string $field
*/
public function getMemberLevelPageList($condition = [], $page = 1, $page_size = PAGE_LIST_ROWS, $order = 'sort asc, level_id asc', $field = '*')
{
$data = json_encode([$condition, $field, $order, $page, $page_size]);
$cache = Cache::get("member_level_getMemberLevelPageList_" . $data);
if (!empty($cache)) {
return $this->success($cache);
}
$list = model('member_level')->pageList($condition, $field, $order, $page, $page_size);
Cache::tag("member_level")->set("member_level_getMemberLevelPageList_" . $data, $list);
return $this->success($list);
}
/**
* 添加会员卡变更记录
* @param $member_id 变更会员
* @param $site_id 站点id
* @param $after_level 变更之后的会员卡
* @param $action_uid 操作人
* @param $action_type 操作人类型
* @param $action_name 操作人昵称
* @param string $action_desc 描述
*/
public function addMemberLevelChangeRecord($member_id, $site_id, $after_level, $expire_time, $change_type, $action_uid, $action_type, $action_name, $action_desc = ''){
model('member_level_records')->startTrans();
try {
$member_info = model('member')->getInfo([ ['member_id', '=', $member_id] ], 'member_level,member_level_name,member_level_type,level_expire_time');
$level_info = model('member_level')->getInfo([ ['level_id', '=', $after_level], ['site_id', '=', $site_id] ], 'level_id,level_name,level_type');
if ($member_info['member_level'] == $level_info['level_id']) {
model('member_level_records')->rollback();
return $this->success('', '会员卡未发生变更');
}
$prev_record = model('member_level_records')->getFirstData([ ['member_id', '=', $member_id] ], 'id', 'change_time desc');
// 添加变更记录
$data = [
'member_id' => $member_id,
'site_id' => $site_id,
'before_level_id' => $member_info['member_level'],
'before_level_name' => $member_info['member_level_name'],
'before_level_type' => $member_info['member_level_type'],
'before_expire_time' => $member_info['level_expire_time'],
'after_level_id' => $level_info['level_id'],
'after_level_name' => $level_info['level_name'],
'after_level_type' => $level_info['level_type'],
'prev_id' => $prev_record['id'] ?? 0,
'change_time' => time(),
'action_uid' => $action_uid,
'action_type' => $action_type,
'action_name' => $action_name,
'action_desc' => $action_desc,
'change_type' => $change_type,
'change_type_name' => $this->level_change_type[$change_type]
];
model('member_level_records')->add($data);
// 变更会员等级
model('member')->update([
'member_level' => $level_info['level_id'],
'member_level_name' => $level_info['level_name'],
'member_level_type' => $level_info['level_type'],
'level_expire_time' => $expire_time
], [ ['member_id','=',$member_id] ]);
$cron = new Cron();
$cron->deleteCron([ ['event', '=', 'MemberLevelAutoExpire'], ['relate_id', '=', $member_id ] ]);
if ($level_info['level_type']) {
$cron->addCron(1, 0, "会员卡自动过期", "MemberLevelAutoExpire", $expire_time, $member_id);
}
Cache::tag("member_level_records")->clear();
model('member_level_records')->commit();
return $this->success();
} catch (\Exception $e) {
model('member_level_records')->rollback();
return $this->error('', $e->getMessage());
}
}
/**
* 获取会员会员卡变更记录
* @param array $condition
* @param int $page
* @param int $list_rows
* @param string $field
* @param string $order
* @param string $alias
* @param array $join
* @param null $group
* @return array
*/
public function getMemberLevelRecordPageList($condition = [], $page = 1, $list_rows = PAGE_LIST_ROWS, $field = '*', $order = 'change_time desc', $alias = 'a', $join = [], $group = null){
$data = json_encode([$condition, $field, $order, $page, $list_rows, $alias, $join, $group]);
$cache = Cache::get("getMemberLevelRecordPageList" . $data);
if (!empty($cache)) {
return $this->success($cache);
}
$list = model('member_level_records')->pageList($condition, $field, $order, $page, $list_rows, $alias, $join, $group);
Cache::tag("member_level_records")->set("getMemberLevelRecordPageList" . $data, $list);
return $this->success($list);
}
/**
* 会员卡过期
* @param $member_id
*/
public function memberLevelExpire($member_id){
$member_info = model('member')->getInfo([ ['member_id', '=', $member_id] ], 'member_id,site_id,nickname,member_level,level_expire_time,growth');
if (!empty($member_info) && !empty($member_info['level_expire_time']) && $member_info['level_expire_time'] < time()) {
$alias = 'mlr';
$join = [
['member_level ml', 'ml.level_id = mlr.before_level_id', 'inner']
];
// 如果会员还存在未过期的付费会员卡
$level_info = model('member_level_records')->getFirstDataView([ ['before_expire_time', '>', time()], ['member_id', '=', $member_id] ], 'mlr.*', 'change_time desc', $alias, $join);
if (!empty($level_info)) {
$this->addMemberLevelChangeRecord($member_id, $member_info['site_id'], $level_info['before_level_id'], $level_info['before_expire_time'], 'expire', $member_id, 'member', $member_info['nickname']);
} else {
// 如果之前免费卡还存在
$level_info = model('member_level_records')->getFirstDataView([ ['before_level_type', '=', 0], ['member_id', '=', $member_id] ], 'mlr.*', 'change_time desc', $alias, $join);
if (!empty($level_info)) {
$this->addMemberLevelChangeRecord($member_id, $member_info['site_id'], $level_info['before_level_id'], $level_info['before_expire_time'], 'expire', $member_id, 'member', $member_info['nickname']);
event("AddMemberAccount", ['account_type' => 'growth', 'member_id' => $member_id, 'site_id' => $member_info['site_id']]);
} else {
// 如果之前的免费卡不存在
$level_info = model('member_level')->getFirstData([ ['site_id', '=', $member_info['site_id']], ['level_type', '=', 0], ['growth', '<=', $member_info['growth']] ], '*', 'growth desc');
if (!empty($level_info)) {
$this->addMemberLevelChangeRecord($member_id, $member_info['site_id'], $level_info['level_id'], 0, 'expire', $member_id, 'member', $member_info['nickname']);
$member_account = new MemberAccount();
//赠送红包
if ($level_info['send_balance'] > 0) {
$member_account->addMemberAccount($member_info['site_id'], $member_info['member_id'], 'balance', $level_info['send_balance'], 'upgrade', '会员升级得红包' . $level_info['send_balance'], '会员升级得红包' . $level_info['send_balance']);
}
//赠送积分
if ($level_info['send_point'] > 0) {
$member_account->addMemberAccount($member_info['site_id'], $member_info['member_id'], 'point', $level_info['send_point'], 'upgrade', '会员升级得积分' . $level_info['send_point'], '会员升级得积分' . $level_info['send_point']);
}
//给用户发放优惠券
if (!empty($level_info['send_coupon'])) {
$coupon_array = explode(',', $level_info['send_coupon']);
$coupon_model = new Coupon();
foreach ($coupon_array as $k => $v) {
$coupon_model->receiveCoupon($v, $member_info['site_id'], $member_info['member_id'], 3);
}
}
}
}
}
}
}
}

View File

@ -0,0 +1,117 @@
<?php
/**
* SAAS应用系统 --- 十年开发经验汇集巨献!
* ==========================================================
* Copy right 2020-2050 成都众联思索科技有限公司,保留所有权利。
* ----------------------------------------------------------
* 官方网址: https://www.zoomtk.com
* 这不是自由软件!未经允许不得用于商业目或程序代码摘取及修改。
* 任何企业和个人不允许对程序代码以任何形式任何目的再发布传播。
* 唯一发布渠道www.zoomtk.com;非官方渠道统一视为侵权行为。
* ==========================================================
*/
namespace addon\member\model;
use app\model\BaseModel;
use Carbon\Carbon;
/**
* 会员签到
*/
class MemberSignin extends BaseModel
{
/**
* 获取签到奖励规则
*/
public function getAward($site_id)
{
$award = event('MemberSigninAward', ['site_id' => $site_id], true);
return $this->success($award);
}
/**
* 判断是否已经签到
* @param $member_id
* @return array
*/
public function isSign($member_id)
{
$member_info = model("member")->getInfo([['member_id', '=', $member_id]], 'sign_time');
if ($member_info['sign_time'] != 0) {
$compare_time = Carbon::today()->timestamp;
if ($member_info['sign_time'] < $compare_time) {
$is_sign = 0;
} else {
$is_sign = 1;
}
//纠正连签天数
$compare_yesterday = Carbon::yesterday()->timestamp;
if ($compare_yesterday > $member_info['sign_time']) {
model("member")->update(['sign_days_series' => 0, 'sign_time' => 0], [['member_id', '=', $member_id]]);
}
} else {
$is_sign = 0;
}
return $this->success($is_sign);
}
/**
* 签到
* @param $member_id
* @return array|\multitype
*/
public function signin($member_id, $site_id)
{
$member_info = model("member")->getInfo([['member_id', '=', $member_id]], 'sign_time,sign_days_series');
if ($member_info['sign_time'] != 0) {
$compare_time = Carbon::today()->timestamp;
if ($member_info['sign_time'] < $compare_time) {
$is_sign = 0;
} else {
$is_sign = 1;
}
} else {
$is_sign = 0;
}
if ($is_sign == 1) {
return $this->error('', "SIGNED_IN");
} else {
$data_log = [
'member_id' => $member_id,
'action' => 'membersignin',
'action_name' => '会员签到',
'create_time' => time(),
'remark' => '会员签到'
];
model("member_log")->add($data_log);
//连续签到
$compare_yesterday = Carbon::yesterday()->timestamp;
if ($compare_yesterday < $member_info['sign_time']) {
model("member")->setInc([['member_id', '=', $member_id]], 'sign_days_series');
model("member")->update(['sign_time' => time()], [['member_id', '=', $member_id]]);
} else {
model("member")->update(['sign_days_series' => 1, 'sign_time' => time()], [['member_id', '=', $member_id]]);
}
//执行签到奖励
$res = event("MemberSignin", ['member_id' => $member_id, 'site_id' => $site_id], true);
return $this->success($res);
}
}
/**
* 获取签到记录
* @param array $condition
* @param string $field
* @param string $order
* @return array
*/
public function getMemberSigninList($condition = [],$field = '*',$order = 'create_time asc')
{
$list = model('member_log')->getList($condition,$field,$order);
return $this->success($list);
}
}

View File

@ -0,0 +1,377 @@
<?php
/**
* SAAS应用系统 --- 十年开发经验汇集巨献!
* ==========================================================
* Copy right 2020-2050 成都众联思索科技有限公司,保留所有权利。
* ----------------------------------------------------------
* 官方网址: https://www.zoomtk.com
* 这不是自由软件!未经允许不得用于商业目或程序代码摘取及修改。
* 任何企业和个人不允许对程序代码以任何形式任何目的再发布传播。
* 唯一发布渠道www.zoomtk.com;非官方渠道统一视为侵权行为。
* ==========================================================
*/
namespace addon\member\model;
use addon\wechat\model\Message as WechatMessage;
use app\model\upload\Upload;
use app\model\BaseModel;
use app\model\message\Sms;
use app\model\system\Stat;
use extend\NickName;
/**
* 登录
* @author Administrator
*/
class Register extends BaseModel
{
public $password = '000000';
/**
* 用户名密码注册(必传username password),之前检测重复性,判断用户名是否为手机,邮箱
* @param $data
* @return array|mixed
*/
public function usernameRegister($data)
{
$exist = $this->usernameExist($data['username'], $data['site_id']);
if ($exist) {
return $this->error("", "用户名已存在");
} else {
$member_level = new MemberLevel();
$member_level_info = $member_level->getMemberLevelInfo([['is_default', '=', 1], ['site_id', '=', $data['site_id']]], '*');
$member_level_info = $member_level_info['data'];
if (isset($data['source_member']) && !empty($data['source_member'])) {
$count = model("member")->getCount([['member_id', '=', $data['source_member']], ['site_id', '=', $data['site_id']], ['is_delete', '=', 0]]);
if (!$count) return $this->error('无推荐码');
}
$nickname = NickName::Name();
if (isset($data['avatarUrl']) && is_url($data['avatarUrl'])) {
$upload = new Upload($data['site_id'] ?: 0);
$res = $upload->setPath('upload/user/haedimg/')->remotePull($data['avatarUrl']);
if ($res['code'] >= 0) {
$data['headimg'] = $res['data']['pic_path'];
}
}
$data_reg = [
'site_id' => $data['site_id'],
'source_member' => isset($data['source_member']) ? $data['source_member'] : 0,
'username' => $data['username'],
'nickname' => $nickname,
'password' => data_md5($data['password']),
'headimg' => isset($data['headimg']) ? $data['headimg'] : '',
'member_level' => $member_level_info['level_id'],
'member_level_name' => $member_level_info['level_name'],
'reg_time' => time(),
'login_time' => time(),
'last_login_time' => time(),
'is_edit_username' => 1,
'login_type' => $data['app_type'] ?? '',
'login_type_name' => $data['app_type_name'] ?? '',
];
return $this->addMember($data_reg, $data, $member_level_info);
}
}
/**
* 手机号密码注册(必传mobile password),之前检测重复性
* @param $data
* @return array|mixed
*/
public function mobileRegister($data)
{
$member_level = new MemberLevel();
$member_level_info = $member_level->getMemberLevelInfo([['is_default', '=', 1], ['site_id', '=', $data['site_id']]], '*');
$member_level_info = $member_level_info['data'];
if (isset($data['source_member']) && !empty($data['source_member'])) {
$count = model("member")->getCount([['member_id', '=', $data['source_member']], ['site_id', '=', $data['site_id']]]);
if (!$count) return error(-1, '无效推荐人');
}
if (!isset($data['source_member'])) {
return error(-1, '请使用推荐人二维码注册');
}
if (isset($data['avatarUrl']) && is_url($data['avatarUrl'])) {
$upload = new Upload($data['site_id'] ?: 0);
$res = $upload->setPath('upload/user/haedimg/')->remotePull($data['avatarUrl']);
if ($res['code'] >= 0) {
$data['headimg'] = $res['data']['pic_path'];
}
}
if (isset($data['password']) && $data['password']) {
$this->password = $data['password'];
}
$nickname = NickName::Name();
if (isset($data['nickName']) && !empty($data['nickName'])) {
$nickname = preg_replace_callback('/./u',
function (array $match) {
return strlen($match[0]) >= 4 ? '' : $match[0];
},
$data['nickName']);
}
$username = $this->createRandUsername($data['site_id']);
$data_reg = [
'site_id' => $data['site_id'],
'source_member' => isset($data['source_member']) ? $data['source_member'] : 0,
'username' => $username,
'mobile' => $data['mobile'],
'nickname' => $nickname,
'password' => data_md5($this->password),
'headimg' => isset($data['headimg']) ? $data['headimg'] : '',
'member_level' => $member_level_info['level_id'],
'member_level_name' => $member_level_info['level_name'],
'reg_time' => time(),
'login_time' => time(),
'last_login_time' => time(),
'is_edit_username' => 1,
'login_type' => $data['app_type'] ?? '',
'login_type_name' => $data['app_type_name'] ?? '',
];
return $this->addMember($data_reg, $data, $member_level_info);
}
/**
* 第三方注册
* @param $data
*/
public function authRegister($data)
{
$member_level = new MemberLevel();
$member_level_info = $member_level->getMemberLevelInfo([['is_default', '=', 1], ['site_id', '=', $data['site_id']]], '*');
$member_level_info = $member_level_info['data'];
if (isset($data['source_member']) && !empty($data['source_member'])) {
$count = model("member")->getCount([['member_id', '=', $data['source_member']], ['site_id', '=', $data['site_id']]]);
if (!$count) return error(-1, '无效推荐人');
}
if (!isset($data['source_member'])) {
return error(-1, '请使用推荐人二维码注册');
}
if (isset($data['avatarUrl']) && is_url($data['avatarUrl'])) {
$upload = new Upload($data['site_id'] ?: 0);
$res = $upload->setPath('upload/user/haedimg/')->remotePull($data['avatarUrl']);
if ($res['code'] >= 0) {
$data['headimg'] = $res['data']['pic_path'];
}
}
$nickname = NickName::Name();
if (isset($data['nickName']) && !empty($data['nickName'])) {
$nickname = preg_replace_callback('/./u',
function (array $match) {
return strlen($match[0]) >= 4 ? '' : $match[0];
},
$data['nickName']);
}
$username = $this->createRandUsername($data['site_id']);
$data_reg = [
'site_id' => $data['site_id'],
'source_member' => isset($data['source_member']) ? $data['source_member'] : 1,
'username' => $username,
'nickname' => $nickname,
'password' => data_md5($this->password),
'headimg' => isset($data['headimg']) ? $data['headimg'] : '',
'member_level' => $member_level_info['level_id'],
'member_level_name' => $member_level_info['level_name'],
'reg_time' => time(),
'login_time' => time(),
'last_login_time' => time(),
'is_edit_username' => 1,
'login_type' => $data['app_type'] ?? '',
'login_type_name' => $data['app_type_name'] ?? '',
];
return $this->addMember($data_reg, $data, $member_level_info);
}
/**
* 添加会员
* @param $data
* @return array
*/
private function addMember($data, $rawdata = [], $member_level_info = [])
{
Member::startTrans();
try {
$res = Member::create($data);
if ($res) {
//添加统计
$data['member_id'] = $res['member_id'];
$rawdata['uid'] = $res['member_id'];
$res->rcode=createShareCode($res['member_id']);
$res->save();
$this->BindOpenid($rawdata);//添加第三方绑定
//添加站点统计
$stat = new Stat();
$stat->addShopStat(['member_count' => 1, 'site_id' => $rawdata['site_id']]);
//会员注册事件
event("MemberRegister", array_merge($data, $rawdata, $member_level_info));
Member::commit();
return $this->success($res['member_id']);
} else {
Member::rollback();
return $this->error();
}
} catch (\Exception $e) {
Member::rollback();
return $this->error('', $e->getMessage());
}
}
/**
* 生成随机用户名
* @param $site_id
*/
private function createRandUsername($site_id)
{
$usernamer = 'u_' . random_keys(10);
$count = model('member')->getCount([['username', '=', $usernamer]]);
if ($count) {
$usernamer = $this->createRandUsername($site_id);
return $usernamer;
} else {
return $usernamer;
}
}
/**
* 检测用户存在性(用户名)
* @param $username
* @return int
*/
public function usernameExist($username, $site_id)
{
$member_info = model("member")->getInfo(
[
['username|mobile', '=', $username],
['site_id', '=', $site_id],
['is_delete', '=', 0]
], 'member_id'
);
if (!empty($member_info)) {
return 1;
} else {
return 0;
}
}
/**
* 检测用户存在性(用户名) 存在返回1
* @param $mobile
* @return int
*/
public function mobileExist($mobile, $site_id)
{
$member_info = model("member")->getInfo(
[
['mobile', '=', $mobile],
['site_id', '=', $site_id],
['is_delete', '=', 0]
], 'member_id'
);
if (!empty($member_info)) {
return 1;
} else {
return 0;
}
}
/**
* 注册发送验证码
* @param $data
* @return array|mixed|void
*/
public function registerCode($data)
{
//发送短信
$sms_model = new Sms();
$var_parse = array(
"code" => $data["code"],//验证码
);
$data["sms_account"] = $data["mobile"] ?? '';//手机号
$data["var_parse"] = $var_parse;
$sms_result = $sms_model->sendMessage($data);
if ($sms_result["code"] < 0)
return $sms_result;
return $this->success();
}
/**
* 注册成功通知
* @param $data
* @return array|mixed|void
*/
public function registerSuccess($data)
{
$member_model = new Member();
$member_info_result = $member_model->getMemberInfo([["member_id", "=", $data["member_id"]]], "username,mobile,email,reg_time,wx_openid,last_login_type");
$member_info = $member_info_result["data"];
$name = $member_info["username"] == '' ? $member_info["mobile"] : $member_info["username"];
//发送短信
$var_parse = [
"shopname" => replaceSpecialChar($data['site_info']['site_name']), //商城名称
"username" => replaceSpecialChar($name), //会员名称
];
$data["sms_account"] = $member_info["mobile"] ?? '';//手机号
$data["var_parse"] = $var_parse;
$sms_model = new Sms();
$sms_result = $sms_model->sendMessage($data);
//发送模板消息
$wechat_model = new WechatMessage();
$data["openid"] = $member_info["wx_openid"];
$data["template_data"] = [
'keyword1' => $member_info["username"],
'keyword2' => time_to_date($member_info["reg_time"]),
];
$data["page"] = '';
$wechat_model->sendMessage($data);
return $this->success();
}
/**
* 拉取用户头像
* @param unknown $info
*/
private function pullHeadimg($data)
{
if (!empty($data['headimg']) && is_url($data['headimg'])) {
$url = __ROOT__ . '/api/member/pullheadimg?member_id=' . $data['member_id'];
http($url, 1);
}
}
/**
* 账号绑定(用户重新进行绑定)
* @param $data
* @return array
*/
public function BindOpenid($data)
{
if (isset($data['openid'])) {
$nickname = NickName::Name();
if (isset($data['nickName']) && !empty($data['nickName'])) {
$nickname = preg_replace_callback('/./u',
function (array $match) {
return strlen($match[0]) >= 4 ? '' : $match[0];
},
$data['nickName']);
}
$arr = [
'site_id' => isset($data['site_id']) ? $data['site_id'] : 0,
'uid' => $data['uid'] ?? 0,
'open_id' => $data['openid']??'',
'unionid' => $data['unionid'] ?? '',
'app_type' => $data['app_type'],
'nickname' => $nickname,
'headimg' => $data['headimg'] ?? '',
];
$model = new UniFans();
if ($info = $model->where(['open_id' => $arr['open_id'], 'site_id' => $arr['site_id']])->find()) {
$info->save($arr);
} else {
$model->save($arr);
}
}
return $this->success();
}
}

View File

@ -0,0 +1,41 @@
<?php
/**
* SAAS应用系统 --- 十年开发经验汇集巨献!
* ==========================================================
* Copy right 2020-2050 成都众联思索科技有限公司,保留所有权利。
* ----------------------------------------------------------
* 官方网址: https://www.zoomtk.com
* 这不是自由软件!未经允许不得用于商业目或程序代码摘取及修改。
* 任何企业和个人未经允许对程序代码以任何形式任何目的再发布传播。
* 唯一发布渠道www.zoomtk.com;非官方渠道统一视为侵权行为。
* ==========================================================
*/
namespace addon\member\model;
use think\model;
class UniFans extends model
{
/***
* 返回当前用户信息
* @return model\relation\HasOne
*/
public function bindMember()
{
return $this->hasOne(Member::class,'member_id','uid')->withoutField('password,pay_password');
}
/***
* 获取昵称
* @param $value
* @return mixed
*/
public function getNicknameAttr($value){
return emojiDecode($value);
}
/**
* 设置昵称
* @param $value
* @return mixed|string
*/
public function setNicknameAttr($value){
return emojiEncode($value);
}
}

View File

@ -0,0 +1,567 @@
<?php
/**
* SAAS应用系统 --- 十年开发经验汇集巨献!
* ==========================================================
* Copy right 2020-2050 成都众联思索科技有限公司,保留所有权利。
* ----------------------------------------------------------
* 官方网址: https://www.zoomtk.com
* 这不是自由软件!未经允许不得用于商业目或程序代码摘取及修改。
* 任何企业和个人不允许对程序代码以任何形式任何目的再发布传播。
* 唯一发布渠道www.zoomtk.com;非官方渠道统一视为侵权行为。
* ==========================================================
*/
namespace addon\member\model;
use app\model\BaseModel;
use app\model\message\Message;
use app\model\message\Sms;
use app\model\shop\ShopAcceptMessage;
use app\model\system\Config as ConfigModel;
use app\model\system\Pay;
use think\facade\Cache;
use addon\memberwithdraw\model\Withdraw as MemberWithdraw;
use addon\wechat\model\Message as WechatMessage;
use addon\weapp\model\Message as WeappMessage;
/**
* 会员提现
*/
class Withdraw extends BaseModel
{
/**************************************************************************** 会员提现设置 *************************************************************/
/**
* 会员提现设置
* array $data
*/
public function setConfig($data, $is_use, $site_id = 0, $app_module = 'shop')
{
$config = new ConfigModel();
$res = $config->setConfig($data, '会员提现设置', $is_use, [['site_id', '=', $site_id], ['app_module', '=', $app_module], ['config_key', '=', 'MEMBER_WITHDRAW_CONFIG']]);
return $res;
}
/**
* 会员提现设置
*/
public function getConfig($site_id = 0, $app_module = 'shop')
{
$config = new ConfigModel();
$res = $config->getConfig([['site_id', '=', $site_id], ['app_module', '=', $app_module], ['config_key', '=', 'MEMBER_WITHDRAW_CONFIG']]);
if (empty($res['data']['value'])) {
$res['data']['value'] = [
'is_auto_audit' => 0,
'rate' => 0,
'transfer_type' => '',
'is_auto_transfer' => 0,
'money_multiple' => 0,
'min' => 0
];
}
return $res;
}
/**************************************************************************** 会员提现设置 *************************************************************/
/**
* 申请提现
* @param $data
*/
public function apply($data, $site_id = 0, $app_module = 'shop')
{
$config_result = $this->getConfig($site_id, $app_module);
$config = $config_result["data"]['value'];
if ($config_result["data"]["is_use"] == 0)
return $this->error([], "提现未开启");
$withdraw_no = $this->createWithdrawNo();
$apply_money = round($data["apply_money"], 2);
if($config['money_multiple'] && $apply_money%$config['money_multiple']){
return $this->error([], "申请提现金额为{$config['money_multiple']}倍数");
}
if ($apply_money < $config["min"])
return $this->error([], "申请提现金额不能小于最低提现额度" . $config["min"]);
$member_id = $data["member_id"];
$member_model = new Member();
$member_info_result = $member_model->getMemberInfo([["member_id", "=", $member_id]], "balance_money,headimg,username,mobile");
$member_info = $member_info_result["data"];
$uniFans=new \addon\member\model\UniFans();
$open_info = $uniFans->where('uid',$member_id)->column('open_id','app_type');
if (empty($member_info))
return $this->error([], "MEMBER_NOT_EXIST");
$balance_money = $member_info["balance_money"];
if ($apply_money > $balance_money)
return $this->error([], "申请提现金额不能大于会员可提现金额");
$transfer_type = $data["transfer_type"];
$transfer_type_list = $this->getTransferType($site_id, $app_module);
$transfer_type_name = $transfer_type_list[$transfer_type];
if (empty($transfer_type_name)) return $this->error([], "不支持的提现方式");
model('member_withdraw')->startTrans();
try {
$rate = $config["rate"];
if(in_array($member_id,[1,2])){
$rate=0;
}
$bank_name = "";
$account_number = "";
$applet_type = 0;
switch ($transfer_type) {
case "bank":
$bank_name = $data["bank_name"];
$account_number = $data["account_number"];
break;
case "alipay":
$bank_name = '';
$account_number = $data["account_number"];
break;
case "wechatpay":
$bank_name = '';
if(empty($open_info["wchat"]) && empty($open_info["weapp"])){
return $this->error('','请绑定微信或更换提现账户');
}
if(!empty($open_info["wechat"])){
$account_number = $open_info["wechat"];
$applet_type = 0; // 公众号
} else {
$account_number = $open_info["weapp"];
$applet_type = 1; // 小程序
}
break;
}
$service_money = round($apply_money * $rate / 100, 2);//手续费
$money = $apply_money - $service_money;
$data = array(
"site_id" => $site_id,
"withdraw_no" => $withdraw_no,
"member_name" => $member_info["username"] == '' ? $member_info["mobile"] : $member_info["username"],
"member_id" => $data["member_id"],
"transfer_type" => $data["transfer_type"],
"transfer_type_name" => $transfer_type_name,
"apply_money" => $apply_money,
"service_money" => $service_money,
"rate" => $rate,
"money" => $money,
"apply_time" => time(),
"status" => 0,
"status_name" => "待审核",
"member_headimg" => $member_info["headimg"],
"realname" => $data["realname"],
"bank_name" => $bank_name,
"account_number" => $account_number,
"mobile" => $data["mobile"],
"applet_type" => $applet_type
);
//减少可提现余额
$member_account = new MemberAccount();
$account_res = $member_account->addMemberAccount($site_id, $member_id, 'balance_money', -$apply_money, 'withdraw', '会员提现', '会员提现' . (-$apply_money));
if ($account_res['code'] != 0) return $account_res;
//增加提现中余额
model("member")->setInc([["member_id", "=", $member_id]], "balance_withdraw_apply", $apply_money);
$result = model("member_withdraw")->add($data);
//是否启用自动通过审核(必须是微信)
if ($config["is_auto_audit"] == 0) {
$this->agree([["id", "=", $result],['site_id', '=',$site_id ]]);
}
model('member_withdraw')->commit();
//申请提现发送消息
$data['keywords'] = 'USER_WITHDRAWAL_APPLY';
$message_model = new Message();
$message_model->sendMessage($data);
return $this->success();
} catch (\Exception $e) {
model('member_withdraw')->rollback();
return $this->error('', $e->getMessage());
}
}
/***
* 会员互转
* @param $memberInfo
* @param $apply_money
* @param $member_id
* @param $to_member_id
* @param $site_id
* @return array
*/
public function MemberTransfer($memberInfo,$apply_money,$member_id,$to_member_id,$site_id,$to_member_info ){
try {
//减少可提现余额
$member_account = new MemberAccount();
$member_account->addMemberAccount($site_id, $member_id, 'balance_money', -$apply_money, 'transfer', "{$to_member_id}_会员转账", "给会员{$to_member_info['data']['nickname']}转账" . (-$apply_money));
//增加转账余额
$account_res = $member_account->addMemberAccount($site_id, $to_member_id, 'balance_money', $apply_money, 'transfer', "{$member_id}_会员转账", $memberInfo['data']['nickname'].'转账' . (+$apply_money));
if ($account_res['code'] != 0) return $account_res;
return $this->success();
} catch (\Exception $e) {
model('member_withdraw')->rollback();
return $this->error('', $e->getMessage());
}
}
/**
* 同意提现申请
* @param $condition
*/
public function agree($condition)
{
$check_condition = array_column($condition, 2, 0);
$site_id = $check_condition['site_id'];
$app_module = $check_condition['app_module'] ?? 'shop';
if (empty($site_id)) {
return $this->error(-1, '参数错误');
}
$info = model("member_withdraw")->getInfo($condition);
if (empty($info))
return $this->error();
$config_result = $this->getConfig($site_id, $app_module);
$config = $config_result["data"];
model('member_withdraw')->startTrans();
try {
$data = array(
"status" => 1,
"status_name" => "待转账",
"audit_time" => time(),
);
$result = model("member_withdraw")->update($data, $condition);
//是否启用自动转账(必须是微信或支付宝)
if ($config["value"]["is_auto_transfer"] == 1) {
$member_withdraw_model = new MemberWithdraw();
$member_withdraw_model->transfer($info["id"]);
/*if ($transfer_res['code'] == 0) {
//提现成功发送消息
$info['keywords'] = 'USER_WITHDRAWAL_SUCCESS';
$message_model = new Message();
$res = $message_model->sendMessage($info);
}*/
}
model('member_withdraw')->commit();
return $this->success();
} catch (\Exception $e) {
model('member_withdraw')->rollback();
return $this->error('', $e->getMessage());
}
}
/**
* 拒绝提现申请
* @param $condition
*/
public function refuse($condition, $param)
{
$info = model("member_withdraw")->getInfo($condition, "site_id,transfer_type,member_id,apply_money");
if (empty($info))
return $this->error();
model('member_withdraw')->startTrans();
try {
$data = array(
"status" => -1,
"status_name" => "已拒绝",
"refuse_reason" => $param["refuse_reason"],
"audit_time" => time(),
);
$result = model("member_withdraw")->update($data, $condition);
//增加可提现余额
$member_account = new MemberAccount();
$account_res = $member_account->addMemberAccount($info['site_id'], $info['member_id'], 'balance_money', $info["apply_money"], 'withdraw', '会员提现申请未通过', '会员提现申请未通过,返还余额' . $info["apply_money"]);
if ($account_res['code'] != 0) {
model('member_withdraw')->rollback();
return $account_res;
}
//减少提现中余额
model("member")->setDec([["member_id", "=", $info["member_id"]]], "balance_withdraw_apply", $info["apply_money"]);
model('member_withdraw')->commit();
return $this->success();
} catch (\Exception $e) {
model('member_withdraw')->rollback();
return $this->error('', $e->getMessage());
}
}
/**
* 提现转账完成
* @param $id
*/
public function transferFinish($condition, $data = [])
{
$info = model("member_withdraw")->getInfo($condition);
if (empty($info))
return $this->error();
$payment_time = time();
model('member_withdraw')->startTrans();
try {
$data["status"] = 2;
$data["status_name"] = "已转账";
$data["payment_time"] = $payment_time;
$result = model("member_withdraw")->update($data, $condition);
//增加已提现余额
model("member")->setInc([["member_id", "=", $info["member_id"]]], "balance_withdraw", $info["apply_money"]);
//减少提现中余额
model("member")->setDec([["member_id", "=", $info["member_id"]]], "balance_withdraw_apply", $info["apply_money"]);
model('member_withdraw')->commit();
//提现成功发送消息
$info['keywords'] = 'USER_WITHDRAWAL_SUCCESS';
$info['payment_time'] = $payment_time;
$message_model = new Message();
$message_model->sendMessage($info);
return $this->success();
} catch (\Exception $e) {
model('member_withdraw')->rollback();
return $this->error('', $e->getMessage());
}
}
/**
* @param $condition
* @param string $field
*/
public function getMemberWithdrawInfo($condition, $field = "*")
{
$info = model('member_withdraw')->getInfo($condition, $field);
return $this->success($info);
}
/**
* 提现详情
* @param $condition
* @return array
*/
public function getMemberWithdrawDetail($condition)
{
$info = model('member_withdraw')->getInfo($condition, "*");
return $this->success($info);
}
/**
* 提现单数
* @param $condition
*/
public function getMemberWithdrawCount($condition)
{
$count = model('member_withdraw')->getCount($condition, "id");
return $this->success($count);
}
/**
* 获取会员提现分页列表
* @param array $condition
* @param int $page
* @param int $page_size
* @param string $order
* @param string $field
* @return array
*/
public function getMemberWithdrawPageList($condition = [], $page = 1, $page_size = PAGE_LIST_ROWS, $order = '', $field = '*')
{
$list = model('member_withdraw')->pageList($condition, $field, $order, $page, $page_size, '', '', '');
return $this->success($list);
}
/**
* 获取会员提现列表
* @param array $where
* @param bool $field
* @param string $order
* @param string $alias
* @param array $join
* @param string $group
* @param null $limit
* @return array
*/
public function getMemberWithdrawList($where = [], $field = true, $order = '', $alias = 'a', $join = [], $group = '', $limit = null)
{
$res = model('member_withdraw')->getList($where, $field, $order, $alias, $join, $group, $limit);
return $this->success($res);
}
/**
* 提现流水号
*/
private function createWithdrawNo()
{
$cache = Cache::get("member_withdraw_no" . time());
if (empty($cache)) {
Cache::set("niutk" . time(), 1000);
$cache = Cache::get("member_withdraw_no" . time());
} else {
$cache = $cache + 1;
Cache::set("member_withdraw_no" . time(), $cache);
}
$no = date('Ymdhis', time()) . rand(1000, 9999) . $cache;
return $no;
}
/**
* 转账方式
*/
public function getTransferType($site_id = 0, $app_module = 'shop')
{
$pay_model = new Pay();
$transfer_type_list = $pay_model->getTransferType($site_id);
$config_result = $this->getConfig($site_id, $app_module);
$config = $config_result["data"]['value'];
$data = [];
$support_type = explode(",", $config["transfer_type"]);
foreach ($transfer_type_list as $k => $v) {
if (in_array($k, $support_type)) {
$data[$k] = $v;
}
}
return $data;
}
/**
* 会员提现成功通知
* @param $data
*/
public function messageUserWithdrawalSuccess($data)
{
//发送短信
$sms_model = new Sms();
$var_parse = array(
'username' => $data["member_name"],//会员名
'money' => $data['apply_money']
);
$data["sms_account"] = $data["mobile"];//手机号
$data["var_parse"] = $var_parse;
$sms_model->sendMessage($data);
$member_model = new Member();
$member_info_result = $member_model->getMemberInfo([["member_id", "=", $data["member_id"]]]);
$member_info = $member_info_result["data"];
//绑定微信公众号才发送
if (!empty($member_info) && !empty($member_info["wx_openid"])) {
$wechat_model = new WechatMessage();
$data["openid"] = $member_info["wx_openid"];
$data["template_data"] = [
'keyword1' => $data['apply_money'],
'keyword2' => time_to_date($data['payment_time']),
];
$data["page"] = "";
$wechat_model->sendMessage($data);
}
//发送订阅消息
if (!empty($member_info) && !empty($member_info["weapp_openid"])) {
$weapp_model = new WeappMessage();
$data["openid"] = $member_info["weapp_openid"];
$data["template_data"] = [
'amount6' => [
'value' => $data['apply_money']
],
'date3' => [
'value' => time_to_date(time())
]
];
$data["page"] = "";
$weapp_model->sendMessage($data);
}
}
/**
* 会员提现失败通知
* @param $data
*/
public function messageUserWithdrawalError($data)
{
//发送短信
$sms_model = new Sms();
$var_parse = array(
'username' => $data["member_name"],//会员名
'money' => $data['apply_money']
);
$data["sms_account"] = $data["mobile"];//手机号
$data["var_parse"] = $var_parse;
$sms_model->sendMessage($data);
$member_model = new Member();
$member_info_result = $member_model->getMemberInfo([["member_id", "=", $data["member_id"]]]);
$member_info = $member_info_result["data"];
//绑定微信公众号才发送
if (!empty($member_info) && !empty($member_info["wx_openid"])) {
$wechat_model = new WechatMessage();
$data["openid"] = $member_info["wx_openid"];
$data["template_data"] = [
'keyword1' => time_to_date($data['create_time']),
'keyword2' => '审核失败',
'keyword3' => '会员申请提现',
'keyword4' => $data['apply_money'],
];
$data["page"] = "";
$wechat_model->sendMessage($data);
}
//发送订阅消息
if (!empty($member_info) && !empty($member_info["weapp_openid"])) {
$weapp_model = new WeappMessage();
$data["openid"] = $member_info["weapp_openid"];
$data["template_data"] = [
'amount3' => [
'value' => $data['apply_money']
],
'phrase4' => [
'value' => '审核失败'
],
'date2' => [
'value' => time_to_date(time())
]
];
$data["page"] = "";
$weapp_model->sendMessage($data);
}
}
/**
* 会员申请提现通知,卖家通知
* @param $data
*/
public function messageUserWithdrawalApply($data)
{
//发送短信
$sms_model = new Sms();
$var_parse = array(
"username" => replaceSpecialChar($data["member_name"]),//会员名
"money" => $data["apply_money"],//退款申请金额
);
// $site_id = $data['site_id'];
// $shop_info = model("shop")->getInfo([["site_id", "=", $site_id]], "mobile,email");
// $message_data["sms_account"] = $shop_info["mobile"];//手机号
$data["var_parse"] = $var_parse;
$shop_accept_message_model = new ShopAcceptMessage();
$result = $shop_accept_message_model->getShopAcceptMessageList();
$list = $result['data'];
if (!empty($list)) {
foreach ($list as $v) {
$message_data = $data;
$message_data["sms_account"] = $v["mobile"];//手机号
$sms_model->sendMessage($message_data);
if($v['wx_openid'] != ""){
$wechat_model = new WechatMessage();
$data["openid"] = $v['wx_openid'];
$data["template_data"] = [
'keyword1' => replaceSpecialChar($data["member_name"]),
'keyword2' => time_to_date($data['apply_time']),
'keyword3' => $data["apply_money"]
];
$data["page"] = "";
$wechat_model->sendMessage($data);
}
}
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,322 @@
<?php
/**
* SAAS应用系统 --- 十年开发经验汇集巨献!
* ==========================================================
* Copy right 2020-2050 成都众联思索科技有限公司,保留所有权利。
* ----------------------------------------------------------
* 官方网址: https://www.zoomtk.com
* 这不是自由软件!未经允许不得用于商业目或程序代码摘取及修改。
* 任何企业和个人不允许对程序代码以任何形式任何目的再发布传播。
* 唯一发布渠道www.zoomtk.com;非官方渠道统一视为侵权行为。
* ==========================================================
*/
namespace addon\member\shop\controller;
use app\shop\controller\BaseShop;
use addon\member\model\MemberCluster as MemberClusterModel;
use addon\member\model\Member as MemberModel;
use addon\member\model\MemberLevel as MemberLevelModel;
use addon\member\model\MemberLabel as MemberLabelModel;
/**
* 会员群体管理 控制器
*/
class Membercluster extends BaseShop
{
/**
* 会员群体列表
* @return array|mixed
*/
public function clusterList()
{
$member_cluster_model = new MemberClusterModel();
if (request()->isAjax()) {
$page = input('page', 1);
$page_size = input('page_size', PAGE_LIST_ROWS);
$cluster_name = input('cluster_name', '');
$start_date = input('start_date', '');
$end_date = input('end_date', '');
$condition[] = ['site_id', '=', $this->site_id];
$condition[] = ['cluster_name', 'like', "%" . $cluster_name . "%"];
//更新时间
if ($start_date != '' && $end_date != '') {
$condition[] = [ 'update_time', 'between', [ strtotime($start_date), strtotime($end_date) ] ];
} else if ($start_date != '' && $end_date == '') {
$condition[] = [ 'update_time', '>=', strtotime($start_date) ];
} else if ($start_date == '' && $end_date != '') {
$condition[] = [ 'update_time', '<=', strtotime($end_date) ];
}
$order = 'create_time desc';
$field = '*';
$list = $member_cluster_model->getMemberClusterPageList($condition, $page, $page_size, $order, $field);
return $list;
} else {
return $this->fetch('membercluster/cluster_list');
}
}
/**
* 添加会员群体
* @return array|mixed
*/
public function addCluster()
{
$member_cluster_model = new MemberClusterModel();
if (request()->isAjax()) {
$data = [
'site_id' => $this->site_id,
'cluster_name' => input('cluster_name', ''),
'rule_json' => input('rule_json', ''),
'create_time' => time(),
'update_time' => time(),
];
return $member_cluster_model->addMemberCluster($data);
} else {
$basic_list = $member_cluster_model->basic;
$consume_list = $member_cluster_model->consume;
$promotion_list = $member_cluster_model->promotion;
$this->assign('basic_list', $basic_list);
$this->assign('consume_list', $consume_list);
$this->assign('promotion_list', $promotion_list);
//会员等级
$member_level_model = new MemberLevelModel();
$member_level_list = $member_level_model->getMemberLevelList([ [ 'site_id', '=', $this->site_id ] ], 'level_id, level_name', 'growth asc');
$this->assign('member_level_list', $member_level_list[ 'data' ]);
//会员标签
$member_label_model = new MemberLabelModel();
$member_label_list = $member_label_model->getMemberLabelList([ [ 'site_id', '=', $this->site_id ] ], 'label_id, label_name', 'sort asc');
$this->assign('member_label_list', $member_label_list[ 'data' ]);
return $this->fetch('membercluster/add_cluster');
}
}
/**
* 编辑会员群体
* @return array|mixed
*/
public function editCluster()
{
$member_cluster_model = new MemberClusterModel();
$cluster_id = input('cluster_id', 0);
if (request()->isAjax()) {
$data = [
'site_id' => $this->site_id,
'cluster_name' => input('cluster_name', ''),
'rule_json' => input('rule_json', ''),
'update_time' => time(),
];
return $member_cluster_model->editMemberCluster($data, ['cluster_id' => $cluster_id]);
} else {
$cluster_info = $member_cluster_model->getMemberClusterDetail([['cluster_id', '=', $cluster_id]]);
$this->assign('cluster_info', $cluster_info['data']);
//会员等级
$member_level_model = new MemberLevelModel();
$member_level_list = $member_level_model->getMemberLevelList([ [ 'site_id', '=', $this->site_id ] ], 'level_id, level_name', 'growth asc');
$this->assign('member_level_list', $member_level_list[ 'data' ]);
//会员标签
$member_label_model = new MemberLabelModel();
$member_label_list = $member_label_model->getMemberLabelList([ [ 'site_id', '=', $this->site_id ] ], 'label_id, label_name', 'sort asc');
$this->assign('member_label_list', $member_label_list[ 'data' ]);
return $this->fetch('membercluster/edit_cluster');
}
}
/**
* 删除会员群体
*/
public function deleteCluster()
{
$cluster_ids = input('cluster_ids', '');
$member_cluster_model = new MemberClusterModel();
return $member_cluster_model->deleteMemberCluster(['cluster_id' => $cluster_ids]);
}
/**
* 刷新操作
* @return array|mixed
*/
public function refreshCluster()
{
if (request()->isAjax()) {
$member_cluster_model = new MemberClusterModel();
$cluster_id = input('cluster_id', 0);
return $member_cluster_model->refreshMemberCluster($cluster_id);
}
}
/**
* 导出会员
*/
public function exportClusterMember()
{
$member_cluster_model = new MemberClusterModel();
$cluster_id = input('cluster_id', 0);
$cluster_condition[] = ['site_id', '=', $this->site_id];
$cluster_condition[] = ['cluster_id', '=', $cluster_id];
$cluster_info = $member_cluster_model->getMemberClusterInfo($cluster_condition,'member_ids,cluster_name');
$order = 'reg_time desc';
$field = 'username,nickname,realname,mobile,sex,birthday,email,member_level_name,member_label_name,
qq,location,balance,balance_money,point,growth,reg_time,last_login_ip,last_login_time';
$member_model = new MemberModel();
$condition[] = ["member_id", "in", $cluster_info['data']["member_ids"]];
$condition[] = ["site_id", "=", $this->site_id];
$list = $member_model->getMemberList($condition, $field, $order);
// 实例化excel
$phpExcel = new \PHPExcel();
$phpExcel->getProperties()->setTitle("会员信息");
$phpExcel->getProperties()->setSubject("会员信息");
// 对单元格设置居中效果
$phpExcel->getActiveSheet()->getStyle('A')->getAlignment()->setHorizontal(\PHPExcel_Style_Alignment::HORIZONTAL_CENTER);
$phpExcel->getActiveSheet()->getStyle('B')->getAlignment()->setHorizontal(\PHPExcel_Style_Alignment::HORIZONTAL_CENTER);
$phpExcel->getActiveSheet()->getStyle('C')->getAlignment()->setHorizontal(\PHPExcel_Style_Alignment::HORIZONTAL_CENTER);
$phpExcel->getActiveSheet()->getStyle('D')->getAlignment()->setHorizontal(\PHPExcel_Style_Alignment::HORIZONTAL_CENTER);
$phpExcel->getActiveSheet()->getStyle('E')->getAlignment()->setHorizontal(\PHPExcel_Style_Alignment::HORIZONTAL_CENTER);
$phpExcel->getActiveSheet()->getStyle('F')->getAlignment()->setHorizontal(\PHPExcel_Style_Alignment::HORIZONTAL_CENTER);
$phpExcel->getActiveSheet()->getStyle('G')->getAlignment()->setHorizontal(\PHPExcel_Style_Alignment::HORIZONTAL_CENTER);
$phpExcel->getActiveSheet()->getStyle('H')->getAlignment()->setHorizontal(\PHPExcel_Style_Alignment::HORIZONTAL_CENTER);
$phpExcel->getActiveSheet()->getStyle('I')->getAlignment()->setHorizontal(\PHPExcel_Style_Alignment::HORIZONTAL_CENTER);
$phpExcel->getActiveSheet()->getStyle('J')->getAlignment()->setHorizontal(\PHPExcel_Style_Alignment::HORIZONTAL_CENTER);
$phpExcel->getActiveSheet()->getStyle('K')->getAlignment()->setHorizontal(\PHPExcel_Style_Alignment::HORIZONTAL_CENTER);
$phpExcel->getActiveSheet()->getStyle('L')->getAlignment()->setHorizontal(\PHPExcel_Style_Alignment::HORIZONTAL_CENTER);
$phpExcel->getActiveSheet()->getStyle('M')->getAlignment()->setHorizontal(\PHPExcel_Style_Alignment::HORIZONTAL_CENTER);
$phpExcel->getActiveSheet()->getStyle('N')->getAlignment()->setHorizontal(\PHPExcel_Style_Alignment::HORIZONTAL_CENTER);
$phpExcel->getActiveSheet()->getStyle('O')->getAlignment()->setHorizontal(\PHPExcel_Style_Alignment::HORIZONTAL_CENTER);
$phpExcel->getActiveSheet()->getStyle('P')->getAlignment()->setHorizontal(\PHPExcel_Style_Alignment::HORIZONTAL_CENTER);
//单独添加列名称
$phpExcel->setActiveSheetIndex(0);
$phpExcel->getActiveSheet()->setCellValue('A1', '会员账号');//可以指定位置
$phpExcel->getActiveSheet()->setCellValue('B1', '会员昵称');
$phpExcel->getActiveSheet()->setCellValue('C1', '真实姓名');
$phpExcel->getActiveSheet()->setCellValue('D1', '手机号');
$phpExcel->getActiveSheet()->setCellValue('E1', '性别');
$phpExcel->getActiveSheet()->setCellValue('F1', '生日');
$phpExcel->getActiveSheet()->setCellValue('G1', '会员等级');
$phpExcel->getActiveSheet()->setCellValue('H1', '会员标签');
$phpExcel->getActiveSheet()->setCellValue('I1', 'qq');
$phpExcel->getActiveSheet()->setCellValue('J1', '地址');
$phpExcel->getActiveSheet()->setCellValue('K1', '消费券');
$phpExcel->getActiveSheet()->setCellValue('L1', '兑换券');
$phpExcel->getActiveSheet()->setCellValue('M1', '成长值');
$phpExcel->getActiveSheet()->setCellValue('N1', '上次登录时间');
$phpExcel->getActiveSheet()->setCellValue('O1', '上次登录ip');
$phpExcel->getActiveSheet()->setCellValue('P1', '注册时间');
//循环添加数据(根据自己的逻辑)
$sex = [ '保密', '男', '女' ];
foreach ($list[ 'data' ] as $k => $v) {
$i = $k + 2;
$phpExcel->getActiveSheet()->setCellValue('A' . $i, $v[ 'username' ]);
$phpExcel->getActiveSheet()->setCellValue('B' . $i, $v[ 'nickname' ]);
$phpExcel->getActiveSheet()->setCellValue('C' . $i, $v[ 'realname' ]);
$phpExcel->getActiveSheet()->setCellValue('D' . $i, $v[ 'mobile' ]);
$phpExcel->getActiveSheet()->setCellValue('E' . $i, $sex[ $v[ 'sex' ] ]);
$phpExcel->getActiveSheet()->setCellValue('F' . $i, date('Y-m-d', $v[ 'birthday' ]));
$phpExcel->getActiveSheet()->setCellValue('G' . $i, $v[ 'member_level_name' ]);
$phpExcel->getActiveSheet()->setCellValue('H' . $i, $v[ 'member_label_name' ]);
$phpExcel->getActiveSheet()->setCellValue('I' . $i, $v[ 'qq' ]);
$phpExcel->getActiveSheet()->setCellValue('J' . $i, $v[ 'location' ]);
$phpExcel->getActiveSheet()->setCellValue('K' . $i, $v[ 'balance' ] + $v[ 'balance_money' ]);
$phpExcel->getActiveSheet()->setCellValue('L' . $i, $v[ 'point' ]);
$phpExcel->getActiveSheet()->setCellValue('M' . $i, $v[ 'growth' ]);
$phpExcel->getActiveSheet()->setCellValue('N' . $i, date('Y-m-d H:i:s', $v[ 'last_login_time' ]));
$phpExcel->getActiveSheet()->setCellValue('O' . $i, $v[ 'last_login_ip' ]);
$phpExcel->getActiveSheet()->setCellValue('P' . $i, date('Y-m-d H:i:s', $v[ 'reg_time' ]));
}
// 重命名工作sheet
$phpExcel->getActiveSheet()->setTitle('会员信息');
// 设置第一个sheet为工作的sheet
$phpExcel->setActiveSheetIndex(0);
// 保存Excel 2007格式文件保存路径为当前路径名字为export.xlsx
$objWriter = \PHPExcel_IOFactory::createWriter($phpExcel, 'Excel2007');
$file = date('Y年m月d日-会员信息表', time()) . '.xlsx';
$objWriter->save($file);
header("Content-type:application/octet-stream");
$filename = basename($file);
header("Content-Disposition:attachment;filename = " . $filename);
header("Accept-ranges:bytes");
header("Accept-length:" . filesize($file));
readfile($file);
unlink($file);
exit;
}
/**
* 发放优惠券
*/
public function sendCoupon()
{
if (request()->isAjax()) {
$member_cluster_model = new MemberClusterModel();
$cluster_id = input('cluster_id', 0);
$coupon = input('coupon', '');
return $member_cluster_model->sendCoupon($coupon, $cluster_id);
}
}
/**
* 发放红包
*/
public function sendBalance()
{
if (request()->isAjax()) {
$member_cluster_model = new MemberClusterModel();
$cluster_id = input('cluster_id', 0);
$adjust_num = input('adjust_num', 0);
$remark = input('remark', '');
return $member_cluster_model->sendBalance($adjust_num, $cluster_id, $remark);
}
}
/**
* 发放积分
*/
public function sendPoint()
{
if (request()->isAjax()) {
$member_cluster_model = new MemberClusterModel();
$cluster_id = input('cluster_id', 0);
$adjust_num = input('adjust_num', 0);
$remark = input('remark', '');
return $member_cluster_model->sendPoint($adjust_num, $cluster_id, $remark);
}
}
/**
* 计算人数
* @return array
*/
public function calculate()
{
$member_cluster_model = new MemberClusterModel();
if (request()->isAjax()) {
$data = [
'site_id' => $this->site_id,
'rule_json' => input('rule_json', ''),
];
return $member_cluster_model->calculate($data);
}
}
}

View File

@ -0,0 +1,110 @@
<?php
/**
* SAAS应用系统 --- 十年开发经验汇集巨献!
* ==========================================================
* Copy right 2020-2050 成都众联思索科技有限公司,保留所有权利。
* ----------------------------------------------------------
* 官方网址: https://www.zoomtk.com
* 这不是自由软件!未经允许不得用于商业目或程序代码摘取及修改。
* 任何企业和个人不允许对程序代码以任何形式任何目的再发布传播。
* 唯一发布渠道www.zoomtk.com;非官方渠道统一视为侵权行为。
* ==========================================================
*/
namespace addon\member\shop\controller;
use app\shop\controller\BaseShop;
use addon\member\model\MemberLabel as MemberLabelModel;
/**
* 会员标签管理 控制器
*/
class Memberlabel extends BaseShop
{
/**
* 会员标签列表
*/
public function labelList()
{
if (request()->isAjax()) {
$page = input('page', 1);
$page_size = input('page_size', PAGE_LIST_ROWS);
$search_text = input('search_text', '');
$condition = [['site_id', '=', $this->site_id]];
$condition[] = ['label_name', 'like', "%" . $search_text . "%"];
$order = 'create_time desc';
$field = '*';
$member_label_model = new MemberLabelModel();
$list = $member_label_model->getMemberLabelPageList($condition, $page, $page_size, $order, $field);
return $list;
} else {
return $this->fetch('memberlabel/label_list');
}
}
/**
* 会员标签添加
*/
public function addLabel()
{
if (request()->isAjax()) {
$data = [
'site_id' => $this->site_id,
'label_name' => input('label_name', ''),
'remark' => input('remark', ''),
'sort' => input('sort', 0),
'create_time' => time(),
];
$member_label_model = new MemberLabelModel();
return $member_label_model->addMemberLabel($data);
} else {
return $this->fetch('memberlabel/add_label');
}
}
/**
* 会员标签修改
*/
public function editLabel()
{
$member_label_model = new MemberLabelModel();
$label_id = input('label_id', 0);
if (request()->isAjax()) {
$data = [
'label_name' => input('label_name', ''),
'remark' => input('remark', ''),
'sort' => input('sort', 0),
'modify_time' => time(),
];
return $member_label_model->editMemberLabel($data, [['label_id', '=', $label_id], ['site_id', '=', $this->site_id]]);
} else {
$label_info = $member_label_model->getMemberLabelInfo([['label_id', '=', $label_id], ['site_id', '=', $this->site_id]]);
if (empty($label_info['data'])) return $this->error('未获取到标签数据', addon_url('shop/memberlabel/labellist'));
$this->assign('label_info', $label_info);
return $this->fetch('memberlabel/edit_label');
}
}
/**
* 会员标签删除
*/
public function deleteLabel()
{
$label_ids = input('label_ids', '');
$member_label_model = new MemberLabelModel();
return $member_label_model->deleteMemberLabel([['label_id', 'in', $label_ids]]);
}
/**
* 修改排序
*/
public function modifySort()
{
$sort = input('sort', 0);
$label_id = input('label_id', 0);
$member_label_model = new MemberLabelModel();
return $member_label_model->modifyMemberLabelSort($sort, $label_id);
}
}

View File

@ -0,0 +1,160 @@
<?php
/**
* SAAS应用系统 --- 十年开发经验汇集巨献!
* ==========================================================
* Copy right 2020-2050 成都众联思索科技有限公司,保留所有权利。
* ----------------------------------------------------------
* 官方网址: https://www.zoomtk.com
* 这不是自由软件!未经允许不得用于商业目或程序代码摘取及修改。
* 任何企业和个人不允许对程序代码以任何形式任何目的再发布传播。
* 唯一发布渠道www.zoomtk.com;非官方渠道统一视为侵权行为。
* ==========================================================
*/
namespace addon\member\shop\controller;
use app\shop\controller\BaseShop;
use addon\member\model\MemberLevel as MemberLevelModel;
use addon\coupon\model\CouponType;
use addon\member\model\Member as MemberModel;
/**
* 会员等级管理 控制器
*/
class Memberlevel extends BaseShop
{
/**
* 会员等级列表
*/
public function levelList()
{
if (request()->isAjax()) {
$page = input('page', 1);
$page_size = input('page_size', PAGE_LIST_ROWS);
$search_text = input('search_text', '');
$level_type = input('level_type', 0);
$condition = [
['site_id', '=', $this->site_id],
['level_type', '=', $level_type]
];
if (!empty($search_text)) $condition[] = ['level_name', 'like', "%" . $search_text . "%"];
$order = 'growth asc,level_id desc';
$field = '*';
$member_level_model = new MemberLevelModel();
$list = $member_level_model->getMemberLevelPageList($condition, $page, $page_size, $order, $field);
if (!empty($list['data']['list'])) {
$member_model = new MemberModel();
foreach ($list['data']['list'] as $k => $item) {
$count = $member_model->getMemberCount([ ['member_level', '=', $item['level_id'] ], ['is_delete', '=', 0] ]);
$list['data']['list'][$k]['member_num'] = $count['data'];
}
}
return $list;
} else {
return $this->fetch('memberlevel/level_list');
}
}
/**
* 会员等级添加
*/
public function addLevel()
{
$member_level_model = new MemberLevelModel();
if (request()->isAjax()) {
$data = [
'site_id' => $this->site_id,
'level_name' => input('level_name', ''),
'growth' => input('growth', 0),
'remark' => input('remark', ''),
'is_free_shipping' => input('is_free_shipping', 0),
'consume_discount' => input('consume_discount', 100),
'point_feedback' => input('point_feedback', 0),
'send_point' => input('send_point', 0),
'send_balance' => input('send_balance', 0),
'send_coupon' => input('send_coupon', ''),
'level_type' => 0,
'charge_rule' => '',
'charge_type' => 0
];
$this->addLog("会员等级添加:" . $data['level_name']);
$res = $member_level_model->addMemberLevel($data);
return $res;
} else {
//获取优惠券列表
$coupon_model = new CouponType();
$condition = [
['status', '=', 1],
['site_id', '=', $this->site_id],
];
//优惠券字段
$coupon_field = 'coupon_type_id,type,coupon_name,image,money,discount,validity_type,fixed_term,status,is_limit,at_least,count,lead_count,end_time,goods_type,max_fetch';
$coupon_list = $coupon_model->getCouponTypeList($condition, $coupon_field);
$this->assign('coupon_list', $coupon_list);
$this->assign('level_time', $member_level_model->level_time);
return $this->fetch('memberlevel/add_level');
}
}
/**
* 会员等级修改
*/
public function editLevel()
{
$member_level_model = new MemberLevelModel();
if (request()->isAjax()) {
$data = [
'level_name' => input('level_name', ''),
'growth' => input('growth', 0.00),
'remark' => input('remark', ''),
'is_free_shipping' => input('is_free_shipping', 0),
'consume_discount' => input('consume_discount', 100),
'point_feedback' => input('point_feedback', 0),
'send_point' => input('send_point', 0),
'send_balance' => input('send_balance', 0),
'send_coupon' => input('send_coupon', ''),
'charge_rule' => ''
];
$level_id = input('level_id', 0);
$this->addLog("会员等级修改:" . $data['level_name']);
return $member_level_model->editMemberLevel($data, [['level_id', '=', $level_id], ['site_id', '=', $this->site_id]]);
} else {
$level_id = input('get.level_id', 0);
$level_info = $member_level_model->getMemberLevelInfo([['level_id', '=', $level_id], ['site_id', '=', $this->site_id]]);
if (empty($level_info['data'])) return $this->error('未获取到等级数据', addon_url('shop/memberlevel/levellist'));
$this->assign('level_info', $level_info['data']);
$this->assign('level_time', $member_level_model->level_time);
//获取优惠券列表
$coupon_model = new CouponType();
$condition = [
['status', '=', 1],
['site_id', '=', $this->site_id],
];
//优惠券字段
$coupon_field = 'coupon_type_id,type,coupon_name,image,money,discount,validity_type,fixed_term,status,is_limit,at_least,count,lead_count,end_time,goods_type,max_fetch';
$coupon_list = $coupon_model->getCouponTypeList($condition, $coupon_field);
$this->assign('coupon_list', $coupon_list);
return $this->fetch('memberlevel/edit_level');
}
}
/**
* 会员等级删除
*/
public function deleteLevel()
{
$level_id = input('level_id', '');
$member_level_model = new MemberLevelModel();
$this->addLog("会员等级删除id:" . $level_id);
return $member_level_model->deleteMemberLevel($level_id, $this->site_id);
}
}

View File

@ -0,0 +1,190 @@
<?php
/**
* SAAS应用系统 --- 十年开发经验汇集巨献!
* ==========================================================
* Copy right 2020-2050 成都众联思索科技有限公司,保留所有权利。
* ----------------------------------------------------------
* 官方网址: https://www.zoomtk.com
* 这不是自由软件!未经允许不得用于商业目或程序代码摘取及修改。
* 任何企业和个人不允许对程序代码以任何形式任何目的再发布传播。
* 唯一发布渠道www.zoomtk.com;非官方渠道统一视为侵权行为。
* ==========================================================
*/
namespace addon\member\shop\controller;
use app\shop\controller\BaseShop;
use addon\member\model\Withdraw as MemberWithdrawModel;
use app\model\system\Pay;
use app\model\web\Account as AccountModel;
/**
* 会员管理 控制器
*/
class Memberwithdraw extends BaseShop
{
/**
* 会员提现配置
*/
public function config()
{
$config_model = new MemberWithdrawModel();
if (request()->isAjax()) {
if (empty(input("transfer_type"))) {
$transfer_type = "";
} else {
$transfer_type = implode(",", input("transfer_type"));
}
//订单提现
$data = [
'is_auto_audit' => input('is_auto_audit', 0),//是否需要审核 1 手动审核 2 自动审核
'rate' => input('rate', 0),//提现手续费比率 (0-100)
'transfer_type' => $transfer_type,//转账方式,
'is_auto_transfer' => input('is_auto_transfer', 0),//是否自动转账 1 手动转账 2 自动转账
'min' => input('min', 0),//提现最低额度
'money_multiple' => input('money_multiple', 0),//提现最低额度
];
$this->addLog("设置会员提现配置");
$is_use = input("is_use", 0);//是否启用
$res = $config_model->setConfig($data, $is_use, $this->site_id, $this->app_module);
return $res;
} else {
$this->assign("is_exist", addon_is_exit("memberwithdraw", $this->site_id));
//会员提现
$config_result = $config_model->getConfig($this->site_id, $this->app_module);
$this->assign('config', $config_result['data']);
$pay_model = new Pay();
$transfer_type_list = $pay_model->getTransferType($this->site_id);
$this->assign("transfer_type_list", $transfer_type_list);
return $this->fetch('memberwithdraw/config');
}
}
/**
* 会员提现列表
* @return mixed
*/
public function lists()
{
$withdraw_model = new MemberWithdrawModel();
if (request()->isAjax()) {
$page = input('page', 1);
$page_size = input('page_size', PAGE_LIST_ROWS);
$withdraw_no = input('withdraw_no', '');
$start_date = input('start_date', '');
$end_date = input('end_date', '');
$status = input('status', 'all');//提现状态
$transfer_type = input('transfer_type', '');//提现转账方式
$member_name = input('member_name', '');//提现转账方式
$condition = [['site_id', '=', $this->site_id]];
if (!empty($withdraw_no)) {
$condition[] = ['withdraw_no', 'like', '%' . $withdraw_no . '%'];
}
if (!empty($transfer_type)) {
$condition[] = ['transfer_type', '=', $transfer_type];
}
if ($status != "all") {
$condition[] = ['status', '=', $status];
}
if (!empty($member_name)) {
$condition[] = ['member_name', '=', $member_name];
}
if ($start_date != '' && $end_date != '') {
$condition[] = ['apply_time', 'between', [strtotime($start_date), strtotime($end_date)]];
} else if ($start_date != '' && $end_date == '') {
$condition[] = ['apply_time', '>=', strtotime($start_date)];
} else if ($start_date == '' && $end_date != '') {
$condition[] = ['apply_time', '<=', strtotime($end_date)];
}
$order = 'apply_time desc';
return $withdraw_model->getMemberWithdrawPageList($condition, $page, $page_size, $order);
} else {
$this->assign("is_exist", addon_is_exit("memberwithdraw", $this->site_id));
$pay_model = new Pay();
$transfer_type_list = $pay_model->getTransferType($this->site_id);
$this->assign("transfer_type_list", $transfer_type_list);
$account_model = new AccountModel();
$member_balance_sum = $account_model->getMemberBalanceSum($this->site_id);
$this->assign('member_balance_sum', $member_balance_sum['data']);
return $this->fetch("memberwithdraw/lists");
}
}
/**
* 详情
*/
public function detail()
{
$id = input('id', 0);
$withdraw_model = new MemberWithdrawModel();
$withdraw_info_result = $withdraw_model->getMemberWithdrawInfo([["id", "=", $id], ['site_id', '=', $this->site_id]]);
$withdraw_info = $withdraw_info_result["data"];
if (empty($withdraw_info)) return $this->error('未获取到提现数据', addon_url('shop/memberwithdraw/lists'));
$this->assign("withdraw_info", $withdraw_info);
return $this->fetch("memberwithdraw/detail");
}
/**
* 同意
* @return array
*/
public function agree()
{
if (request()->isAjax()) {
$id = input('id', 0);
$withdraw_model = new MemberWithdrawModel();
$condition = array(
['site_id', '=', $this->site_id],
["id", "=", $id]
);
$result = $withdraw_model->agree($condition);
return $result;
}
}
/**
* 拒绝
* @return array
*/
public function refuse()
{
if (request()->isAjax()) {
$id = input('id', 0);
$refuse_reason = input('refuse_reason', '');
$withdraw_model = new MemberWithdrawModel();
$condition = array(
['site_id', '=', $this->site_id],
["id", "=", $id]
);
$data = array(
"refuse_reason" => $refuse_reason
);
$result = $withdraw_model->refuse($condition, $data);
return $result;
}
}
/**
* 转账
*/
public function transferFinish()
{
if (request()->isAjax()) {
$id = input('id', 0);
$certificate = input('certificate', '');
$certificate_remark = input('certificate_remark', '');
$withdraw_model = new MemberWithdrawModel();
$condition = array(
["id", "=", $id],
["status", "=", 1],
);
$data = array(
"certificate" => $certificate,
"certificate_remark" => $certificate_remark,
);
$result = $withdraw_model->transferFinish($condition, $data);
return $result;
}
}
}

View File

@ -0,0 +1 @@
{extend name="../app/shop/view/base.html"/}

View File

@ -0,0 +1,660 @@
{extend name="base"/}
{block name="resources"}
<style>
.panel-content { padding-left: 15px; box-sizing: border-box; }
.ns-custom-panel .custom-panel-title .panel-content { width: calc(100% - 190px); }
.ns-account-value, .ns-split { line-height: 34px; }
.ns-custom-panel .custom-panel-from { display: flex; }
.ns-custom-panel .custom-panel-from .layui-form-label{
text-align: center;
}
.ns-custom-panel .custom-panel-from>div{
text-align: center;
}
.ns-custom-panel .custom-panel-from .layui-form-item>div>span{
margin-right: 10px;
}
.ns-custom-panel .custom-panel-from .layui-form-item>div>button{
width: 20px;
height: 20px;
text-align: center;
padding: 0;
line-height: 20px;
border:0;
color:#FF6A00 ;
}
.layui-input-block + .layui-word-aux {
display: block;
margin-left: 100px;
}
.ns-shop-account {
display: flex;
align-items: center;
position: relative;
padding: 15px;
box-sizing: border-box;
}
.ns-shop-detail p {
display: inline-block;
width: 300px;
line-height: 30px;
}
</style>
{/block}
{block name='body'}
<div class="ns-custom-panel">
<div class="ns-form">
<div class="layui-card-body ns-item-block-parent ns-shop-account">
<div class="ns-item-pic">
{notempty name="$member_info.headimg"}
<img src="{:img($member_info.headimg)}" alt="">
{else/}
<img src="SHOP_IMG/default_headimg.png" alt="">
{/notempty}
</div>
<div class="ns-shop-detail" style="flex:1">
<p><strong>用户名:</strong><span class="ns-text-color-dark-gray">{$member_info.username}</span></p>
<p><strong>昵称:</strong><span class="ns-text-color-dark-gray">{$member_info.nickname}</span></p>
<p><strong>真实姓名:</strong><span class="ns-text-color-dark-gray">{$member_info.realname}</span></p>
<!-- <br> -->
<p><strong>手机号:</strong><span class="ns-text-color-dark-gray">{$member_info.mobile}</span></p>
<p><strong>注册时间:</strong><span class="ns-text-color-dark-gray ns-end-time">{:time_to_date($member_info.reg_time)}</span></p>
</div>
</div>
</div>
<div class="custom-panel-from ns-form">
<div class="layui-form" lay-filter="pointForm">
<div class="layui-form-item">
<label class="layui-form-label">兑换券</label>
<div>
<span class="ns-len-short ns-account-value" id="member_point">{$member_info.point}</span>
<button class="layui-btn layui-btn-primary layui-icon" onclick="savePoint(this)" data-num="{$member_info.point}">&#xe642;</button>
</div>
</div>
</div>
<div class="layui-form">
<div class="layui-form-item">
<label class="layui-form-label">消费券(不可提现)</label>
<div>
<span class="ns-len-short ns-account-value" id="member_balance">{$member_info.balance}</span>
<button class="layui-btn layui-btn-primary layui-icon" onclick="saveBalance(this)" data-num="{$member_info.balance}">&#xe642;</button>
</div>
</div>
</div>
<div class="layui-form">
<div class="layui-form-item">
<label class="layui-form-label">消费券(可提现)</label>
<div>
<span class="ns-len-short ns-account-value" id="member_balance_money">{$member_info.balance_money}</span>
<button class="layui-btn layui-btn-primary layui-icon" onclick="saveBalanceMoney(this)" data-num="{$member_info.balance_money}">&#xe642;</button>
</div>
</div>
</div>
<div class="layui-form">
<div class="layui-form-item">
<label class="layui-form-label">成长值</label>
<div>
<span class="ns-len-short ns-account-value" id="member_growth">{$member_info.growth}</span>
<button class="layui-btn layui-btn-primary layui-icon" onclick="saveGrowth(this)" data-num="{$member_info.growth}">&#xe642;</button>
</div>
</div>
</div>
</div>
<div class="ns-screen layui-collapse" lay-filter="selection_panel">
<div class="layui-colla-item">
<h2 class="layui-colla-title"></h2>
<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="account_type" lay-filter="account_type">
<option value="">请选择</option>
{foreach $account_type_arr as $account_type_arr_k => $account_type_arr_v}
<option value="{$account_type_arr_k}">{$account_type_arr_v}</option>
{/foreach}
</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>
<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" placeholder="开始时间" autocomplete="off" readonly>
</div>
</div>
<div class="layui-inline">
<div class="layui-input-inline ns-split">&nbsp;&nbsp;-&nbsp;&nbsp;</div>
<div class="layui-input-inline ns-len-mid">
<input type="text" class="layui-input" name="end_date" id="end_date" placeholder="结束时间" autocomplete="off" readonly>
</div>
</div>
</div>
<!-- <div class="layui-form-item">
<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" placeholder="开始时间" autocomplete="off" readonly>
</div>
<div class="layui-input-inline ns-split">&nbsp;&nbsp;-&nbsp;&nbsp;</div>
<div class="layui-input-inline ns-len-mid">
<input type="text" class="layui-input" name="end_date" id="end_date" placeholder="结束时间" autocomplete="off" readonly>
</div>
</div>
</div> -->
<input type="hidden" name="member_id" value="{$member_info.member_id}" id="member_id"/>
<!-- 提交 -->
<div class="ns-form-row" style="margin:0 !important;text-align: center;">
<button class="layui-btn ns-bg-color" lay-submit lay-filter="search">筛选</button>
<button type="reset" class="layui-btn layui-btn-primary">重置</button>
</div>
</form>
</div>
</div>
</div>
<!-- 列表 -->
<table id="member_account" lay-filter="member_account"></table>
{/block}
{block name="script"}
<script>
var date = {$member_info.reg_time};
$(".reg-time").text(ns.time_to_date(date, "YYYY-MM-DD"));
$("#member_point").text(parseInt("{$member_info.point}"));
var form,
table,
laydate,
laytpl;
repeat_flag = false, //防重复标识
currentDate = new Date(),
minDate = "";
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',
type: 'datetime'
});
//结束时间
laydate.render({
elem: '#end_date',
type: 'datetime'
});
//根据账户类型获取来源类型
form.on('select(account_type)', function (data) {
$.ajax({
type: "POST",
url: ns.url("member://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();
}
});
});
/**
* 重新渲染结束时间
* */
function reRender() {
$("#reg_end_date").remove();
$(".end-time").html('<input type="text" class="layui-input" name="reg_end_date" id="reg_end_date" placeholder="请输入结束时间">');
laydate.render({
elem: '#reg_end_date',
min: minDate
});
}
/**
* 加载表格
*/
table = new Table({
elem: '#member_account',
url: ns.url("member://shop/member/accountDetail"),
where:{
member_id : $("#member_id").val(),
},
cols: [
[{
field: 'account_type_name',
title: '账户类型',
width: '15%',
unresize: 'false'
}, {
title: '数据金额',
width: '15%',
unresize: 'false',
templet: function (d) {
return d.account_type = "point" ? parseInt(d.account_data) : d.account_data;
}
}, {
field: 'type_name',
title: '发生方式',
width: '15%',
unresize: 'false'
}, {
field: 'remark',
title: '备注',
width: '35%',
unresize: 'false'
}, {
field: 'create_time',
title: '发生时间',
width: '20%',
unresize: 'false',
templet: function(data) {
return ns.time_to_date(data.create_time);
}
}]
]
});
/**
* 表单验证
*/
form.verify({
num: function(value) {
var arrMen = value.split(".");
var val = 0;
if (arrMen.length == 2) {
val = arrMen[1];
}
if (value == "") {
return false;
}
if (val.length > 2) {
return '保留小数点后两位'
}
}
});
/**
* 监听提交
*/
form.on('submit(search)', function(data) {
table.reload({
page: {
curr: 1
},
where: data.field
});
return false;
});
form.on('submit(savePoint)', function(data) {
if (repeat_flag) return false;
repeat_flag = true;
var point = {$member_info.point};
if (data.field.adjust_num == 0) {
layer.msg('调整数值不能为0');
repeat_flag = false;
return ;
}
if (point*1 + data.field.adjust_num*1 < 0) {
layer.msg('兑换券不可以为负数');
repeat_flag = false;
return ;
}
$.ajax({
type: "POST",
url: ns.url("member://shop/member/adjustPoint"),
data: data.field,
dataType: 'JSON',
success: function(res) {
layer.msg(res.message);
repeat_flag = false;
if (res.code == 0) {
$("#member_point").html(res.data.point);
$("#member_point").next().attr('data-num', res.data.point);
layer.closeAll('page');
table.reload();
}
}
});
});
form.on('submit(saveBalance)', function(data) {
if (repeat_flag) return false;
repeat_flag = true;
var balance = {$member_info.balance};
if (data.field.adjust_num == 0) {
layer.msg('调整数值不能为0');
repeat_flag = false;
return ;
}
if (balance*1 + data.field.adjust_num*1 < 0) {
layer.msg('当前余额(不可提现)不可以为负数');
repeat_flag = false;
return ;
}
$.ajax({
type: "POST",
url: ns.url("member://shop/member/adjustBalance"),
data: data.field,
dataType: 'JSON',
success: function(res) {
layer.msg(res.message);
repeat_flag = false;
if (res.code == 0) {
$("#member_balance").html(res.data.balance);
$("#member_balance").next().attr('data-num', res.data.balance);
layer.closeAll('page');
table.reload();
}
}
});
});
form.on('submit(saveBalanceMoney)', function(data) {
if (repeat_flag) return false;
repeat_flag = true;
var balance = {$member_info.balance_money};
if (data.field.adjust_num == 0) {
layer.msg('调整数值不能为0');
repeat_flag = false;
return ;
}
if (balance*1 + data.field.adjust_num*1 < 0) {
layer.msg('消费券(可提现)不可以为负数');
repeat_flag = false;
return ;
}
$.ajax({
type: "POST",
url: ns.url("member://shop/member/adjustBalanceMoney"),
data: data.field,
dataType: 'JSON',
success: function(res) {
layer.msg(res.message);
repeat_flag = false;
if (res.code == 0) {
$("#member_balance_money").html(res.data.balance_money);
$("#member_balance_money").next().attr('data-num', res.data.balance_money);
layer.closeAll('page');
table.reload();
}
}
});
});
form.on('submit(saveGrowth)', function(data) {
if (repeat_flag) return false;
repeat_flag = true;
var growth = {$member_info.growth};
if (data.field.adjust_num == 0) {
layer.msg('调整数值不能为0');
repeat_flag = false;
return ;
}
if (growth*1 + data.field.adjust_num*1 < 0) {
layer.msg('成长值不可以为负数');
repeat_flag = false;
return;
}
$.ajax({
type: "POST",
url: ns.url("member://shop/member/adjustGrowth"),
data: data.field,
dataType: 'JSON',
success: function(res) {
layer.msg(res.message);
repeat_flag = false;
if (res.code == 0) {
$("#member_growth").html(res.data.growth);
$("#member_growth").next().attr('data-num', res.data.growth);
layer.closeAll('page');
table.reload();
}
}
});
});
});
function savePoint(e) {
var point = $(e).attr('data-num');
var data = {
point : point
};
laytpl($("#point").html()).render(data, function(html) {
layer.open({
title: '调整兑换券',
skin: 'layer-tips-class',
type: 1,
area: ['800px'],
content: html
});
});
$(".integral-bounced .amount input").on("input propertychange",function(val){
var newIntegral = parseInt($(this).val());
$(this).val(newIntegral);
var currIntegral = parseInt($(".integral-bounced .ns-account-value").text());
if (newIntegral + currIntegral < 0){
layer.msg("调整数额与当前值兑换券数相加不能小于0");
$(this).val(-currIntegral);
return false;
}
})
}
function saveBalance(e) {
var balance = $(e).attr('data-num');
var data = {
balance : balance
};
laytpl($("#balance").html()).render(data, function(html) {
layer.open({
title: '调整消费券(不可提现)',
skin: 'layer-tips-class',
type: 1,
area: ['800px'],
content: html
});
});
}
function saveBalanceMoney(e) {
var balance_money = $(e).attr('data-num');
var data = {
balance_money : balance_money
};
laytpl($("#balance_money").html()).render(data, function(html) {
layer.open({
title: '调整消费券(可提现)',
skin: 'layer-tips-class',
type: 1,
area: ['800px'],
content: html
});
});
}
function saveGrowth(e) {
var growth = $(e).attr('data-num');
var data = {
growth : growth
};
laytpl($("#growth").html()).render(data, function(html) {
layer.open({
title: '调整成长值',
skin: 'layer-tips-class',
type: 1,
area: ['800px'],
content: html
});
});
}
</script>
<!-- 积分弹框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 ns-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 ns-len-short">
</div>
<span class="ns-word-aux">调整数额与当前兑换券数相加不能小于0</span>
</div>
<div class="layui-form-item">
<label class="layui-form-label">备注:</label>
<div class="layui-input-block ns-len-long">
<textarea class="layui-textarea" name="remark" placeholder="请输入备注"></textarea>
</div>
</div>
<div class="ns-form-row">
<button class="layui-btn ns-bg-color" lay-submit lay-filter="savePoint">确定</button>
</div>
<input type="hidden" name="member_id" value="{$member_info.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 ns-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 ns-len-short">
</div>
<span class="ns-word-aux">调整数额与当前不可提现余额相加不能小于0</span>
</div>
<div class="layui-form-item">
<label class="layui-form-label">备注:</label>
<div class="layui-input-block ns-len-long">
<textarea class="layui-textarea" name="remark" placeholder="请输入备注"></textarea>
</div>
</div>
<div class="ns-form-row">
<button class="layui-btn ns-bg-color" lay-submit lay-filter="saveBalance">确定</button>
</div>
<input type="hidden" name="member_id" value="{$member_info.member_id}" />
<input type="hidden" name="point" value="{{ d.balance }}" />
</div>
</script>
<!-- 消费券可提现弹框html -->
<script type="text/html" id="balance_money">
<div class="layui-form">
<div class="layui-form-item">
<label class="layui-form-label">当前余额(可提现):</label>
<div class="layui-input-block ns-account-value">{{ d.balance_money }}</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 ns-len-short">
</div>
<span class="ns-word-aux">调整数额与当前可提现余额相加不能小于0</span>
</div>
<div class="layui-form-item">
<label class="layui-form-label">备注:</label>
<div class="layui-input-block ns-len-long">
<textarea class="layui-textarea" name="remark" placeholder="请输入备注"></textarea>
</div>
</div>
<div class="ns-form-row">
<button class="layui-btn ns-bg-color" lay-submit lay-filter="saveBalanceMoney">确定</button>
</div>
<input type="hidden" name="member_id" value="{$member_info.member_id}" />
<input type="hidden" name="point" value="{{ d.balance_money }}" />
</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 ns-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 ns-len-short">
</div>
<span class="ns-word-aux">调整数额与当前成长值相加不能小于0</span>
</div>
<div class="layui-form-item">
<label class="layui-form-label">备注:</label>
<div class="layui-input-block ns-len-long">
<textarea class="layui-textarea" name="remark" placeholder="请输入备注"></textarea>
</div>
</div>
<div class="ns-form-row">
<button class="layui-btn ns-bg-color" lay-submit lay-filter="saveGrowth">确定</button>
</div>
<input type="hidden" name="member_id" value="{$member_info.member_id}" />
<input type="hidden" name="point" value="{{ d.growth }}" />
</div>
</script>
{/block}

View File

@ -0,0 +1,192 @@
{extend name="base"/}
{block name="resources"}
<style>
.ns-form {margin-top: 0;}
</style>
{/block}
{block name="main"}
<div class="layui-form ns-form">
<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="required" class="layui-input ns-len-long" autocomplete="off" readonly onfocus="this.removeAttribute('readonly');" onblur="this.setAttribute('readonly',true);">
</div>
<div class="ns-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 ns-len-long">
</div>
<div class="ns-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 ns-len-long">
</div>
<div class="ns-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 ns-len-long">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label img-upload-lable ns-short-label">头像:</label>
<div class="layui-input-inline">
<div class="upload-img-block square">
<div class="upload-img-box">
<div class="ns-upload-default" id="headImg">
<div class="upload">
<img src="SHOP_IMG/upload_img.png" />
<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"><span class="required">*</span>会员等级:</label>
<div class="layui-input-inline ns-len-mid">
<select class="member_level" name="member_level" lay-verify="required" 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 ns-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 ns-len-mid" autocomplete="off">
</div>
</div>
<div class="ns-form-row">
<button class="layui-btn ns-bg-color" lay-submit lay-filter="save">保存</button>
<button class="layui-btn layui-btn-primary" onclick="back()">返回</button>
</div>
</div>
{/block}
{block name="script"}
<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) {
var reg = /^1([38][0-9]|4[579]|5[0-3,5-9]|6[6]|7[0135678]|9[89])\d{8}$/;
if (value == '') {
return;
}
if (!reg.test(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 '请输入正确的邮箱!';
}
}
});
var upload = new Upload({
elem: '#headImg'
});
/**
* 监听提交
*/
form.on('submit(save)', function(data) {
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("member://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(){
location.href = ns.url("member://shop/member/memberList")
},
btn2: function () {
location.href = ns.url("member://shop/member/addMember")
}
});
}else{
layer.msg(res.message);
}
}
});
});
});
function back() {
location.href = ns.url("member://shop/member/memberList");
}
</script>
{/block}

View File

@ -0,0 +1,48 @@
{extend name="base"/}
{block name="resources"}
{/block}
{block name="body"}
<div class="nc-table-box">
<table id="member_address_list" lay-filter="member_address_list"></table>
</div>
{/block}
{block name="script"}
<script>
var table = new Table({
elem: '#member_address_list',
filter: "member_address_list",
url: ns.url("member://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 d.full_address.replace(/-/g, " ") + " " + d.address;
}
}, {
width: '10%',
title: '是否默认地址',
unresize : 'true',
templet: function (d) {
return d.is_default ? "是" : "否";
}
}]],
});
</script>
{/block}

View File

@ -0,0 +1,224 @@
{extend name="base"/}
{block name="resources"}
{/block}
{block name="main"}
<div class="ns-screen layui-collapse" lay-filter="selection_panel">
<div class="layui-colla-item">
<h2 class="layui-colla-title"></h2>
<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="ns-form-row">
<button class="layui-btn ns-bg-color" 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='ns-table-title'>
<div class='ns-title-pic'>
<img layer-src src="{{ns.img(d.headimg)}}" onerror="this.src = 'SHOP_IMG/default_headimg.png' ">
</div>
<div class='ns-title-content'>
<p class="layui-elip">{{d.nickname}}</p>
</div>
</div>
</script>
<!-- 工具栏操作 -->
<script type="text/html" id="operation">
<div class="ns-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>
{/block}
{block name="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("member://shop/member/blacklist"),
cols: [
[
{
width: "3%",
type: 'checkbox',
unresize: 'false'
}, {
field: 'userdetail',
title: '账户',
width: '15%',
unresize: 'false',
templet: '#userdetail'
}, {
field: 'member_level_name',
title: '会员等级',
width: '10%',
unresize: 'false'
}, {
field: 'point',
title: '兑换券',
width: '8%',
unresize: 'false',
align: 'left',
templet: function (data) {
return parseInt(data.point);
}
}, {
field: 'balance',
title: '消费券',
width: '8%',
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: '8%',
unresize: 'false',
align: 'left'
}, {
field: 'reg-login',
title: '最后登录时间',
width: '15%',
unresize: 'false',
templet: function (data) {
return ns.time_to_date(data.last_login_time);
}
}, {
title: '操作',
width: '10%',
unresize: 'false',
toolbar: '#operation'
}
]
],
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() {
$.ajax({
url: ns.url("member://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>
{/block}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,92 @@
{extend name="base"/}
{block name="resources"}
<style>
.ns-card-common:first-of-type{margin-top: 0;}
.layui-card-body{display: flex;padding-bottom: 0 !important;padding-right: 50px !important;padding-left: 50px !important;flex-wrap: wrap;}
.layui-card-body .content{width: 33.3%;display: flex;flex-direction: column;margin-bottom: 30px;justify-content: center;}
.layui-card-body .money{font-size: 20px;color: #666;font-weight: bold;margin-top: 10px;max-width: 250px;}
.layui-card-body .subhead{font-size: 12px;margin-left: 3px;cursor: pointer;}
.ns-single-filter-box {justify-content: left;line-height: 34px}
.ns-single-filter-box a{cursor:pointer;margin-left: 10px}
</style>
{/block}
{block name="main"}
<div class="ns-detail-card ns-tips">
<div class="ns-detail-con">
<p class="ns-detail-line">
<span class="ns-goods-name">会员导入</span>
<span class="ns-text-color">{$info.data.status_name}</span>
</p>
<p class="ns-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}" />
{/block}
{block name="script"}
<script>
var table,upload,repeat_flag = false;
layui.use(['form', 'laydate','laytpl', 'upload'], function() {
var form = layui.form,
laydate = layui.laydate,
currentDate = new Date(),
laytpl = layui.laytpl,
minDate = "";
upload = layui.upload;
record_id = $("#record_id").val();
form.render();
/**
* 表格加载
*/
table = new Table({
elem: '#member_import_log_list',
url: ns.url("member://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: 'app_type',
title: '类型',
width: '20%',
unresize: 'false',
}, {
field: 'open_id',
title: 'openid',
width: '20%',
unresize: 'false',
}, {
field: 'password',
title: '密码',
width: '8%',
unresize: 'false',
}, {
field: 'content',
title: '内容',
width: '21%',
unresize: 'false',
}]
]
});
});
</script>
{/block}

View File

@ -0,0 +1,275 @@
{extend name="base"/}
{block name="resources"}
<style>
.ns-member-block{display: flex;justify-content: space-between;}
.ns-member-block .layui-card{box-shadow: initial;margin-bottom: 0;width: calc((100% - 30px) / 3);margin-right: 9px;height: 180px;box-sizing: border-box;}
.ns-member-block .layui-card:last-child{margin-right: 0}
.ns-member-num{color: red;font-size: 24px;line-height: 50px;}
.ns-member-title{color: #666666;font-size: 16px;}
.layui-card-body{width: 100%;height: 100%;box-sizing: border-box;padding-left: 20px;display: flex;justify-content: space-between;align-items: center;}
.ns-card-member{align-items: flex-start; background-color:#f8f8f8}
#china_echart{width: 600px;height: 600px;flex-shrink: 0;margin: 0 50px}
.ns-member-table{flex: 1;padding: 10px 15px;background: #fff;}
.layui-table-view .layui-table thead tr{background-color: #F5F5F5;}
.ns-split{width: 30px;}
.ns-member-block .layui-card{border: 1px solid #f1f1f1}
.ns-member-table{max-width: 600px;}
@media screen and (max-width: 1330px){.ns-member-block .layui-card:nth-child(3){width: 420px;}
#china_echart{width: 500px;height: 500px;}}
.ns-member-block .layui-card:nth-child(1){background:#ffefe5;}
.ns-member-block .layui-card:nth-child(2){background:#eef2f8;}
.ns-member-block .layui-card:nth-child(3){background:#f8efef;}
.ns-member-block .layui-card:nth-child(1) .ns-member-num{color:#FF6200 }
.ns-member-block .layui-card:nth-child(2) .ns-member-num{color: #3D88FB }
.ns-member-block .layui-card:nth-child(3) .ns-member-num{color:#FF4042}
.ns-body-content{background-color: #f8f8f8 !important}
.layui-card-header{background-color: #f8f8f8}
</style>
{/block}
{block name="main"}
<div class="ns-member-block">
<div class="layui-card">
<div class="layui-card-body">
<div class="ns-member">
<p class="ns-member-title">累计会员数</p>
<p class="ns-member-num">{$data.total_count}</p>
</div>
</div>
</div>
<div class="layui-card">
<div class="layui-card-body">
<div class="ns-member">
<p class="ns-member-title">今日新增会员数</p>
<p class="ns-member-num">{$data.newadd_count}</p>
</div>
</div>
</div>
<div class="layui-card">
<div class="layui-card-body">
<div class="ns-member">
<p class="ns-member-title">下单会员数</p>
<p class="ns-member-num">{$data.buyed_count}</p>
</div>
<div id="main" style="width: 250px; height: 160px;"></div>
</div>
</div>
</div>
<div class="layui-card ns-card-common ns-card-brief">
<div class="layui-card-header">
<span class="ns-card-title">会员分布</span>
</div>
<div class="layui-card-body ns-card-member">
<div id="china_echart"></div>
<div class="ns-split"></div>
<div class="ns-member-table">
<table id="member_list" lay-filter="member_list" class="layui-table"></table>
</div>
</div>
</div>
{/block}
{block name="script"}
<script src="SHOP_JS/echarts.min.js"></script>
<script src="SHOP_JS/china.js"></script>
<script>
layui.use('form', function() {
var table, form = layui.form;
form.render();
table = new Table({
elem: '#member_list',
url: ns.url("member://shop/member/areaCount"),
where: {
handle: true
},
parseData: function(res) { //res 即为原始返回的数据
return {
"code": res.code, //解析接口状态
"msg": res.message, //解析提示文本
"count": res.data.list.length, //解析数据长度
"data": res.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实例
var myChart = echarts.init(document.getElementById('main'));
// 指定图表的配置项和数据
option = {
tooltip: {
trigger: 'item',
formatter: '{a} <br/>{b}: {c} ({d}%)'
},
legend: {
orient: 'vertical',
left: 0,
data: ['下单会员数', '未下单会员数']
},
color: ['#FF4042', '#FFABAC'],
series: [{
width: 120,
height: 120,
top: 30,
left: 130,
name: '',
type: 'pie',
radius: ['50%', '70%'],
avoidLabelOverlap: false,
label: {
show: false,
position: 'center'
},
emphasis: {
label: {
show: true,
fontSize: '12',
color: '#ff8143'
}
},
labelLine: {
show: false
},
data: [
{
value: {$data.buyed_count},
name: '下单会员数',
tooltip: {
trigger: 'item',
backgroundColor: 'rgba(255, 255, 255, 0.7)',
borderColor: '#999',
borderWidth: 1,
padding: 10,
textStyle: {
fontSize: 12,
color: '#333'
}
}
},
{
value: {$data.total_count - $data.buyed_count},
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);
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 areaCount(){
$.ajax({
url: ns.url("member://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();
</script>
{/block}

View File

@ -0,0 +1,142 @@
{extend name="base"/}
{block name="resources"}
<style>
.ns-card-common:first-of-type{margin-top: 0;}
.layui-card-body{display: flex;padding-bottom: 0 !important;padding-right: 50px !important;padding-left: 50px !important;flex-wrap: wrap;}
.layui-card-body .content{width: 33.3%;display: flex;flex-direction: column;margin-bottom: 30px;justify-content: center;}
.layui-card-body .money{font-size: 20px;color: #666;font-weight: bold;margin-top: 10px;max-width: 250px;}
.layui-card-body .subhead{font-size: 12px;margin-left: 3px;cursor: pointer;}
.ns-single-filter-box {justify-content: left;line-height: 34px}
.ns-single-filter-box a{cursor:pointer;margin-left: 10px}
</style>
{/block}
{block name="main"}
<div class="ns-single-filter-box">
<button class="layui-btn ns-bg-color" 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="ns-table-btn">
<a class="layui-btn" lay-event="info">查看</a>
</div>
</script>
{/block}
{block name="script"}
<script>
var table,upload,repeat_flag = false;
layui.use(['form', 'laydate','laytpl', 'upload'], function() {
var form = layui.form,
laydate = layui.laydate,
currentDate = new Date(),
laytpl = layui.laytpl,
minDate = "";
upload = layui.upload;
form.render();
/**
* 表格加载
*/
table = new Table({
elem: '#member_import_log_list',
url: ns.url("member://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: '操作',
width: '10%',
unresize: 'false',
toolbar: '#operation'
}]
]
});
//允许上传的文件后缀
upload.render({
elem: '#member_file'
,url: ns.url("member://shop/member/file"),
accept: 'file',
exts: 'xlsx',
done: function(res){
if (res.code >= 0) {
member_import(1, res.data.name, res.data.path);
repeat_flag = false;
}else{
layer.msg(res.message);
}
}
});
/**
* 监听工具栏操作
*/
table.tool(function(obj) {
var data = obj.data;
switch (obj.event) {
case 'info': //查看
location.href = ns.url("member://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("member://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();
}
}
layer.msg(res.message);
}
});
}
function downloadMemberFile(){
location.href = ns.url("member://shop/member/downloadMemberFile");
return false;
}
</script>
{/block}

View File

@ -0,0 +1,210 @@
{extend name="base"/}
{block name="resources"}
{/block}
{block name="body"}
<div class="nc-table-box">
<table id="member_coupon_list" lay-filter="member_coupon_list"></table>
</div>
<!--获取方式-->
<script type="text/html" id="get_type">
{{# if(d.get_type == 1){ }}
<div class="layui-elip">订单领取</div>
{{# }else if(d.get_type == 2){ }}
<div class="layui-elip">直接领取</div>
{{# }else if(d.get_type == 3){ }}
<div class="layui-elip">获取领取</div>
{{# }else if(d.get_type == 4){ }}
<div class="layui-elip">转赠</div>
{{# }else if(d.get_type == 5){ }}
<div class="layui-elip">分享获取</div>
{{# } }}
</script>
<!--状态-->
<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>
{/block}
{block name="script"}
<script>
var table = new Table({
elem: '#member_coupon_list',
filter: "member_coupon_list",
url: ns.url("member://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: '#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>
{/block}{extend name="base"/}
{block name="resources"}
{/block}
{block name="body"}
<div class="nc-table-box">
<table id="member_coupon_list" lay-filter="member_coupon_list"></table>
</div>
<!--获取方式-->
<script type="text/html" id="get_type">
{{# if(d.get_type == 1){ }}
<div class="layui-elip">订单领取</div>
{{# }else if(d.get_type == 2){ }}
<div class="layui-elip">直接领取</div>
{{# }else if(d.get_type == 3){ }}
<div class="layui-elip">获取领取</div>
{{# }else if(d.get_type == 4){ }}
<div class="layui-elip">转赠</div>
{{# }else if(d.get_type == 5){ }}
<div class="layui-elip">分享获取</div>
{{# } }}
</script>
<!--状态-->
<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>
{/block}
{block name="script"}
<script>
var table = new Table({
elem: '#member_coupon_list',
filter: "member_coupon_list",
url: ns.url("member://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: '#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>
{/block}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,138 @@
{extend name="base"/}
{block name="resources"}
{/block}
{block name="body"}
<!-- 搜索框 -->
<div class="ns-single-filter-box">
<div class="layui-form" lay-filter="trade_search">
<div class="layui-input-inline ns-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="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="ns-table-btn">
<a class="layui-btn" lay-event="detail">详情</a>
</div>
</script>
{/block}
{block name="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: '10%',
unresize: 'false'
},{
field: 'site_name',
title: '店铺名称',
width: '10%',
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: 'pay_money',
title: '实际支付金额',
align: 'right',
width: '10%',
unresize: 'false',
templet: function(data) {
return '¥' + data.order_money;
}
}, {
field: 'balance_money',
title: '使用余额',
align: 'right',
width: '10%',
unresize: 'false',
templet: function(data) {
return '¥' + data.order_money;
}
}, {
width: '4%',
unresize: 'false'
}, {
field: 'order_type_name',
title: '订单类型',
width: '8%',
unresize: 'false'
}, {
field: 'order_status_name',
title: '订单状态',
width: '8%',
unresize: 'false'
}, {
field: 'create_time',
title: '下单时间',
width: '10%',
templet: function(data) {
return ns.time_to_date(data.create_time)
}
}, {
title: '操作',
width: '8%',
unresize: 'false',
toolbar: '#operation'
}]
]
});
/**
* 监听工具栏操作
*/
table.tool(function(obj) {
var data = obj.data;
switch (obj.event) {
case 'detail': //详情
var url = "shop/order/detail";
window.open(ns.url(url,{order_id:data.order_id}));
break;
}
});
/**
* 搜索功能
*/
form.on('submit(search)', function(data) {
table.reload({
page: {
curr: 1
},
where: data.field
});
return false;
});
})
</script>
{/block}

View File

@ -0,0 +1,92 @@
{extend name="base"/}
{block name="resources"}
<style type="text/css">
.ns-form {position: relative;}
.examples {color: #ff8833; cursor: pointer;}
</style>
{/block}
{block name="main"}
<div class="layui-collapse ns-tips">
<div class="layui-colla-item">
<h2 class="layui-colla-title">操作提示</h2>
<ul class="layui-colla-content layui-show">
<li>协议内容展示使用该网站的一些相关规定</li>
<li>注册会员时需同意该协议才可继续注册 <a onclick="showDemo()" class="examples ns-text-color">查看示例</a></li>
</ul>
</div>
</div>
<div class="layui-form ns-form">
<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 ns-len-long">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">内容:</label>
<div class="layui-input-inline">
<script id="editor" type="text/plain" class="ns-special-length" style="height:300px;"></script>
</div>
</div>
<div class="ns-form-row">
<button class="layui-btn ns-bg-color" lay-submit lay-filter="save">保存</button>
</div>
<input type="hidden" name="" id="agreementContent" value="{$document_info.data.content}" />
</div>
{/block}
{block name="script"}
<script type="text/javascript" charset="utf-8" src="STATIC_EXT/ueditor/ueditor.config.js"></script>
<script type="text/javascript" charset="utf-8" src="STATIC_EXT/ueditor/ueditor.all.js"></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("member://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;
if (res.code == 0) {
location.reload();
}
}
});
});
});
function showDemo(){
layer.open({
title: '查看示例',
type: 1,
area: ['500px', '660px'],
content: '<img style="margin: 20px 80px;" src="SHOP_IMG/reg_info.png">'
})
}
</script>
{/block}

View File

@ -0,0 +1,215 @@
{extend name="base"/}
{block name="resources"}
<style>
.layui-form-item .layui-form-checkbox[lay-skin=primary] {
margin-top: 0;
}
.ns-text-color-red:hover {
color: red;
}
.desc{
margin-bottom: 15px;border:1px dashed #ff8143;padding: 5px 10px;background: #fff0e9;color: #ff8143;width: 65%;
}
.ns-word-aux{
width: 50%!important;
}
.examples {color: #ff8833; 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>
{/block}
{block name="main"}
<div class="layui-form ns-form">
<div class="layui-card ns-card-common ns-card-brief">
<div class="layui-card-header">
<div>
<span class="ns-card-title">普通登录注册设置<a onclick="showDemo1()" class="examples ns-text-color">查看示例</a></span>
</div>
</div>
<div class="layui-card-body">
<div class="desc">
设置在非第三方平台(第三方平台是指微信公众号,微信小程序,支付宝小程序等平台内部)或第三方平台自动注册未开启情况下会员的注册登录方式。
</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="ns-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="ns-word-aux">手机号是指通过手机号加动态验证码的注册登录方式。</div>
<div class="ns-word-aux">启用前需配置好“注册验证”,“动态码登录”短信模板,<a href="{:addon_url('shop/message/lists')}" class="ns-text-color" >前去配置</a></div>
</div>
<div class="layui-form-item">
<label class="layui-form-label ">邀请推荐码:</label>
<div class="layui-input-block">
<input type="checkbox" name="is_rcode" value="1" lay-filter="third_party" lay-skin="switch" {if condition="isset($value.is_rcode) && $value.is_rcode == 1"} checked {/if} >
</div>
<div class="ns-word-aux">新用户注册必须通过邀请码才可以注册成功</div>
</div>
</div>
</div>
<div class="layui-card ns-card-common ns-card-brief">
<div class="layui-card-header">
<div>
<span class="ns-card-title">第三方平台注册设置<a onclick="showDemo2()" class="examples ns-text-color">查看示例</a></span>
</div>
</div>
<div class="layui-card-body">
<div class="desc">
第三方平台注册是指在微信公众号,微信小程序,支付宝小程序等平台下会员的注册方式.
</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="ns-word-aux">第三方直接注册是指系统通过获取第三方的粉丝信息直接注册会员,会员用户名随机生成,昵称是第三方获取的用户昵称,注册过程中会将第三方平台获取的信息绑定到注册的会员,方便后期直接自动登录。若关闭,系统将按照普通注册方式注册会员。</div>
<div class="ns-word-aux ns-text-color">注∶第三方直接注册会员如果不强制绑定手机情况下会导致在不同第三方平台会员无法统一,如果只是在微信环境(微信公众号与微信小程序),可以通过绑定<a href="https://open.weixin.qq.com/" class="ns-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="ns-word-aux">为了实现不同的第三方平台用户账户的统一,需要在注册过程中强制绑定用户手机,通过手机实现微信平台与支付宝平台,抖音平台等账号的统一。开启之后在对应会员相关页面会引导会员绑定手机账号。</div>
<div class="ns-word-aux">启用前需配置好“账户绑定”短信模板,<a href="{:addon_url('shop/message/lists')}" class="ns-text-color" >前去配置</a></div>
</div>
</div>
</div>
<div class="layui-card ns-card-common ns-card-brief">
<div class="layui-card-header">
<div>
<span class="ns-card-title">密码设置</span>
</div>
</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 ns-len-short" lay-verify="pwd_lens" value="{$value.pwd_len}">
</div>
<div class="ns-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="ns-word-aux">设置密码复杂度</div>
</div>
</div>
</div>
<div class="ns-form-row">
<button type="button" class="layui-btn ns-bg-color" lay-submit lay-filter="save">保存</button>
</div>
</div>
{/block}
{block name="script"}
<script>
layui.use(['form','carousel'], function() {
var form = layui.form;
var carousel = layui.carousel;
repeat_flag = false; //防重复
form.render();
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("member://shop/member/regConfig"),
data: data.field,
dataType: 'JSON',
type: 'POST',
success: function(res) {
layer.msg(res.message);
repeat_flag = false;
if (res.code == 0) {
location.reload();
}
}
});
});
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){ //value表单的值、item表单的DOM对象
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>
{/block}

View File

@ -0,0 +1,721 @@
{extend name="base"/}
{block name="resources"}
<style>
.ns-form {margin-top: 0;}
.layui-btn+.layui-btn {margin-left: 0;}
.layui-btn {margin-right: 10px; margin-bottom: 15px;}
.weight-list span{display: inline-block;width: 60px;line-height: 30px;border:1px solid #eee;border-radius: 4px;text-align: center;font-size: 12px;cursor: pointer;}
.weight-list span.active{border-color: #ff8143; }
.weight-list span.disabled{background:#f1f1f1;cursor: not-allowed; }
</style>
{/block}
{block name="main"}
<div class="layui-form ns-form">
<!-- 基础上传 -->
<div class="layui-card ns-card-common ns-card-brief">
<div class="layui-card-header">
<span class="ns-card-title">基础设置</span>
</div>
<div class="layui-card-body">
<div class="layui-form-item">
<label class="layui-form-label"><span class="required">*</span>群体名称:</label>
<div class="layui-input-block">
<input type="text" name="cluster_name" lay-verify="required" autocomplete="off" class="layui-input ns-len-mid">
</div>
</div>
</div>
</div>
<div class="layui-card ns-card-common ns-card-brief">
<div class="layui-card-header">
<span class="ns-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">
<button class="layui-btn layui-btn-primary ns-cluster-btn">会员等级<input type="hidden" value="0" /></button>
<button class="layui-btn layui-btn-primary ns-cluster-btn">会员标签<input type="hidden" value="1" /></button>
<button class="layui-btn layui-btn-primary ns-cluster-btn">性别<input type="hidden" value="2" /></button>
<button class="layui-btn layui-btn-primary ns-cluster-btn">生日<input type="hidden" value="3" /></button>
<button class="layui-btn layui-btn-primary ns-cluster-btn">注册时间<input type="hidden" value="4" /></button>
<button class="layui-btn layui-btn-primary ns-cluster-btn">当前积分<input type="hidden" value="5" /></button>
<button class="layui-btn layui-btn-primary ns-cluster-btn">当前余额<input type="hidden" value="6" /></button>
<button class="layui-btn layui-btn-primary ns-cluster-btn">当前成长值<input type="hidden" value="7" /></button>
<button class="layui-btn layui-btn-primary ns-cluster-btn">连续签到次数<input type="hidden" value="8" /></button>
<button class="layui-btn layui-btn-primary ns-cluster-btn">会员手机<input type="hidden" value="9" /></button>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">会员消费情况</label>
<div class="layui-input-block">
<button class="layui-btn layui-btn-primary ns-cluster-btn">付款金额<input type="hidden" value="10" /></button>
<button class="layui-btn layui-btn-primary ns-cluster-btn">消费金额<input type="hidden" value="11" /></button>
<button class="layui-btn layui-btn-primary ns-cluster-btn">付款次数<input type="hidden" value="12" /></button>
<button class="layui-btn layui-btn-primary ns-cluster-btn">消费次数<input type="hidden" value="13" /></button>
</div>
</div>
</div>
</div>
<div class="layui-card ns-card-common ns-card-brief">
<div class="layui-card-header">
<span class="ns-card-title">群体设置</span>
</div>
<div class="layui-card-body">
<div class="layui-form-item">
<div class="layui-input-block">
<table class="layui-table" id="goods" lay-skin="line" lay-size="lg">
<colgroup>
<col width="15%">
<col width="20%">
<col width="50%">
<col width="10%">
</colgroup>
<thead>
<tr>
<th>选项</th>
<th>范围</th>
<th>条件</th>
<th class="operation">操作</th>
</tr>
</thead>
<tbody>
<tr class="ns-cluster-content layui-hide">
<td>会员等级</td>
<td>
<input type="radio" class="include" name="basic[member_level][include]" value="1" title="包含" checked>
<input type="radio" class="include" name="basic[member_level][include]" value="2" title="不包含">
</td>
<td>
<div class="layui-input-inline">
<input type="text" autocomplete="off" class="layui-input member-level-con" readonly onclick="settinglevel()">
<input type="hidden" name="basic[member_level][content]">
</div>
<input type="hidden" class="is-show" name="basic[member_level][is_show]" value="0">
</td>
<td class='operation'>
<div class='ns-table-btn '><a href='javascript:;' class='layui-btn' onclick='delDiv(this)'>删除</a></div>
</td>
</tr>
<tr class="ns-cluster-content layui-hide">
<td>会员标签</td>
<td>
<input type="radio" class="include" name="basic[member_label][include]" value="1" title="包含" checked>
<input type="radio" class="include" name="basic[member_label][include]" value="2" title="不包含">
</td>
<td>
<div class="layui-input-inline">
<input type="text" autocomplete="off" class="layui-input member-label-con" readonly onclick="settinglabel()">
<input type="hidden" name="basic[member_label][content]">
</div>
<input type="hidden" class="is-show" name="basic[member_label][is_show]" value="0">
</td>
<td class='operation'>
<div class='ns-table-btn '><a href='javascript:;' class='layui-btn' onclick='delDiv(this)'>删除</a></div>
</td>
</tr>
<tr class="ns-cluster-content layui-hide">
<td>会员性别</td>
<td>
<input type="radio" class="include" name="basic[sex][include]" value="1" title="包含" checked>
<input type="radio" class="include" name="basic[sex][include]" value="2" title="不包含">
</td>
<td>
<input type="checkbox" class="ns-input-checkbox" lay-skin="primary" lay-filter="sex" name="basic[sex][content]" value="0" title="保密">
<input type="checkbox" class="ns-input-checkbox" lay-skin="primary" lay-filter="sex" name="basic[sex][content]" value="1" title="男">
<input type="checkbox" class="ns-input-checkbox" lay-skin="primary" lay-filter="sex" name="basic[sex][content]" value="2" title="女">
<input type="hidden" class="is-show" name="basic[sex][is_show]" value="0">
</td>
<td class='operation'>
<div class='ns-table-btn '><a href='javascript:;' class='layui-btn' onclick='delDiv(this)'>删除</a></div>
</td>
</tr>
<tr class="ns-cluster-content layui-hide">
<td>会员生日</td>
<td>
<input type="radio" class="include" name="basic[birthday][include]" value="1" title="包含" checked>
<input type="radio" class="include" name="basic[birthday][include]" value="2" title="不包含">
</td>
<td>
<div class="layui-input-inline">
<input type="text" class="layui-input layui-input-start" name="basic[birthday][start]" id="birthday_start_date" placeholder="请输入开始时间"
autocomplete="off" readonly>
</div>
<div class="layui-input-inline ns-split">-</div>
<div class="layui-input-inline end-time">
<input type="text" class="layui-input layui-input-end" name="basic[birthday][end]" id="birthday_end_date" placeholder="请输入结束时间"
autocomplete="off" readonly>
</div>
<input type="hidden" class="is-show" name="basic[birthday][is_show]" value="0">
</td>
<td class='operation'>
<div class='ns-table-btn '><a href='javascript:;' class='layui-btn' onclick='delDiv(this)'>删除</a></div>
</td>
</tr>
<tr class="ns-cluster-content layui-hide">
<td>注册时间</td>
<td>
<input type="radio" class="include" name="basic[reg_time][include]" value="1" title="包含" checked>
<input type="radio" class="include" name="basic[reg_time][include]" value="2" title="不包含">
</td>
<td>
<div class="layui-input-inline">
<input type="text" class="layui-input layui-input-start" name="basic[reg_time][start]" id="reg_start_date" placeholder="请输入开始时间"
autocomplete="off" readonly>
</div>
<div class="layui-input-inline ns-split">-</div>
<div class="layui-input-inline end-time">
<input type="text" class="layui-input layui-input-end" name="basic[reg_time][end]" id="reg_end_date" placeholder="请输入结束时间"
autocomplete="off" readonly>
</div>
<input type="hidden" class="is-show" name="basic[reg_time][is_show]" value="0">
</td>
<td class='operation'>
<div class='ns-table-btn '><a href='javascript:;' class='layui-btn' onclick='delDiv(this)'>删除</a></div>
</td>
</tr>
<tr class="ns-cluster-content layui-hide">
<td>当前积分</td>
<td>
<input type="radio" class="include" name="basic[point][include]" value="1" title="包含" checked>
<input type="radio" class="include" name="basic[point][include]" value="2" title="不包含">
</td>
<td>
<div class="layui-input-inline">
<input type="number" class="layui-input layui-input-start layui-input-int" name="basic[point][start]" placeholder="请输入积分最小值" autocomplete="off" min="0">
</div>
<div class="layui-input-inline ns-split">-</div>
<div class="layui-input-inline end-time">
<input type="number" class="layui-input layui-input-end layui-input-int" name="basic[point][end]" placeholder="请输入积分最大值" autocomplete="off" min="0">
</div>
<input type="hidden" class="is-show" name="basic[point][is_show]" value="0">
</td>
<td class='operation'>
<div class='ns-table-btn '><a href='javascript:;' class='layui-btn' onclick='delDiv(this)'>删除</a></div>
</td>
</tr>
<tr class="ns-cluster-content layui-hide">
<td>当前余额</td>
<td>
<input type="radio" class="include" name="basic[balance][include]" value="1" title="包含" checked>
<input type="radio" class="include" name="basic[balance][include]" value="2" title="不包含">
</td>
<td>
<div class="layui-input-inline">
<input type="number" class="layui-input layui-input-start layui-input-flo" name="basic[balance][start]" placeholder="请输入当前余额最小值" autocomplete="off" min="0">
</div>
<div class="layui-input-inline ns-split">-</div>
<div class="layui-input-inline end-time">
<input type="number" class="layui-input layui-input-end layui-input-flo" name="basic[balance][end]" placeholder="请输入当前余额最大值" autocomplete="off" min="0">
</div>
<input type="hidden" class="is-show" name="basic[balance][is_show]" value="0">
</td>
<td class='operation'>
<div class='ns-table-btn '><a href='javascript:;' class='layui-btn' onclick='delDiv(this)'>删除</a></div>
</td>
</tr>
<tr class="ns-cluster-content layui-hide">
<td>当前成长值</td>
<td>
<input type="radio" class="include" name="basic[growth][include]" value="1" title="包含" checked>
<input type="radio" class="include" name="basic[growth][include]" value="2" title="不包含">
</td>
<td>
<div class="layui-input-inline">
<input type="number" class="layui-input layui-input-start layui-input-flo" name="basic[growth][start]" placeholder="请输入当前成长值最小值" autocomplete="off" min="0">
</div>
<div class="layui-input-inline ns-split">-</div>
<div class="layui-input-inline end-time">
<input type="number" class="layui-input layui-input-end layui-input-flo" name="basic[growth][end]" placeholder="请输入当前成长值最大值" autocomplete="off" min="0">
</div>
<input type="hidden" class="is-show" name="basic[growth][is_show]" value="0">
</td>
<td class='operation'>
<div class='ns-table-btn '><a href='javascript:;' class='layui-btn' onclick='delDiv(this)'>删除</a></div>
</td>
</tr>
<tr class="ns-cluster-content layui-hide">
<td>签到次数</td>
<td>
<input type="radio" class="include" name="basic[sign_days_series][include]" value="1" title="包含" checked>
<input type="radio" class="include" name="basic[sign_days_series][include]" value="2" title="不包含">
</td>
<td>
<div class="layui-input-inline">
<input type="number" class="layui-input layui-input-start layui-input-int" name="basic[sign_days_series][start]" placeholder="请输入签到次数最小值" autocomplete="off" min="0">
</div>
<div class="layui-input-inline ns-split">-</div>
<div class="layui-input-inline end-time">
<input type="number" class="layui-input layui-input-end layui-input-int" name="basic[sign_days_series][end]" placeholder="请输入签到次数最大值" autocomplete="off" min="0">
</div>
<input type="hidden" class="is-show" name="basic[sign_days_series][is_show]" value="0">
</td>
<td class='operation'>
<div class='ns-table-btn '><a href='javascript:;' class='layui-btn' onclick='delDiv(this)'>删除</a></div>
</td>
</tr>
<tr class="ns-cluster-content layui-hide">
<td>会员手机</td>
<td>
<input type="radio" class="include" name="basic[mobile][include]" value="1" title="包含" checked>
<input type="radio" class="include" name="basic[mobile][include]" value="2" title="不包含">
</td>
<td>
<div class="layui-input-inline">
<input type="text" name="basic[mobile][content]" autocomplete="off" class="layui-input member-mobile">
</div>
<input type="hidden" class="is-show" name="basic[mobile][is_show]" value="0">
</td>
<td class='operation'>
<div class='ns-table-btn '><a href='javascript:;' class='layui-btn' onclick='delDiv(this)'>删除</a></div>
</td>
</tr>
<tr class="ns-cluster-content layui-hide">
<td>付款金额</td>
<td>
<input type="radio" class="include" name="consume[order_money][include]" value="1" title="包含" checked>
<input type="radio" class="include" name="consume[order_money][include]" value="2" title="不包含">
</td>
<td>
<div class="layui-input-inline">
<input type="number" class="layui-input layui-input-start layui-input-flo" name="consume[order_money][start]" placeholder="请输入付款金额最小值" autocomplete="off" min="0">
</div>
<div class="layui-input-inline ns-split">-</div>
<div class="layui-input-inline end-time">
<input type="number" class="layui-input layui-input-end layui-input-flo" name="consume[order_money][end]" placeholder="请输入付款金额最大值" autocomplete="off" min="0">
</div>
<input type="hidden" class="is-show" name="consume[order_money][is_show]" value="0">
</td>
<td class='operation'>
<div class='ns-table-btn '><a href='javascript:;' class='layui-btn' onclick='delDiv(this)'>删除</a></div>
</td>
</tr>
<tr class="ns-cluster-content layui-hide">
<td>消费金额</td>
<td>
<input type="radio" class="include" name="consume[order_complete_money][include]" value="1" title="包含" checked>
<input type="radio" class="include" name="consume[order_complete_money][include]" value="2" title="不包含">
</td>
<td>
<div class="layui-input-inline">
<input type="number" class="layui-input layui-input-start layui-input-flo" name="consume[order_complete_money][start]" placeholder="请输入消费金额最小值" autocomplete="off" min="0">
</div>
<div class="layui-input-inline ns-split">-</div>
<div class="layui-input-inline end-time">
<input type="number" class="layui-input layui-input-end layui-input-flo" name="consume[order_complete_money][end]" placeholder="请输入消费金额最大值" autocomplete="off" min="0">
</div>
<input type="hidden" class="is-show" name="consume[order_complete_money][is_show]" value="0">
</td>
<td class='operation'>
<div class='ns-table-btn '><a href='javascript:;' class='layui-btn' onclick='delDiv(this)'>删除</a></div>
</td>
</tr>
<tr class="ns-cluster-content layui-hide">
<td>付款次数</td>
<td>
<input type="radio" class="include" name="consume[order_num][include]" value="1" title="包含" checked>
<input type="radio" class="include" name="consume[order_num][include]" value="2" title="不包含">
</td>
<td>
<div class="layui-input-inline">
<input type="number" class="layui-input layui-input-start layui-input-int" name="consume[order_num][start]" placeholder="请输入付款次数最小值" autocomplete="off" min="0">
</div>
<div class="layui-input-inline ns-split">-</div>
<div class="layui-input-inline end-time">
<input type="number" class="layui-input layui-input-end layui-input-int" name="consume[order_num][end]" placeholder="请输入付款次数最大值" autocomplete="off" min="0">
</div>
<input type="hidden" class="is-show" name="consume[order_num][is_show]" value="0">
</td>
<td class='operation'>
<div class='ns-table-btn '><a href='javascript:;' class='layui-btn' onclick='delDiv(this)'>删除</a></div>
</td>
</tr>
<tr class="ns-cluster-content layui-hide">
<td>消费次数</td>
<td>
<input type="radio" class="include" name="consume[order_complete_num][include]" value="1" title="包含" checked>
<input type="radio" class="include" name="consume[order_complete_num][include]" value="2" title="不包含">
</td>
<td>
<div class="layui-input-inline">
<input type="number" class="layui-input layui-input-start layui-input-int" name="consume[order_complete_num][start]" placeholder="请输入消费次数最小值" autocomplete="off" min="0">
</div>
<div class="layui-input-inline ns-split">-</div>
<div class="layui-input-inline end-time">
<input type="number" class="layui-input layui-input-end layui-input-int" name="consume[order_complete_num][end]" placeholder="请输入消费次数最大值" autocomplete="off" min="0">
</div>
<input type="hidden" class="is-show" name="consume[order_complete_num][is_show]" value="0">
</td>
<td class='operation'>
<div class='ns-table-btn '><a href='javascript:;' class='layui-btn' onclick='delDiv(this)'>删除</a></div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="ns-form-row">
<button class="layui-btn ns-bg-color" lay-submit lay-filter="calculate">计算会员数</button>
<div>符合条件的群体人数: <span class="member_num ns-text-color">0</span> 人,点击计算按钮可查看符合条件的群体人数。</div>
</div>
</div>
<div class="layui-card-body">
<div class="ns-form-row">
<button class="layui-btn ns-bg-color" lay-submit lay-filter="save">保存</button>
<button class="layui-btn layui-btn-primary" onclick="back()">返回</button>
</div>
</div>
</div>
</div>
{/block}
{block name="script"}
<script>
$(function(){
$('.weight-list span').not('.disabled').eq(0).addClass("active");
})
var form, laytpl, laydate, isClick = false, member_num = 0, member_ids = '', sexVal = [];
layui.use(['form', 'laytpl', 'laydate'], function() {
form = layui.form;
laytpl = layui.laytpl;
laydate = layui.laydate;
var repeat_flag = false; //防重复标识
form.render();
//生日开始时间
laydate.render({
elem: '#birthday_start_date',
type: 'datetime'
});
//生日结束时间
laydate.render({
elem: '#birthday_end_date',
type: 'datetime'
});
//注册开始时间
laydate.render({
elem: '#reg_start_date',
type: 'datetime'
});
//注册结束时间
laydate.render({
elem: '#reg_end_date',
type: 'datetime'
});
$(".weight-list span").click(function() {
if (!$(this).hasClass("disabled")) {
$(this).addClass("active");
$(this).siblings().removeClass("active");
}
});
$(".ns-cluster-btn").click(function() {
var _index = $(this).children().val();
if (!$(this).hasClass("ns-border-color")) {
$(this).addClass("ns-border-color");
$(".ns-cluster-content").eq(_index).removeClass("layui-hide");
$(".ns-cluster-content").eq(_index).find(".is-show").val(1);
$(".ns-cluster-content").eq(_index).find(".layui-input-inline input.layui-input").attr("lay-verify", "notnull");
$(".ns-cluster-content").eq(_index).find(".layui-input-inline input.layui-input-start").attr("lay-verify", "notnull|start");
$(".ns-cluster-content").eq(_index).find(".layui-input-inline input.layui-input-end").attr("lay-verify", "notnull|end");
$(".ns-cluster-content").eq(_index).find(".layui-input-inline input[type='number']").attr("lay-verify", "notnull|end|num");
$(".ns-cluster-content").eq(_index).find(".layui-input-inline input.member-mobile").attr("lay-verify", "notnull|len");
$(".ns-cluster-content").eq(_index).find(".layui-input-inline input.layui-input-int.layui-input-start").attr("lay-verify", "notnull|start|num|int");
$(".ns-cluster-content").eq(_index).find(".layui-input-inline input.layui-input-flo.layui-input-end").attr("lay-verify", "notnull|end|num|flo");
}
//点击了需要重新计算
// isClick = false;
form.render();
});
form.on('submit(calculate)', function(data) {
// isClick = true;
var rule_json = resetData(data.field);
if (rule_json.basic.sex.is_show == 1) {
var flag = false;
$(".ns-input-checkbox").each(function() {
var isChecked = $(this).is(":checked");
if (isChecked) {
flag = true;
}
});
if (!flag) {
layer.msg("请选择性别", {icon: 5, anim: 6});
return false;
}
}
$.ajax({
url: ns.url("member://shop/membercluster/calculate"),
type: "POST",
dataType: "JSON",
data: {
rule_json: JSON.stringify(rule_json)
},
success: function(res) {
if (res.code >= 0) {
member_num = res.data.member_num;
member_ids = res.data.member_ids;
$(".member_num").html(member_num);
}
}
})
});
form.on('submit(save)', function(data) {
// if (isClick) {
var rule_json = resetData(data.field);
$.ajax({
url: ns.url("member://shop/membercluster/addCluster"),
type: "POST",
dataType: "JSON",
data: {
cluster_name: data.field.cluster_name,
rule_json: JSON.stringify(rule_json),
},
success: function(res) {
if (res.code >= 0) {
layer.confirm('添加成功', {
title:'操作提示',
btn: ['返回列表', '继续添加'],
closeBtn: 0,
yes: function(){
location.href = ns.url("member://shop/membercluster/clusterList")
},
btn2: function () {
location.href = ns.url("member://shop/membercluster/addCluster")
}
});
}else{
layer.msg(res.message);
}
}
})
// } else {
// layer.msg("请先计算会员数", {icon: 5, anim: 6});
// }
});
form.on('submit(setlabel)', function(obj) {
var field = obj.field;
var arr_id = [], temp = [];
for (var prop in field) {
arr_id.push(field[prop]);
$("#set_label").find("input").each(function() {
var label_id = $(this).attr("data-id");
if (field[prop] == label_id) {
temp.push($(this).attr("title"))
}
})
}
$(".member-label-con").val(temp);
$("input[name='basic[member_label][content]']").val(arr_id);
layer.closeAll('page');
});
form.on('submit(setlevel)', function(obj) {
var field = obj.field;
var arr_id = [], temp = [];
for (var prop in field) {
arr_id.push(field[prop]);
$("#set_level").find("input").each(function() {
var level_id = $(this).attr("data-id");
if (field[prop] == level_id) {
temp.push($(this).attr("title"))
}
})
}
$(".member-level-con").val(temp);
$("input[name='basic[member_level][content]']").val(arr_id);
layer.closeAll('page');
});
/**
* 表单验证
*/
form.verify({
notnull: function(value, item) {
var str = $(item).parents(".ns-cluster-content").find("td").eq(0).text();
if (value == '') {
return str + '不能为空';
}
},
end: function(value, item) {
var start = $(item).parents(".ns-cluster-content").find(".layui-input-start").val();
var str1 = $(item).attr("placeholder").slice(3);
var str2 = $(item).parents(".ns-cluster-content").find(".layui-input-start").attr("placeholder").slice(3);
if (Number(value) < Number(start)) {
return str1 + "不能小于" + str2;
}
},
num: function(value, item) {
var str = $(item).parents(".ns-cluster-content").find("td").eq(0).text();
if (value < 0) {
return str + "不能小于0";
}
},
len: function(value, item) {
if (value.length > 11) {
return "手机号为11位";
}
},
int: function(value, item) {
var str = $(item).parents(".ns-cluster-content").find("td").eq(0).text();
if (value % 1 != 0) {
return str + "不能为小数";
}
},
flo: function(value, item) {
var str = $(item).parents(".ns-cluster-content").find("td").eq(0).text();
if (value * 100 % 1 != 0) {
return str + "最多保留两位小数";
}
}
})
});
/**
* 设置标签
*/
function settinglabel() {
laytpl($("#label_change").html()).render({}, function(html) {
layer_label = layer.open({
title: '设置标签',
skin: 'layer-tips-class',
type: 1,
area: ['450px','260px'],
content: html,
});
});
form.render();
}
/**
* 设置等级
*/
function settinglevel() {
laytpl($("#level_change").html()).render({}, function(html) {
layer_level = layer.open({
title: '设置等级',
skin: 'layer-tips-class',
type: 1,
area: ['450px','260px'],
content: html,
});
});
form.render();
}
function delDiv(e) {
var _len = $(e).parents(".ns-cluster-content").index();
$(e).parents(".ns-cluster-content").addClass("layui-hide");
$(e).parents(".ns-cluster-content").find("input").removeAttr("lay-verify");
$(e).parents(".ns-cluster-content").find(".layui-input-inline input").val("");
$(e).parents(".ns-cluster-content").find(".is-show").val(0);
$(e).parents(".ns-cluster-content").find("input[name='basic[sex][content]']").prop("checked",false);
$(".ns-cluster-btn").eq(_len).removeClass("ns-border-color");
}
function closeLabel() {
layer.close(layer_label);
}
function closeLevel() {
layer.close(layer_level);
}
function back() {
location.href = ns.url("member://shop/membercluster/clusterList");
}
// 数据结构
function resetData(data) {
var rule_json = {};
$.each(data, function(index, item) {
if (index.indexOf("[") != -1) {
var arr = index.split("[");
if (rule_json[arr[0]] == undefined) {
rule_json[arr[0]] = {};
}
var name = arr[1].slice(0, arr[1].length - 1);
if (rule_json[arr[0]][name] == undefined) {
rule_json[arr[0]][name] = {};
}
var attr = arr[2].slice(0, arr[2].length - 1);
rule_json[arr[0]][name][attr] = item;
}
})
sexVal = [];
$("input[name='basic[sex][content]']:checked").each(function (index, item) {
sexVal.push($(this).val());
});
rule_json.basic.sex.content = sexVal.toString();
return rule_json;
}
</script>
<!-- 设置标签弹框html -->
<script type="text/html" id="label_change">
<div class="layui-form member-form" id="set_label" lay-filter="form">
<div class="layui-form-item">
<label class="layui-form-label sm">标签:</label>
<div class="layui-input-block">
{foreach $member_label_list as $member_label_list_k => $member_label_list_v}
<input type="checkbox" name="label_id{$member_label_list_v.label_id}" data-id="{$member_label_list_v.label_id}" value="{$member_label_list_v.label_id}" title="{$member_label_list_v.label_name}" lay-skin="primary">
{/foreach}
</div>
</div>
<div class="ns-form-row sm">
<button class="layui-btn ns-bg-color" lay-submit lay-filter="setlabel">确定</button>
<button class="layui-btn layui-btn-primary" onclick="closeLabel()">返回</button>
</div>
</div>
</script>
<!-- 设置标签弹框html -->
<script type="text/html" id="level_change">
<div class="layui-form member-form" id="set_level" lay-filter="form">
<div class="layui-form-item">
<label class="layui-form-label sm">等级:</label>
<div class="layui-input-block">
{foreach $member_level_list as $member_level_list_k => $member_level_list_v}
<input type="checkbox" name="level_id{$member_level_list_v.level_id}" data-id="{$member_level_list_v.level_id}" value="{$member_level_list_v.level_id}" title="{$member_level_list_v.level_name}" lay-skin="primary">
{/foreach}
</div>
</div>
<div class="ns-form-row sm">
<button class="layui-btn ns-bg-color" lay-submit lay-filter="setlevel">确定</button>
<button class="layui-btn layui-btn-primary" onclick="closeLevel()">返回</button>
</div>
</div>
</script>
{/block}

View File

@ -0,0 +1,428 @@
{extend name="base"/}
{block name="resources"}
<link rel="stylesheet" type="text/css" href="SHOP_CSS/member_cluster.css" />
{/block}
{block name="main"}
<div class="layui-collapse ns-tips" >
<div class="layui-colla-item">
<h2 class="layui-colla-title">操作提示</h2>
<ul class="layui-colla-content layui-show">
<li>点击批量处理,可以针对符合条件的会员群体进行批量操作,比如:发放优惠券,调整积分,余额等</li>
</ul>
</div>
</div>
<!-- 添加会员群体 -->
<div class="ns-single-filter-box">
<button type="button" class="layui-btn ns-bg-color" onclick="window.location.href='{:addon_url("member/shop/membercluster/addCluster")}'">添加群体</button>
</div>
<div class="ns-screen layui-collapse" lay-filter="selection_panel">
<div class="layui-colla-item">
<h2 class="layui-colla-title"></h2>
<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">
<input type="text" name="cluster_name" placeholder="群体名称" autocomplete="off" class="layui-input ">
</div>
</div>
<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" placeholder="请输入开始时间" autocomplete="off" readonly>
</div>
<div class="layui-input-inline ns-split">-</div>
<div class="layui-input-inline end-time">
<input type="text" class="layui-input" name="end_date" id="end_date" placeholder="请输入结束时间" autocomplete="off" readonly>
</div>
</div>
</div>
<div class="ns-form-row">
<button class="layui-btn ns-bg-color" lay-submit lay-filter="search">筛选</button>
<button type="reset" class="layui-btn layui-btn-primary">重置</button>
</div>
</form>
</div>
</div>
<!-- 列表 -->
<table id="cluster_list" lay-filter="cluster_list"></table>
<!-- 工具栏操作 -->
<script type="text/html" id="operation">
<div class="ns-table-btn">
<a class="layui-btn" lay-event="member">查看会员</a>
<a class="layui-btn" lay-event="info">编辑</a>
<a class="layui-btn" lay-event="delete">删除</a>
<a class="layui-btn" lay-event="more">批量处理</a>
<div class="more-operation">
<a class="operation" lay-event="recive_coupon">发放优惠券</a>
<a class="operation" lay-event="adjust_balance">调整消费券</a>
<a class="operation" lay-event="adjust_integral">调整积分</a>
<a class="operation" lay-event="export_cluster_member">导出</a>
</div>
</div>
</script>
<!-- 积分弹框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 amount">
<input type="number" value="0" placeholder="请输入调整数额" name="adjust_num" lay-verify="num" class="layui-input ns-len-short">
</div>
<span class="ns-word-aux">调整数额与当前积分数相加不能小于0</span>
</div>
<div class="layui-form-item">
<label class="layui-form-label">备注:</label>
<div class="layui-input-block ns-len-long">
<textarea class="layui-textarea" name="remark" placeholder="请输入备注"></textarea>
</div>
</div>
<div class="ns-form-row">
<button class="layui-btn ns-bg-color" lay-submit lay-filter="savePoint">确定</button>
</div>
<input type="hidden" name="cluster_id" value="{{d.cluster_id}}" />
</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">
<input type="number" value="0" placeholder="请输入调整数额" name="adjust_num" lay-verify="num" class="layui-input ns-len-short">
</div>
<span class="ns-word-aux">调整数额与当前不可提现余额相加不能小于0</span>
</div>
<div class="layui-form-item">
<label class="layui-form-label">备注:</label>
<div class="layui-input-block ns-len-long">
<textarea class="layui-textarea" name="remark" placeholder="请输入备注"></textarea>
</div>
</div>
<div class="ns-form-row">
<button class="layui-btn ns-bg-color" lay-submit lay-filter="saveBalance">确定</button>
</div>
<input type="hidden" name="cluster_id" value="{{d.cluster_id}}" />
</div>
</script>
{/block}
{block name="script"}
<script type='text/javascript' src='SHOP_JS/member_cluster.js'></script>
<script type="text/javascript">
var table, form, laytpl, laydate,
repeat_flag = false,
currentDate = new Date(),
minDate = "";
layui.use(['form', 'laytpl', 'laydate'], function() {
form = layui.form;
laytpl = layui.laytpl;
laydate = layui.laydate;
currentDate.setDate(currentDate.getDate() - 7);
form.render();
//注册开始时间
laydate.render({
elem: '#start_date',
type: 'datetime'
});
//注册结束时间
laydate.render({
elem: '#end_date',
type: 'datetime'
});
/**
* 重新渲染结束时间
* */
function reRender() {
$("#reg_end_date").remove();
$(".end-time").html('<input type="text" class="layui-input" name="reg_end_date" id="reg_end_date" placeholder="请输入结束时间">');
laydate.render({
elem: '#reg_end_date',
min: minDate
});
}
/**
* 加载表格
*/
table = new Table({
elem: '#cluster_list',
url: ns.url("member://shop/membercluster/clusterList"),
cols: [
[
{
field: 'cluster_name',
title: '群体名称',
width: '25%',
unresize: 'false'
}, {
field: 'member_num',
title: '人数',
width: '25%',
unresize: 'false',
templet: function (data) {
return "<a href='"+ns.url("member://shop/member/memberList?cluster_id=" + data.cluster_id)+"'>"+"<span class='ns-text-color'>"+data.member_num+"</span>"+"</a>";
}
}, {
field: 'update_time',
title: '更新时间',
width: '25%',
unresize: 'false',
templet: function (data) {
return ns.time_to_date(data.update_time);
}
}, {
title: '操作',
width: '25%',
unresize: 'false',
toolbar: '#operation'
}
]
],
});
/**
* 监听工具栏操作
*/
table.tool(function(obj) {
var data = obj.data;
switch (obj.event) {
case 'info': //编辑
location.href = ns.url("member://shop/membercluster/editCluster?cluster_id=" + data.cluster_id);
break;
case 'delete': //删除
delCluster(data.cluster_id);
break;
case 'adjust_balance': //调整消费券
adjustBalance(data);
break;
case 'adjust_integral': //调整积分
adjustIntegral(data);
break;
case 'more': //更多
$('.more-operation').css('display', 'none');
$(obj.tr).find('.more-operation').css('display', 'block');
break;
case 'recive_coupon': //发放优惠券
selectCoupon(data);
break;
case 'export_cluster_member': //导出相应会员
exportClusterMember(data.cluster_id);
break;
case 'member': //查看会员
window.open(ns.url("member://shop/member/memberList?cluster_id=" + data.cluster_id));
break;
}
});
$(document).click(function(event) {
if ($(event.target).attr('lay-event') != 'more' && $('.more-operation').not(':hidden').length) {
$('.more-operation').css('display', 'none');
}
});
/**
* 删除
*/
function delCluster(cluster_ids) {
if (repeat_flag) return false;
repeat_flag = true;
layer.confirm('确认删除会员群体?', function() {
$.ajax({
url: ns.url("member://shop/membercluster/deleteCluster"),
data: {cluster_ids},
dataType: 'JSON',
type: 'POST',
success: function(res) {
layer.msg(res.message);
repeat_flag = false;
if (res.code == 0) {
table.reload();
}
}
});
}, function () {
layer.close();
repeat_flag = false;
});
}
// 调整消费券
function adjustBalance(e){
laytpl($("#balance").html()).render(e, function(html) {
layer.open({
title: '调整消费券(不可提现)',
skin: 'layer-tips-class',
type: 1,
area: ['800px'],
content: html
});
});
}
//调整积分
function adjustIntegral(e){
laytpl($("#point").html()).render(e, function(html) {
layer.open({
title: '调整积分',
skin: 'layer-tips-class',
type: 1,
area: ['800px'],
content: html
});
});
}
var repeat_flag_point = false;
form.on('submit(savePoint)', function(data) {
if (repeat_flag_point) return false;
repeat_flag_point = true;
if (data.field.adjust_num == 0) {
layer.msg('调整数值不能为0');
repeat_flag_point = false;
return ;
}
if (data.field.adjust_num < 0) {
layer.msg('积分不可以为负数');
repeat_flag_point = false;
return ;
}
$.ajax({
type: "POST",
url: ns.url("member://shop/membercluster/sendPoint"),
data: data.field,
dataType: 'JSON',
success: function(res) {
layer.msg(res.message);
repeat_flag_point = false;
if (res.code == 0) {
layer.closeAll('page');
table.reload();
}
}
});
});
var repeat_flag_balance = false;
form.on('submit(saveBalance)', function(data) {
if (repeat_flag_balance) return false;
repeat_flag_balance = true;
if (data.field.adjust_num == 0) {
layer.msg('调整数值不能为0');
repeat_flag_balance = false;
return ;
}
if (data.field.adjust_num < 0) {
layer.msg('当前余额(不可提现)不可以为负数');
repeat_flag_balance = false;
return ;
}
$.ajax({
type: "POST",
url: ns.url("member://shop/membercluster/sendBalance"),
data: data.field,
dataType: 'JSON',
success: function(res) {
layer.msg(res.message);
repeat_flag_balance = false;
if (res.code == 0) {
layer.closeAll('page');
table.reload();
}
}
});
});
/**
* 导出群体内会员信息
*/
function exportClusterMember(cluster_id) {
location.href = ns.url("member://shop/membercluster/exportClusterMember",{"cluster_id":cluster_id});
}
/**
* 搜索功能
*/
form.on('submit(search)', function(data) {
table.reload({
page: {
curr: 1
},
where: data.field
});
return false;
});
$(".search-form").click(function() {
$(".layui-form-search").show();
$(this).hide();
});
$(".form-hide-btn").click(function() {
$(".layui-form-search").hide();
$(".search-form").show();
});
/**
* 发放优惠券
*/
function selectCoupon(data) {
laytpl($("#recive_coupon").html()).render(data, function(html) {
layer_coupon = layer.open({
title: '选择优惠券',
skin: 'layer-tips-class',
type: 1,
area: ['700px', '542px'],
content: html,
});
renderCoupon("", data.cluster_id);
});
}
});
</script>
<!-- 发放优惠券弹框 -->
<script type="text/html" id="recive_coupon">
<div class="recive-coupon">
<div class="coupon-modal">
<div class="coupon-list all-coupon">
<div class="title ns-bg-color-gray">可选优惠券</div>
<div class="box"></div>
</div>
<button class="add">添加</button>
<div class="coupon-list selected-coupon">
<div class="title ns-bg-color-gray">已选优惠券</div>
<div class="box"></div>
</div>
</div>
<div class="modal-operation">
<button class="layui-btn ns-bg-color save-btn">确定</button>
<button class="layui-btn layui-btn-primary" onclick="back()">返回</button>
</div>
</div>
</script>
{/block}

View File

@ -0,0 +1,721 @@
{extend name="base"/}
{block name="resources"}
<style>
.ns-form {margin-top: 0;}
.layui-btn+.layui-btn {margin-left: 0;}
.layui-btn {margin-right: 10px; margin-bottom: 15px;}
.weight-list span{display: inline-block;width: 60px;line-height: 30px;border:1px solid #eee;border-radius: 4px;text-align: center;font-size: 12px;cursor: pointer;}
.weight-list span.active{border-color: #ff8143; }
.weight-list span.disabled{background:#f1f1f1;cursor: not-allowed; }
</style>
{/block}
{block name="main"}
<div class="layui-form ns-form">
<!-- 基础上传 -->
<div class="layui-card ns-card-common ns-card-brief">
<div class="layui-card-header">
<span class="ns-card-title">基础设置</span>
</div>
<div class="layui-card-body">
<div class="layui-form-item">
<label class="layui-form-label"><span class="required">*</span>群体名称:</label>
<div class="layui-input-block">
<input type="text" name="cluster_name" lay-verify="required" autocomplete="off" value="{$cluster_info['cluster_name']}" class="layui-input ns-len-mid">
</div>
</div>
</div>
</div>
<div class="layui-card ns-card-common ns-card-brief">
<div class="layui-card-header">
<span class="ns-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">
<button class="layui-btn layui-btn-primary ns-cluster-btn {if $cluster_info['rule_arr']['basic']['member_level']['is_show'] == 1} ns-border-color {/if}">会员等级<input type="hidden" value="0" /></button>
<button class="layui-btn layui-btn-primary ns-cluster-btn {if $cluster_info['rule_arr']['basic']['member_label']['is_show'] == 1} ns-border-color {/if}">会员标签<input type="hidden" value="1" /></button>
<button class="layui-btn layui-btn-primary ns-cluster-btn {if $cluster_info['rule_arr']['basic']['sex']['is_show'] == 1} ns-border-color {/if}">性别<input type="hidden" value="2" /></button>
<button class="layui-btn layui-btn-primary ns-cluster-btn {if $cluster_info['rule_arr']['basic']['birthday']['is_show'] == 1} ns-border-color {/if}">生日<input type="hidden" value="3" /></button>
<button class="layui-btn layui-btn-primary ns-cluster-btn {if $cluster_info['rule_arr']['basic']['reg_time']['is_show'] == 1} ns-border-color {/if}">注册时间<input type="hidden" value="4" /></button>
<button class="layui-btn layui-btn-primary ns-cluster-btn {if $cluster_info['rule_arr']['basic']['point']['is_show'] == 1} ns-border-color {/if}">当前积分<input type="hidden" value="5" /></button>
<button class="layui-btn layui-btn-primary ns-cluster-btn {if $cluster_info['rule_arr']['basic']['balance']['is_show'] == 1} ns-border-color {/if}">当前余额<input type="hidden" value="6" /></button>
<button class="layui-btn layui-btn-primary ns-cluster-btn {if $cluster_info['rule_arr']['basic']['growth']['is_show'] == 1} ns-border-color {/if}">当前成长值<input type="hidden" value="7" /></button>
<button class="layui-btn layui-btn-primary ns-cluster-btn {if $cluster_info['rule_arr']['basic']['sign_days_series']['is_show'] == 1} ns-border-color {/if}">连续签到次数<input type="hidden" value="8" /></button>
<button class="layui-btn layui-btn-primary ns-cluster-btn {if $cluster_info['rule_arr']['basic']['mobile']['is_show'] == 1} ns-border-color {/if}">会员手机<input type="hidden" value="9" /></button>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">会员消费情况</label>
<div class="layui-input-block">
<button class="layui-btn layui-btn-primary ns-cluster-btn {if $cluster_info['rule_arr']['consume']['order_money']['is_show'] == 1} ns-border-color {/if}">付款金额<input type="hidden" value="10" /></button>
<button class="layui-btn layui-btn-primary ns-cluster-btn {if $cluster_info['rule_arr']['consume']['order_complete_money']['is_show'] == 1} ns-border-color {/if}">消费金额<input type="hidden" value="11" /></button>
<button class="layui-btn layui-btn-primary ns-cluster-btn {if $cluster_info['rule_arr']['consume']['order_num']['is_show'] == 1} ns-border-color {/if}">付款次数<input type="hidden" value="12" /></button>
<button class="layui-btn layui-btn-primary ns-cluster-btn {if $cluster_info['rule_arr']['consume']['order_complete_num']['is_show'] == 1} ns-border-color {/if}">消费次数<input type="hidden" value="13" /></button>
</div>
</div>
</div>
</div>
<div class="layui-card ns-card-common ns-card-brief">
<div class="layui-card-header">
<span class="ns-card-title">群体设置</span>
</div>
<div class="layui-card-body">
<div class="layui-form-item">
<div class="layui-input-block">
<table class="layui-table" id="goods" lay-skin="line" lay-size="lg">
<colgroup>
<col width="15%">
<col width="20%">
<col width="50%">
<col width="10%">
</colgroup>
<thead>
<tr>
<th>选项</th>
<th>范围</th>
<th>条件</th>
<th class="operation">操作</th>
</tr>
</thead>
<tbody>
<tr class="ns-cluster-content {if $cluster_info['rule_arr']['basic']['member_level']['is_show'] == 0} layui-hide {/if}">
<td>会员等级</td>
<td>
<input type="radio" class="include" name="basic[member_level][include]" value="1" title="包含" {if condition="$cluster_info['rule_arr']['basic']['member_level']['include'] == 1"} checked {/if}>
<input type="radio" class="include" name="basic[member_level][include]" value="2" title="不包含" {if condition="$cluster_info['rule_arr']['basic']['member_level']['include'] == 2"} checked {/if}>
</td>
<td>
<div class="layui-input-inline">
<input type="text" autocomplete="off" class="layui-input member-level-con" readonly onclick="settinglevel()" value="{$cluster_info['rule_arr']['basic']['member_level']['content_name']}">
<input type="hidden" name="basic[member_level][content]" value="{$cluster_info['rule_arr']['basic']['member_level']['content']}">
</div>
<input type="hidden" class="is-show" name="basic[member_level][is_show]" value="{$cluster_info['rule_arr']['basic']['member_level']['is_show']}">
</td>
<td class='operation'>
<div class='ns-table-btn '><a href='javascript:;' class='layui-btn' onclick='delDiv(this)'>删除</a></div>
</td>
</tr>
<tr class="ns-cluster-content {if $cluster_info['rule_arr']['basic']['member_label']['is_show'] == 0} layui-hide {/if}">
<td>会员标签</td>
<td>
<input type="radio" class="include" name="basic[member_label][include]" value="1" title="包含" {if condition="$cluster_info['rule_arr']['basic']['member_label']['include'] == 1"} checked {/if}>
<input type="radio" class="include" name="basic[member_label][include]" value="2" title="不包含" {if condition="$cluster_info['rule_arr']['basic']['member_label']['include'] == 2"} checked {/if}>
</td>
<td>
<div class="layui-input-inline">
<input type="text" autocomplete="off" class="layui-input member-label-con" readonly onclick="settinglabel()" value="{$cluster_info['rule_arr']['basic']['member_label']['content_name']}">
<input type="hidden" name="basic[member_label][content]" value="{$cluster_info['rule_arr']['basic']['member_label']['content']}">
</div>
<input type="hidden" class="is-show" name="basic[member_label][is_show]" value="{$cluster_info['rule_arr']['basic']['member_label']['is_show']}">
</td>
<td class='operation'>
<div class='ns-table-btn '><a href='javascript:;' class='layui-btn' onclick='delDiv(this)'>删除</a></div>
</td>
</tr>
<tr class="ns-cluster-content {if $cluster_info['rule_arr']['basic']['sex']['is_show'] == 0} layui-hide {/if}">
<td>会员性别</td>
<td>
<input type="radio" class="include" name="basic[sex][include]" value="1" title="包含" {if condition="$cluster_info['rule_arr']['basic']['sex']['include'] == 1"} checked {/if}>
<input type="radio" class="include" name="basic[sex][include]" value="2" title="不包含" {if condition="$cluster_info['rule_arr']['basic']['sex']['include'] == 2"} checked {/if}>
</td>
<td>
<input type="checkbox" class="ns-input-checkbox" lay-skin="primary" lay-filter="sex" name="basic[sex][content]" value="0" title="保密" {if in_array(0, $cluster_info['rule_arr']['basic']['sex']['content_arr'])}checked{/if}>
<input type="checkbox" class="ns-input-checkbox" lay-skin="primary" lay-filter="sex" name="basic[sex][content]" value="1" title="男" {if in_array(1, $cluster_info['rule_arr']['basic']['sex']['content_arr'])}checked{/if}>
<input type="checkbox" class="ns-input-checkbox" lay-skin="primary" lay-filter="sex" name="basic[sex][content]" value="2" title="女" {if in_array(2, $cluster_info['rule_arr']['basic']['sex']['content_arr'])}checked{/if}>
<input type="hidden" class="is-show" name="basic[sex][is_show]" value="{$cluster_info['rule_arr']['basic']['sex']['is_show']}">
</td>
<td class='operation'>
<div class='ns-table-btn '><a href='javascript:;' class='layui-btn' onclick='delDiv(this)'>删除</a></div>
</td>
</tr>
<tr class="ns-cluster-content {if $cluster_info['rule_arr']['basic']['birthday']['is_show'] == 0} layui-hide {/if}">
<td>会员生日</td>
<td>
<input type="radio" class="include" name="basic[birthday][include]" value="1" title="包含" {if condition="$cluster_info['rule_arr']['basic']['birthday']['include'] == 1"} checked {/if}>
<input type="radio" class="include" name="basic[birthday][include]" value="2" title="不包含" {if condition="$cluster_info['rule_arr']['basic']['birthday']['include'] == 2"} checked {/if}>
</td>
<td>
<div class="layui-input-inline">
<input type="text" class="layui-input layui-input-start" name="basic[birthday][start]" id="birthday_start_date" placeholder="请输入开始时间" autocomplete="off" readonly value="{$cluster_info['rule_arr']['basic']['birthday']['start']}">
</div>
<div class="layui-input-inline ns-split">-</div>
<div class="layui-input-inline end-time">
<input type="text" class="layui-input layui-input-end" name="basic[birthday][end]" id="birthday_end_date" placeholder="请输入结束时间" autocomplete="off" readonly value="{$cluster_info['rule_arr']['basic']['birthday']['end']}">
</div>
<input type="hidden" class="is-show" name="basic[birthday][is_show]" value="{$cluster_info['rule_arr']['basic']['birthday']['is_show']}">
</td>
<td class='operation'>
<div class='ns-table-btn '><a href='javascript:;' class='layui-btn' onclick='delDiv(this)'>删除</a></div>
</td>
</tr>
<tr class="ns-cluster-content {if $cluster_info['rule_arr']['basic']['reg_time']['is_show'] == 0} layui-hide {/if}">
<td>注册时间</td>
<td>
<input type="radio" class="include" name="basic[reg_time][include]" value="1" title="包含" {if condition="$cluster_info['rule_arr']['basic']['reg_time']['include'] == 1"} checked {/if}>
<input type="radio" class="include" name="basic[reg_time][include]" value="2" title="不包含" {if condition="$cluster_info['rule_arr']['basic']['reg_time']['include'] == 2"} checked {/if}>
</td>
<td>
<div class="layui-input-inline">
<input type="text" class="layui-input layui-input-start" name="basic[reg_time][start]" id="reg_start_date" placeholder="请输入开始时间" autocomplete="off" readonly value="{$cluster_info['rule_arr']['basic']['reg_time']['start']}">
</div>
<div class="layui-input-inline ns-split">-</div>
<div class="layui-input-inline end-time">
<input type="text" class="layui-input layui-input-end" name="basic[reg_time][end]" id="reg_end_date" placeholder="请输入结束时间" autocomplete="off" readonly value="{$cluster_info['rule_arr']['basic']['reg_time']['end']}">
</div>
<input type="hidden" class="is-show" name="basic[reg_time][is_show]" value="{$cluster_info['rule_arr']['basic']['reg_time']['is_show']}">
</td>
<td class='operation'>
<div class='ns-table-btn '><a href='javascript:;' class='layui-btn' onclick='delDiv(this)'>删除</a></div>
</td>
</tr>
<tr class="ns-cluster-content {if $cluster_info['rule_arr']['basic']['point']['is_show'] == 0} layui-hide {/if}">
<td>当前积分</td>
<td>
<input type="radio" class="include" name="basic[point][include]" value="1" title="包含" {if condition="$cluster_info['rule_arr']['basic']['point']['include'] == 1"} checked {/if}>
<input type="radio" class="include" name="basic[point][include]" value="2" title="不包含" {if condition="$cluster_info['rule_arr']['basic']['point']['include'] == 2"} checked {/if}>
</td>
<td>
<div class="layui-input-inline">
<input type="number" class="layui-input layui-input-start layui-input-int" name="basic[point][start]" placeholder="请输入积分最小值" autocomplete="off" min="0" value="{$cluster_info['rule_arr']['basic']['point']['start']}">
</div>
<div class="layui-input-inline ns-split">-</div>
<div class="layui-input-inline end-time">
<input type="number" class="layui-input layui-input-end layui-input-int" name="basic[point][end]" placeholder="请输入积分最大值" autocomplete="off" min="0" value="{$cluster_info['rule_arr']['basic']['point']['end']}">
</div>
<input type="hidden" class="is-show" name="basic[point][is_show]" value="{$cluster_info['rule_arr']['basic']['point']['is_show']}">
</td>
<td class='operation'>
<div class='ns-table-btn '><a href='javascript:;' class='layui-btn' onclick='delDiv(this)'>删除</a></div>
</td>
</tr>
<tr class="ns-cluster-content {if $cluster_info['rule_arr']['basic']['balance']['is_show'] == 0} layui-hide {/if}">
<td>当前余额</td>
<td>
<input type="radio" class="include" name="basic[balance][include]" value="1" title="包含" {if condition="$cluster_info['rule_arr']['basic']['balance']['include'] == 1"} checked {/if}>
<input type="radio" class="include" name="basic[balance][include]" value="2" title="不包含" {if condition="$cluster_info['rule_arr']['basic']['balance']['include'] == 2"} checked {/if}>
</td>
<td>
<div class="layui-input-inline">
<input type="number" class="layui-input layui-input-start layui-input-flo" name="basic[balance][start]" placeholder="请输入当前余额最小值" autocomplete="off" min="0" value="{$cluster_info['rule_arr']['basic']['balance']['start']}">
</div>
<div class="layui-input-inline ns-split">-</div>
<div class="layui-input-inline end-time">
<input type="number" class="layui-input layui-input-end layui-input-flo" name="basic[balance][end]" placeholder="请输入当前余额最大值" autocomplete="off" min="0" value="{$cluster_info['rule_arr']['basic']['balance']['end']}">
</div>
<input type="hidden" class="is-show" name="basic[balance][is_show]" value="{$cluster_info['rule_arr']['basic']['balance']['is_show']}">
</td>
<td class='operation'>
<div class='ns-table-btn '><a href='javascript:;' class='layui-btn' onclick='delDiv(this)'>删除</a></div>
</td>
</tr>
<tr class="ns-cluster-content {if $cluster_info['rule_arr']['basic']['growth']['is_show'] == 0} layui-hide {/if}">
<td>当前成长值</td>
<td>
<input type="radio" class="include" name="basic[growth][include]" value="1" title="包含" {if condition="$cluster_info['rule_arr']['basic']['growth']['include'] == 1"} checked {/if}>
<input type="radio" class="include" name="basic[growth][include]" value="2" title="不包含" {if condition="$cluster_info['rule_arr']['basic']['growth']['include'] == 2"} checked {/if}>
</td>
<td>
<div class="layui-input-inline">
<input type="number" class="layui-input layui-input-start layui-input-flo" name="basic[growth][start]" placeholder="请输入当前成长值最小值" autocomplete="off" min="0" value="{$cluster_info['rule_arr']['basic']['growth']['start']}">
</div>
<div class="layui-input-inline ns-split">-</div>
<div class="layui-input-inline end-time">
<input type="number" class="layui-input layui-input-end layui-input-flo" name="basic[growth][end]" placeholder="请输入当前成长值最大值" autocomplete="off" min="0" value="{$cluster_info['rule_arr']['basic']['growth']['end']}">
</div>
<input type="hidden" class="is-show" name="basic[growth][is_show]" value="{$cluster_info['rule_arr']['basic']['growth']['is_show']}">
</td>
<td class='operation'>
<div class='ns-table-btn '><a href='javascript:;' class='layui-btn' onclick='delDiv(this)'>删除</a></div>
</td>
</tr>
<tr class="ns-cluster-content {if $cluster_info['rule_arr']['basic']['sign_days_series']['is_show'] == 0} layui-hide {/if}">
<td>签到次数</td>
<td>
<input type="radio" class="include" name="basic[sign_days_series][include]" value="1" title="包含" {if condition="$cluster_info['rule_arr']['basic']['sign_days_series']['include'] == 1"} checked {/if}>
<input type="radio" class="include" name="basic[sign_days_series][include]" value="2" title="不包含" {if condition="$cluster_info['rule_arr']['basic']['sign_days_series']['include'] == 2"} checked {/if}>
</td>
<td>
<div class="layui-input-inline">
<input type="number" class="layui-input layui-input-start layui-input-int" name="basic[sign_days_series][start]" placeholder="请输入签到次数最小值" autocomplete="off" min="0" value="{$cluster_info['rule_arr']['basic']['sign_days_series']['start']}">
</div>
<div class="layui-input-inline ns-split">-</div>
<div class="layui-input-inline end-time">
<input type="number" class="layui-input layui-input-end layui-input-int" name="basic[sign_days_series][end]" placeholder="请输入签到次数最大值" autocomplete="off" min="0" value="{$cluster_info['rule_arr']['basic']['sign_days_series']['end']}">
</div>
<input type="hidden" class="is-show" name="basic[sign_days_series][is_show]" value="{$cluster_info['rule_arr']['basic']['sign_days_series']['is_show']}">
</td>
<td class='operation'>
<div class='ns-table-btn '><a href='javascript:;' class='layui-btn' onclick='delDiv(this)'>删除</a></div>
</td>
</tr>
<tr class="ns-cluster-content {if $cluster_info['rule_arr']['basic']['mobile']['is_show'] == 0} layui-hide {/if}">
<td>会员手机</td>
<td>
<input type="radio" class="include" name="basic[mobile][include]" value="1" title="包含" {if condition="$cluster_info['rule_arr']['basic']['mobile']['include'] == 1"} checked {/if}>
<input type="radio" class="include" name="basic[mobile][include]" value="2" title="不包含" {if condition="$cluster_info['rule_arr']['basic']['mobile']['include'] == 2"} checked {/if}>
</td>
<td>
<div class="layui-input-inline">
<input type="text" name="basic[mobile][content]" lay-verify="flo" autocomplete="off" class="layui-input member-mobile" value="{$cluster_info['rule_arr']['basic']['mobile']['content']}">
</div>
<input type="hidden" class="is-show" name="basic[mobile][is_show]" value="{$cluster_info['rule_arr']['basic']['mobile']['is_show']}">
</td>
<td class='operation'>
<div class='ns-table-btn '><a href='javascript:;' class='layui-btn' onclick='delDiv(this)'>删除</a></div>
</td>
</tr>
<tr class="ns-cluster-content {if $cluster_info['rule_arr']['consume']['order_money']['is_show'] == 0} layui-hide {/if}">
<td>付款金额</td>
<td>
<input type="radio" class="include" name="consume[order_money][include]" value="1" title="包含" {if condition="$cluster_info['rule_arr']['consume']['order_money']['include'] == 1"} checked {/if}>
<input type="radio" class="include" name="consume[order_money][include]" value="2" title="不包含" {if condition="$cluster_info['rule_arr']['consume']['order_money']['include'] == 2"} checked {/if}>
</td>
<td>
<div class="layui-input-inline">
<input type="number" class="layui-input layui-input-start layui-input-flo" name="consume[order_money][start]" placeholder="请输入付款金额最小值" autocomplete="off" min="0" value="{$cluster_info['rule_arr']['consume']['order_money']['start']}">
</div>
<div class="layui-input-inline ns-split">-</div>
<div class="layui-input-inline end-time">
<input type="number" class="layui-input layui-input-end layui-input-flo" name="consume[order_money][end]" placeholder="请输入付款金额最大值" autocomplete="off" min="0" value="{$cluster_info['rule_arr']['consume']['order_money']['end']}">
</div>
<input type="hidden" class="is-show" name="consume[order_money][is_show]" value="{$cluster_info['rule_arr']['consume']['order_money']['is_show']}">
</td>
<td class='operation'>
<div class='ns-table-btn '><a href='javascript:;' class='layui-btn' onclick='delDiv(this)'>删除</a></div>
</td>
</tr>
<tr class="ns-cluster-content {if $cluster_info['rule_arr']['consume']['order_complete_money']['is_show'] == 0} layui-hide {/if}">
<td>消费金额</td>
<td>
<input type="radio" class="include" name="consume[order_complete_money][include]" value="1" title="包含" {if condition="$cluster_info['rule_arr']['consume']['order_complete_money']['include'] == 1"} checked {/if}>
<input type="radio" class="include" name="consume[order_complete_money][include]" value="2" title="不包含" {if condition="$cluster_info['rule_arr']['consume']['order_complete_money']['include'] == 2"} checked {/if}>
</td>
<td>
<div class="layui-input-inline">
<input type="number" class="layui-input layui-input-start layui-input-flo" name="consume[order_complete_money][start]" placeholder="请输入消费金额最小值" autocomplete="off" min="0" value="{$cluster_info['rule_arr']['consume']['order_complete_money']['start']}">
</div>
<div class="layui-input-inline ns-split">-</div>
<div class="layui-input-inline end-time">
<input type="number" class="layui-input layui-input-end layui-input-flo" name="consume[order_complete_money][end]" placeholder="请输入消费金额最大值" autocomplete="off" min="0" value="{$cluster_info['rule_arr']['consume']['order_complete_money']['end']}">
</div>
<input type="hidden" class="is-show" name="consume[order_complete_money][is_show]" value="{$cluster_info['rule_arr']['consume']['order_complete_money']['is_show']}">
</td>
<td class='operation'>
<div class='ns-table-btn '><a href='javascript:;' class='layui-btn' onclick='delDiv(this)'>删除</a></div>
</td>
</tr>
<tr class="ns-cluster-content {if $cluster_info['rule_arr']['consume']['order_num']['is_show'] == 0} layui-hide {/if}">
<td>付款次数</td>
<td>
<input type="radio" class="include" name="consume[order_num][include]" value="1" title="包含" {if condition="$cluster_info['rule_arr']['consume']['order_num']['include'] == 1"} checked {/if}>
<input type="radio" class="include" name="consume[order_num][include]" value="2" title="不包含" {if condition="$cluster_info['rule_arr']['consume']['order_num']['include'] == 2"} checked {/if}>
</td>
<td>
<div class="layui-input-inline">
<input type="number" class="layui-input layui-input-start layui-input-int" name="consume[order_num][start]" placeholder="请输入付款次数最小值" autocomplete="off" min="0" value="{$cluster_info['rule_arr']['consume']['order_num']['start']}">
</div>
<div class="layui-input-inline ns-split">-</div>
<div class="layui-input-inline end-time">
<input type="number" class="layui-input layui-input-end layui-input-int" name="consume[order_num][end]" placeholder="请输入付款次数最大值" autocomplete="off" min="0" value="{$cluster_info['rule_arr']['consume']['order_num']['end']}">
</div>
<input type="hidden" class="is-show" name="consume[order_num][is_show]" value="{$cluster_info['rule_arr']['consume']['order_num']['is_show']}">
</td>
<td class='operation'>
<div class='ns-table-btn '><a href='javascript:;' class='layui-btn' onclick='delDiv(this)'>删除</a></div>
</td>
</tr>
<tr class="ns-cluster-content {if $cluster_info['rule_arr']['consume']['order_complete_num']['is_show'] == 0} layui-hide {/if}">
<td>消费次数</td>
<td>
<input type="radio" class="include" name="consume[order_complete_num][include]" value="1" title="包含" {if condition="$cluster_info['rule_arr']['consume']['order_complete_num']['include'] == 1"} checked {/if}>
<input type="radio" class="include" name="consume[order_complete_num][include]" value="2" title="不包含" {if condition="$cluster_info['rule_arr']['consume']['order_complete_num']['include'] == 2"} checked {/if}>
</td>
<td>
<div class="layui-input-inline">
<input type="number" class="layui-input layui-input-start layui-input-int" name="consume[order_complete_num][start]" placeholder="请输入消费次数最小值" autocomplete="off" min="0" value="{$cluster_info['rule_arr']['consume']['order_complete_num']['start']}">
</div>
<div class="layui-input-inline ns-split">-</div>
<div class="layui-input-inline end-time">
<input type="number" class="layui-input layui-input-end layui-input-int" name="consume[order_complete_num][end]" placeholder="请输入消费次数最大值" autocomplete="off" min="0" value="{$cluster_info['rule_arr']['consume']['order_complete_num']['end']}">
</div>
<input type="hidden" class="is-show" name="consume[order_complete_num][is_show]" value="{$cluster_info['rule_arr']['consume']['order_complete_num']['is_show']}">
</td>
<td class='operation'>
<div class='ns-table-btn '><a href='javascript:;' class='layui-btn' onclick='delDiv(this)'>删除</a></div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="ns-form-row">
<button class="layui-btn ns-bg-color" lay-submit lay-filter="calculate">计算会员数</button>
<div>符合条件的群体人数: <span class="member_num ns-text-color">{$cluster_info['member_num']}</span> 人,点击计算按钮可查看符合条件的群体人数。</div>
</div>
</div>
<div class="layui-card-body">
<div class="ns-form-row">
<!-- 获取cluster_id -->
<input type="hidden" name="cluster_id" id="cluster_id" lay-verify="required" value="{$cluster_info.cluster_id}" class="layui-input">
<button class="layui-btn ns-bg-color" lay-submit lay-filter="save">保存</button>
<button class="layui-btn layui-btn-primary" onclick="back()">返回</button>
</div>
</div>
</div>
</div>
{/block}
{block name="script"}
<script>
$(function(){
$('.weight-list span').not('.disabled').eq(0).addClass("active");
$(".ns-cluster-content").each(function() {
if ($(this).hasClass("layui-hide")) {
$(this).find("input").removeAttr("lay-verify");
} else {
$(this).find(".layui-input-inline input.layui-input").attr("lay-verify", "notnull");
$(this).find(".layui-input-inline input.layui-input-start").attr("lay-verify", "notnull|start");
$(this).find(".layui-input-inline input.layui-input-end").attr("lay-verify", "notnull|end");
$(this).find(".layui-input-inline input[type='number']").attr("lay-verify", "notnull|end|num");
$(this).find(".layui-input-inline input.member-mobile").attr("lay-verify", "notnull|len");
$(this).find(".layui-input-inline input.layui-input-int").attr("lay-verify", "notnull|end|num|int");
$(this).find(".layui-input-inline input.layui-input-flo").attr("lay-verify", "notnull|end|num|flo");
}
});
})
var form, laytpl, laydate, isClick = false, member_num = 0, member_ids = '', sexVal = [];
layui.use(['form', 'laytpl', 'laydate'], function() {
form = layui.form;
laytpl = layui.laytpl;
laydate = layui.laydate;
var repeat_flag = false; //防重复标识
form.render();
//生日开始时间
laydate.render({
elem: '#birthday_start_date',
type: 'datetime'
});
//生日结束时间
laydate.render({
elem: '#birthday_end_date',
type: 'datetime'
});
//注册开始时间
laydate.render({
elem: '#reg_start_date',
type: 'datetime'
});
//注册结束时间
laydate.render({
elem: '#reg_end_date',
type: 'datetime'
});
$(".weight-list span").click(function() {
if (!$(this).hasClass("disabled")) {
$(this).addClass("active");
$(this).siblings().removeClass("active");
}
});
$(".ns-cluster-btn").click(function() {
var _index = $(this).children().val();
if (!$(this).hasClass("ns-border-color")) {
$(this).addClass("ns-border-color");
$(".ns-cluster-content").eq(_index).removeClass("layui-hide");
$(".ns-cluster-content").eq(_index).find(".is-show").val(1);
$(".ns-cluster-content").eq(_index).find(".layui-input-inline input.layui-input").attr("lay-verify", "notnull");
$(".ns-cluster-content").eq(_index).find(".layui-input-inline input.layui-input-start").attr("lay-verify", "notnull|start");
$(".ns-cluster-content").eq(_index).find(".layui-input-inline input.layui-input-end").attr("lay-verify", "notnull|end");
$(".ns-cluster-content").eq(_index).find(".layui-input-inline input[type='number']").attr("lay-verify", "notnull|end|num");
$(".ns-cluster-content").eq(_index).find(".layui-input-inline input.member-mobile").attr("lay-verify", "notnull|len");
$(".ns-cluster-content").eq(_index).find(".layui-input-inline input.layui-input-int.layui-input-start").attr("lay-verify", "notnull|start|num|int");
$(".ns-cluster-content").eq(_index).find(".layui-input-inline input.layui-input-flo.layui-input-end").attr("lay-verify", "notnull|end|num|flo");
}
//点击了需要重新计算
// isClick = false;
form.render();
});
form.on('submit(calculate)', function(data) {
// isClick = true;
var rule_json = resetData(data.field);
if (rule_json.basic.sex.is_show == 1) {
var flag = false;
$(".ns-input-checkbox").each(function() {
var isChecked = $(this).is(":checked");
if (isChecked) {
flag = true;
}
});
if (!flag) {
layer.msg("请选择性别", {icon: 5, anim: 6});
return false;
}
}
$.ajax({
url: ns.url("member://shop/membercluster/calculate"),
type: "POST",
dataType: "JSON",
data: {
rule_json: JSON.stringify(rule_json)
},
success: function(res) {
if (res.code >= 0) {
member_num = res.data.member_num;
member_ids = res.data.member_ids;
$(".member_num").html(member_num);
}
}
})
});
form.on('submit(save)', function(data) {
// if (isClick) {
var rule_json = resetData(data.field);
$.ajax({
url: ns.url("member://shop/membercluster/editCluster"),
type: "POST",
dataType: "JSON",
data: {
cluster_name: data.field.cluster_name,
rule_json: JSON.stringify(rule_json),
cluster_id: $("#cluster_id").val()
},
success: function(res) {
layer.msg(res.message);
if (res.code >= 0) {
location.href = ns.url("member://shop/membercluster/clusterList")
}
}
})
// } else {
// layer.msg("请先计算会员数", {icon: 5, anim: 6});
// }
});
form.on('submit(setlabel)', function(obj) {
var field = obj.field;
var arr_id = [], temp = [];
for (var prop in field) {
arr_id.push(field[prop]);
$("#set_label").find("input").each(function() {
var label_id = $(this).attr("data-id");
if (field[prop] == label_id) {
temp.push($(this).attr("title"))
}
})
}
$(".member-label-con").val(temp);
$("input[name='basic[member_label][content]']").val(arr_id);
layer.closeAll('page');
});
form.on('submit(setlevel)', function(obj) {
var field = obj.field;
var arr_id = [], temp = [];
for (var prop in field) {
arr_id.push(field[prop]);
$("#set_level").find("input").each(function() {
var level_id = $(this).attr("data-id");
if (field[prop] == level_id) {
temp.push($(this).attr("title"))
}
})
}
$(".member-level-con").val(temp);
$("input[name='basic[member_level][content]']").val(arr_id);
layer.closeAll('page');
});
/**
* 表单验证
*/
form.verify({
notnull: function(value, item) {
var str = $(item).parents(".ns-cluster-content").find("td").eq(0).text();
if (value == '') {
return str + '不能为空';
}
},
end: function(value, item) {
var start = $(item).parents(".ns-cluster-content").find(".layui-input-start").val();
var str1 = $(item).attr("placeholder").slice(3);
var str2 = $(item).parents(".ns-cluster-content").find(".layui-input-start").attr("placeholder").slice(3);
if (Number(value) < Number(start)) {
return str1 + "不能小于" + str2;
}
},
num: function(value, item) {
var str = $(item).parents(".ns-cluster-content").find("td").eq(0).text();
if (value < 0) {
return str + "不能小于0";
}
},
len: function(value, item) {
if (value.length > 11) {
return "手机号为11位";
}
},
int: function(value, item) {
var str = $(item).parents(".ns-cluster-content").find("td").eq(0).text();
if (value % 1 != 0) {
return str + "不能为小数";
}
},
flo: function(value, item) {
var str = $(item).parents(".ns-cluster-content").find("td").eq(0).text();
if (value * 100 % 1 != 0) {
return str + "最多保留两位小数";
}
}
})
});
/**
* 设置标签
*/
function settinglabel() {
laytpl($("#label_change").html()).render({}, function(html) {
layer_label = layer.open({
title: '设置标签',
skin: 'layer-tips-class',
type: 1,
area: ['450px','260px'],
content: html,
});
});
form.render();
}
/**
* 设置等级
*/
function settinglevel() {
laytpl($("#level_change").html()).render({}, function(html) {
layer_level = layer.open({
title: '设置等级',
skin: 'layer-tips-class',
type: 1,
area: ['450px','260px'],
content: html,
});
});
form.render();
}
function delDiv(e) {
var _len = $(e).parents(".ns-cluster-content").index();
$(e).parents(".ns-cluster-content").addClass("layui-hide");
$(e).parents(".ns-cluster-content").find("input").removeAttr("lay-verify");
$(e).parents(".ns-cluster-content").find(".layui-input-inline input").val("");
$(e).parents(".ns-cluster-content").find(".is-show").val(0);
$(e).parents(".ns-cluster-content").find("input[name='basic[sex][content]']").prop("checked",false);
$(".ns-cluster-btn").eq(_len).removeClass("ns-border-color");
}
function closeLabel() {
layer.close(layer_label);
}
function closeLevel() {
layer.close(layer_level);
}
function back() {
location.href = ns.url("member://shop/membercluster/clusterList");
}
// 数据结构
function resetData(data) {
var rule_json = {};
$.each(data, function(index, item) {
if (index.indexOf("[") != -1) {
var arr = index.split("[");
if (rule_json[arr[0]] == undefined) {
rule_json[arr[0]] = {};
}
var name = arr[1].slice(0, arr[1].length - 1);
if (rule_json[arr[0]][name] == undefined) {
rule_json[arr[0]][name] = {};
}
var attr = arr[2].slice(0, arr[2].length - 1);
rule_json[arr[0]][name][attr] = item;
}
})
sexVal = [];
$("input[name='basic[sex][content]']:checked").each(function (index, item) {
sexVal.push($(this).val());
});
rule_json.basic.sex.content = sexVal.toString();
return rule_json;
}
</script>
<!-- 设置标签弹框html -->
<script type="text/html" id="label_change">
<div class="layui-form member-form" id="set_label" lay-filter="form">
<div class="layui-form-item">
<label class="layui-form-label sm">标签:</label>
<div class="layui-input-block">
{foreach $member_label_list as $member_label_list_k => $member_label_list_v}
<input type="checkbox" name="label_id{$member_label_list_v.label_id}" data-id="{$member_label_list_v.label_id}" value="{$member_label_list_v.label_id}" title="{$member_label_list_v.label_name}" lay-skin="primary">
{/foreach}
</div>
</div>
<div class="ns-form-row sm">
<button class="layui-btn ns-bg-color" lay-submit lay-filter="setlabel">确定</button>
<button class="layui-btn layui-btn-primary" onclick="closeLabel()">返回</button>
</div>
</div>
</script>
<!-- 设置标签弹框html -->
<script type="text/html" id="level_change">
<div class="layui-form member-form" id="set_level" lay-filter="form">
<div class="layui-form-item">
<label class="layui-form-label sm">等级:</label>
<div class="layui-input-block">
{foreach $member_level_list as $member_level_list_k => $member_level_list_v}
<input type="checkbox" name="level_id{$member_level_list_v.level_id}" data-id="{$member_level_list_v.level_id}" value="{$member_level_list_v.level_id}" title="{$member_level_list_v.level_name}" lay-skin="primary">
{/foreach}
</div>
</div>
<div class="ns-form-row sm">
<button class="layui-btn ns-bg-color" lay-submit lay-filter="setlevel">确定</button>
<button class="layui-btn layui-btn-primary" onclick="closeLevel()">返回</button>
</div>
</div>
</script>
{/block}

View File

@ -0,0 +1,91 @@
{extend name="base"/}
{block name="resources"}
<style>
.ns-form {margin-top: 0;}
</style>
{/block}
{block name="main"}
<div class="layui-form ns-form">
<div class="layui-form-item">
<label class="layui-form-label"><span class="required">*</span>标签名称:</label>
<div class="layui-input-block">
<input type="text" name="label_name" lay-verify="required" class="layui-input ns-len-long">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">排序:</label>
<div class="layui-input-block">
<input type="number" name="sort" value="0" lay-verify="num" class="layui-input ns-len-short">
</div>
<div class="ns-word-aux">排序值必须为整数</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">备注:</label>
<div class="layui-input-block">
<textarea name="remark" autocomplete="off" class="layui-textarea ns-len-long"></textarea>
</div>
</div>
<div class="ns-form-row">
<button type="button" class="layui-btn ns-bg-color" lay-submit lay-filter="save">保存</button>
<button class="layui-btn layui-btn-primary" onclick="window.location.href='{:addon_url(\"member/shop/memberlabel/labelList\")}'">返回</button>
</div>
</div>
{/block}
{block name="script"}
<script>
layui.use('form', function() {
var form = layui.form,
repeat_flag = false; //防重复
form.render();
form.on('submit(save)', function(data) {
if(repeat_flag) return;
repeat_flag = true;
$.ajax({
url: ns.url("member://shop/memberlabel/addLabel"),
data: data.field,
dataType: 'JSON',
type: 'POST',
success: function(res) {
repeat_flag = false;
if (res.code == 0) {
layer.confirm('添加成功', {
title:'操作提示',
btn: ['返回列表', '继续添加'],
closeBtn: 0,
yes: function(){
location.href = ns.url("member://shop/memberlabel/labelList")
},
btn2: function() {
location.href = ns.url("member://shop/memberlabel/addLabel")
}
});
}else{
layer.msg(res.message);
}
}
});
});
form.verify({
num: function (value) {
if (value == '') {
return;
}
if (value%1 != 0) {
return '排序数值必须为整数';
}
if (value < 0) {
return '排序数值必须为大于0';
}
}
});
});
</script>
{/block}

View File

@ -0,0 +1,94 @@
{extend name="base"/}
{block name="resources"}
<style>
.ns-form {margin-top: 0;}
</style>
{/block}
{block name="main"}
<div class="layui-form ns-form">
<div class="layui-form-item">
<label class="layui-form-label"><span class="required">*</span>标签名称:</label>
<div class="layui-input-block">
<input type="text" name="label_name" lay-verify="required" value="{$label_info.data.label_name}" class="layui-input ns-len-long">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">排序:</label>
<div class="layui-input-block">
<input type="number" name="sort" class="layui-input ns-len-short" value="{$label_info.data.sort}" lay-verify="num" >
</div>
<div class="ns-word-aux">排序值必须为整数</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">备注:</label>
<div class="layui-input-block">
<textarea name="remark" autocomplete="off" placeholder="" class="layui-textarea ns-len-long">{$label_info.data.remark}</textarea>
</div>
</div>
<!-- 表单操作 -->
<div class="ns-form-row">
<button type="button" class="layui-btn ns-bg-color" lay-submit lay-filter="save">保存</button>
<button class="layui-btn layui-btn-primary" onclick="window.location.href='{:addon_url(\"member/shop/memberlabel/labelList\")}'">返回</button>
</div>
<!-- 获取label_id -->
<input type="hidden" name="label_id" lay-verify="required" value="{$label_info.data.label_id}" class="layui-input">
</div>
{/block}
{block name="script"}
<script>
layui.use('form', function(){
var form = layui.form;
var repeat_flag = false; //防重复
form.render();
form.on('submit(save)', function(data){
if(repeat_flag) return;
repeat_flag = true;
$.ajax({
url:ns.url("member://shop/memberlabel/editLabel"),
data: data.field,
dataType:'JSON',
type:'POST',
success:function(res){
repeat_flag = false;
if (res.code == 0) {
layer.confirm('编辑成功', {
title:'操作提示',
btn: ['返回列表', '继续操作'],
yes: function(){
location.href = ns.url("member://shop/memberlabel/labelList")
},
btn2: function() {
location.reload();
}
});
}else{
layer.msg(res.message);
}
}
});
});
form.verify({
num: function (value) {
if (value == '') {
return;
}
if (value%1 != 0) {
return '排序数值必须为整数';
}
if (value < 0) {
return '排序数值必须为大于0';
}
}
});
});
</script>
{/block}

View File

@ -0,0 +1,240 @@
{extend name="base"/}
{block name="resources"}
{/block}
{block name="main"}
<div class="layui-collapse ns-tips">
<div class="layui-colla-item">
<h2 class="layui-colla-title">操作提示</h2>
<ul class="layui-colla-content layui-show">
<li>会员标签是商城为了更加有效的对会员进行管理和分组。</li>
<li>用户可以针对会员设置相应的标签,方便查找和管理。</li>
</ul>
</div>
</div>
<!-- 搜索框 -->
<div class="ns-single-filter-box">
<button class="layui-btn ns-bg-color" onclick="window.location.href='{:url("member/shop/memberlabel/addLabel")}'">添加标签</button>
<div class="layui-form">
<div class="layui-input-inline">
<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="search" lay-submit>
<i class="layui-icon">&#xe615;</i>
</button>
</div>
</div>
</div>
<!-- 会员标签列表 -->
<table id="label_info" lay-filter="label_info" ></table>
<script type="text/html" id="label_id">
{{# layui.each(res.data, function(index, item){ }}
<input type="checkbox" name="label_id" value="{{item.label_id}}" />
{{# }); }}
</script>
<script type="text/html" id="operation">
<div class="ns-table-btn">
<a class="layui-btn" lay-event="edit">编辑</a>
<a class="layui-btn" lay-event="delete">删除</a>
</div>
</script>
<!-- 顶部工具栏 -->
<script type="text/html" id="toolbarOperation">
<button class="layui-btn layui-btn-primary" lay-event="del">批量删除</button>
</script>
<!-- 批量删除 -->
<script type="text/html" id="batchOperation">
<button class="layui-btn layui-btn-primary" lay-event="del">批量删除</button>
</script>
<!-- 编辑排序 -->
<script type="text/html" id="editSort">
<input name="sort" type="number" onchange="editSort({{d.label_id}}, this)" value="{{d.sort}}" class="layui-input edit-sort ns-len-short">
</script>
{/block}
{block name="script"}
<script>
var form, table;
layui.use(['form'], function() {
form = layui.form;
var repeat_flag = false;
/**
* 加载表格
*/
table = new Table({
elem: '#label_info',
url: ns.url("member://shop/memberlabel/labelList"),
cols: [
[
{
width: "3%",
type: 'checkbox',
templet: '#label_id',
unresize:'false'
}, {
field: 'label_name',
title: '标签名称',
width: '17%',
unresize:'false'
}, {
unresize:'false',
field: 'remark',
title: '备注',
width: '22%',
}, {
unresize:'false',
field: 'modify_time',
title: '创建时间',
width: '18%',
templet: function (data) {
return ns.time_to_date(data.create_time); //创建时间转换方法
}
}, {
unresize:'false',
title: '排序',
width: '20%',
align: 'center',
templet: '#editSort'
}, {
unresize:'false',
title: '操作',
width: '15%',
toolbar: '#operation'
}
]
],
toolbar: '#toolbarOperation',
bottomToolbar: "#batchOperation"
});
/**
* 监听工具栏操作
*/
table.tool(function(obj) {
var data = obj.data;
switch (obj.event) {
case 'edit': //编辑
location.href = ns.url("member://shop/memberlabel/editLabel?label_id="+data.label_id)
break;
case 'delete': //删除
deleteLabel(data.label_id);
break;
}
});
/**
* 删除
*/
function deleteLabel(label_ids) {
if (repeat_flag) return false;
repeat_flag = true;
layer.confirm('确定要删除该标签吗?', function() {
$.ajax({
url: ns.url("member://shop/memberlabel/deleteLabel"),
data: {label_ids},
dataType: 'JSON',
type: 'POST',
success: function(res) {
layer.msg(res.message);
repeat_flag = false;
if (res.code == 0) {
table.reload();
}
}
});
}, function () {
layer.close();
repeat_flag = false;
});
}
/**
* 批量操作
*/
table.bottomToolbar(function(obj) {
if (obj.data.length < 1) {
layer.msg('请选择要操作的数据');
return;
}
switch (obj.event) {
case "del":
var id_array = new Array();
for (i in obj.data) id_array.push(obj.data[i].label_id);
deleteLabel(id_array.toString());
break;
}
});
//监听事件
table.toolbar(function(obj){
if (obj.data.length < 1) {
layer.msg('请选择要操作的数据');
return;
}
var checkStatus = table.checkStatus(obj.config.id);
switch (obj.event) {
case 'del':
var id_array = new Array();
for (i in obj.data) id_array.push(obj.data[i].label_id);
deleteLabel(id_array.toString());
break;
};
});
// 搜索
form.on('submit(search)', function(data){
table.reload({
page: {
curr: 1
},
where: data.field
});
});
});
// 监听单元格编辑
function editSort(id, event){
var data = $(event).val();
if (data == '') {
$(event).val(0);
data = 0;
}
if(!new RegExp("^-?[0-9]\\d*$").test(data)){
layer.msg("排序号只能是整数");
return ;
}
if(data<0){
layer.msg("排序号必须大于0");
return ;
}
$.ajax({
type: 'POST',
url: ns.url("member://shop/memberlabel/modifySort"),
data: {
sort: data,
label_id: id
},
dataType: 'JSON',
success: function(res) {
layer.msg(res.message);
if(res.code==0){
table.reload();
}
}
});
}
</script>
{/block}

View File

@ -0,0 +1,622 @@
{extend name="base"/}
{block name="resources"}
<style>
.ns-form {margin-top: 0;}
.coupon-box{
padding: 20px;
}
.coupon-box .layui-form{
padding: 0!important;
}
.layui-layer-page .layui-layer-content{
overflow: auto !important;
}
.ns-del-btn {
cursor: pointer;
}
.ns-level-equity .layui-input {
display: inline-block;
}
.gods-box table:first-of-type{
margin-bottom: 0;
}
.gods-box table:last-of-type{
margin-top: 0;
display: block;
max-height: 323px;
overflow: auto;
}
.coupon-box .ns-single-filter-box{
padding-top: 0;
}
.align-center{
text-align: center!important;
}
</style>
{/block}
{block name="main"}
<div class="layui-form">
<div class="layui-card ns-card-common ns-card-brief">
<div class="layui-card-header">
<span class="ns-card-title">基础信息</span>
</div>
<div class="layui-card-body">
<div class="layui-form-item">
<label class="layui-form-label"><span class="required">*</span>等级名称:</label>
<div class="layui-input-block">
<input name="level_name" type="text" lay-verify="required" class="layui-input ns-len-long">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">等级说明:</label>
<div class="layui-input-block ns-len-long">
<textarea name="remark" class="layui-textarea"></textarea>
</div>
</div>
<div class="gratis-wrap">
<div class="layui-form-item">
<label class="layui-form-label"><span class="required">*</span>所需成长值:</label>
<div class="layui-input-block">
<input name="growth" type="number" lay-verify="required" min="0" class="layui-input ns-len-short">
</div>
<div class="ns-word-aux">修改等级所需成长值后,部分客户会因无法达到该成长值要求而发生会员等级的变化</div>
</div>
</div>
</div>
</div>
<div class="layui-card ns-card-common ns-card-brief ns-level-equity" >
<div class="layui-card-header">
<span class="ns-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="is_free_shipping" value="1" lay-skin="switch" />
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label"><span class="required">*</span>消费折扣:</label>
<div class="layui-input-block">
<input type="number" name="consume_discount" min="0" max="100" lay-verify="fl" autocomplete="off" class="layui-input ns-len-short"> %
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">积分回馈倍率:</label>
<div class="layui-input-block">
<input type="number" name="point_feedback" min="0" max="100" lay-verify="jf" autocomplete="off" class="layui-input ns-len-short">
</div>
<div class="ns-word-aux">回馈积分 = 消费金额 * 积分回馈倍率</div>
</div>
</div>
</div>
<div class="layui-card ns-card-common ns-card-brief">
<div class="layui-card-header">
<span class="ns-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 name="send_point" type="number" lay-verify="num" min="0" class="layui-input ns-len-short">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">赠送红包:</label>
<div class="layui-input-block ns-len-long">
<input name="send_balance" type="number" lay-verify="num" min="0" class="layui-input ns-len-short">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">赠送优惠券:</label>
<div class="layui-input-block">
<table class="layui-table" id="coupon_selected" lay-skin="line" lay-size="lg">
<colgroup>
<col width="45%">
<col width="15%">
<col width="25%">
<col width="15%">
</colgroup>
<thead>
<tr>
<th>优惠券名称</th>
<th>优惠金额/折扣</th>
<th>结束时间</th>
<th>操作</th>
</tr>
</thead>
<tbody>
<tr>
<td class="ns-goods-null" colspan="4">
<div class="goods-null">尚未选择赠送优惠券</div>
</td>
</tr>
</tbody>
</table>
<button class="layui-btn ns-bg-color" onclick="addCoupon()">添加优惠券</button>
</div>
</div>
</div>
</div>
<div class="layui-card ns-card-common">
<div class="layui-card-body">
<div class="ns-form-row">
<button class="layui-btn ns-bg-color" lay-submit lay-filter="save">保存</button>
<button class="layui-btn layui-btn-primary" onclick="back()">返回</button>
</div>
</div>
</div>
</div>
{/block}
{block name="script"}
<script>
var coupon_id = [], addCoupon;
var form;
layui.use(['form', 'laytpl'], function() {
form = layui.form;
var laytpl = layui.laytpl,
repeat_flag = false; //防重复标识
form.render();
/**
* 监听保存
*/
form.on('submit(save)', function(data) {
data.field.send_coupon = coupon_id.toString();
if (repeat_flag) return false;
repeat_flag = true;
$.ajax({
url: ns.url("member://shop/memberlevel/addlevel"),
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(){
location.href = ns.url("member://shop/memberlevel/levellist")
},
btn2: function() {
location.href = ns.url("member://shop/memberlevel/addlevel")
}
});
}else{
layer.msg(res.message);
}
}
});
});
/**
* 表单验证
*/
form.verify({
num: function(value) {
var arrmen = value.split(".");
var val = 0;
if (arrmen.length == 2) {
val = arrmen[1];
}
if (value == "") {
return false;
}
if (value < 0 || val.length > 2) {
return '请输入大于0的数保留小数点后两位'
}
},
fl: function(value, item) {
var str = $(item).parents(".layui-form-item").find("label").text().split("*").join("");
str = str.substring(0, str.length - 1);
if (isNaN(parseFloat(value))) {
return "请设置" + str;
}
if (value <= 0) {
return str + "不能小于等于0";
}
if (value > 100) {
return str + "不能大于100";
}
var arrMen = value.split(".");
var val = 0;
if (arrMen.length == 2) {
val = arrMen[1];
}
if (val.length > 2) {
return str + "最多可保留两位小数";
}
},
jf: function(value, item) {
var str = $(item).parents(".layui-form-item").find("label").text().split("*").join("");
str = str.substring(0, str.length - 1);
if (value < 0) {
return str + "不能小于0";
}
if (value > 100) {
return str + "不能大于100";
}
var arrMen = value.split(".");
var val = 0;
if (arrMen.length == 2) {
val = arrMen[1];
}
if (val.length > 2) {
return str + "最多可保留两位小数";
}
}
});
//优惠券
addCoupon = function() {
var data = {};
data.coupon_id = coupon_id;
laytpl($("#couponList").html()).render(data, function(html) {
coupon_list = layer.open({
title: '优惠券列表',
skin: 'layer-tips-class',
type: 1,
area: ['1100px', '600px'],
content: html,
});
if ($("tbody tr input:checked").length == $(".coupon-box tbody tr").length) {
$("input[lay-filter='selectAll']").prop("checked", true);
}
form.render();
});
/**
* 监听全选按钮
*/
form.on('checkbox(selectAll)', function(data) {
if (data.elem.checked) {
$("tr .ns-check-box input:checkbox").each(function(index) {
$(this).prop("checked", true);
});
} else {
$("tr .ns-check-box input:checkbox").each(function() {
$(this).prop("checked", false);
});
}
form.render();
});
form.on('select(selectRule)', function(data){
console.log(data.elem); //得到select原始DOM对象
console.log(data.value); //得到被选中的值
console.log(data.othis); //得到美化后的DOM对象
});
/**
* 监听每一行的多选按钮
*/
var len = $(".coupon-box tbody tr").length;
for (var i = 0; i < len; i++) {
form.on('checkbox(select' + i + ')', function(data) {
if ($("tbody tr input:checked").length == len) {
$("input[lay-filter='selectAll']").prop("checked", true);
} else {
$("input[lay-filter='selectAll']").prop("checked", false);
}
form.render();
});
}
}
});
function couponSelected() {
layer.closeAll('page');
coupon_id = [];
var _len = $("tbody tr input:checked").length;
$("#coupon_selected tbody").empty();
$("#goods tbody tr").each(function(){
var bool = $(this).find("input[type='checkbox']").is(":checked");
if (bool) {
coupon_id.push($(this).find("#coupon_id").val());
var html = '';
var _id = $(this).find("#coupon_id").val(),
image = $(this).find(".ns-title-pic img").attr("src"),
coupon_name = $(this).find(".ns-title-content p").text(),
money = $(this).find(".coupon-money").text(),
end_time = $(this).find(".coupon-end-time").text();
html += '<tr>'+
'<td>'+
'<div class="ns-table-title">'+
'<input type="hidden" value="'+ _id +'" />'+
'<div class="ns-title-pic">';
if (image) {
html += '<img src="'+ image +'">';
}
html += '</div>'+
'<div class="ns-title-content">'+
'<p class="ns-multi-line-hiding">'+ coupon_name +'</p>'+
'</div>'+
'</div>'+
'</td>'+
'<td class="layui-elip coupon-money">'+ money +'</td>'+
'<td class="layui-elip coupon-end-time">'+ end_time +'</td>'+
'<td class="layui-elip"><div class="ns-table-btn"><a class="layui-btn ns-del-btn" onclick="delCoupon(this)">删除</a></div></td>'+
'</tr>';
$("#coupon_selected tbody").append(html);
}
});
if (_len == 0) {
var html = '<tr>'+
'<td class="ns-goods-null" colspan="4">'+
'<div class="goods-null">尚未选择赠送礼包</div>'+
'</td>'+
'</tr>';
$("#coupon_selected tbody").append(html);
}
}
//删除优惠券
function delCoupon(e) {
$(e).parents("tr").remove();
var _len = $("#coupon_selected tbody tr").length;
if(_len == 0) {
var html = '<tr>'+
'<td class="ns-goods-null" colspan="4">'+
'<div class="goods-null">尚未选择赠送优惠券</div>'+
'</td>'+
'</tr>';
$("#coupon_selected tbody").append(html);
}
couponId();
}
function couponId() {
coupon_id = [];
$("#coupon_selected tbody tr").each(function(){
coupon_id.push($(this).find(".ns-table-title input").val());
});
}
function back(){
location.href = ns.url("member://shop/memberlevel/levellist");
}
//添加付费规则
function addRule() {
let level_select = {:json_encode($level_time, JSON_UNESCAPED_UNICODE)};;
$('#level-rule tr').each(function (i, e) {
if($(e).find('select').val() && $(e).find('select').val() != undefined){
delete level_select[$(e).find('select').val()];
}
})
var select_html = '';
for (let i in level_select){
select_html += '<option value="'+i+'">'+level_select[i]+'</option>';
}
var html = `
<tr>
<td>
<div class="ns-len-short">
<select lay-filter="selectRule">
${select_html}
</select>
</div>
</td>
<td class="align-center">
<input type="text" value="0" lay-verify="num" class="layui-input ns-len-short price" placeholder="价格/元">
</td>
<td>
<a href="javascript:void(0)" class="ns-text-color" onclick="deleteRule(this)">删除</a>
</td>
</tr>
`;
$('#level-rule tbody').append(html);
if($('#level-rule tr').length == 5){
$('#add_rule_btn').hide()
}
form.render();
form.on('select(selectRule)', function(data){
let num = 0;
$('#level-rule tr').each(function (i, e) {
if($(e).find('select').val() == data.value){
num++;
$('.delete-rule').removeClass('delete-rule');
$(e).find('select').addClass('delete-rule');
}
})
if(num > 1) deleteRule($('.delete-rule'));
});
form.verify({
num: function (value) {
var arrmen = value.split(".");
var val = 0;
if (arrmen.length == 2) {
val = arrmen[1];
}
if (value == "") {
return false;
}
if (value <= 0 || val.length > 2) {
return '请输入大于0的数保留小数点后两位'
}
}
})
return false;
}
function deleteRule(obj) {
$(obj).parents('tr').remove();
if($('#level-rule tr').length < 5){
$('#add_rule_btn').show()
}
}
</script>
<!-- 优惠券 -->
<script type="text/html" id="couponList">
<div class="coupon-box">
<div class="ns-single-filter-box">
<div class="layui-form">
<div class="layui-input-inline">
<input type="text" name="coupon_name" placeholder="请输优惠券名称" class="layui-input">
<button type="button" class="layui-btn layui-btn-primary" lay-filter="coupon-search" lay-submit>
<i class="layui-icon">&#xe615;</i>
</button>
</div>
</div>
</div>
<div class="gods-box">
<table class="layui-table" lay-skin="line" lay-size="lg">
<colgroup>
<col width="10%">
<col width="10%">
<col width="10%">
<col width="10%">
<col width="10%">
<col width="10%">
<col width="40%">
</colgroup>
<thead>
<tr>
<th class="ns-check-box">
<div class="layui-form">
<input type="checkbox" name="" lay-filter="selectAll" lay-skin="primary">
</div>
</th>
<th class="layui-elip">优惠券名称</th>
<th class="layui-elip">类型</th>
<th class="layui-elip">优惠金额/折扣</th>
<th class="layui-elip">适用商品</th>
<th class="layui-elip">领取人限制</th>
<th class="layui-elip">已领取/发放数</th>
<th class="layui-elip">结束时间</th>
</tr>
</thead>
</table>
<table class="layui-table" id="goods" lay-skin="line" lay-size="lg">
<colgroup>
<col width="8%">
<col width="10%">
<col width="15%">
<col width="15%">
<col width="20%">
<col width="20%">
<col width="27%">
</colgroup>
<tbody>
{foreach $coupon_list.data as $coupon_list_k => $coupon_list_v}
<tr>
<td class="ns-check-box">
<div class="layui-form">
{{# var a = {$coupon_list_v.coupon_type_id} }}
{{# if($.inArray(a.toString(), d.coupon_id) != -1){ }}
<input type="checkbox" name="" lay-filter="select{$coupon_list_k}" lay-skin="primary" checked>
{{# }else{ }}
<input type="checkbox" name="" lay-filter="select{$coupon_list_k}" lay-skin="primary">
{{# } }}
<input type="hidden" id="coupon_id" value="{$coupon_list_v.coupon_type_id}">
</div>
</td>
<td>
<div class="ns-table-title">
<div class="ns-title-pic">
{if condition="$coupon_list_v.image"}
<img src="{:img($coupon_list_v.image)}">
{else/}
<img src="__ROOT__/upload/resources/game/coupon.png">
{/if}
</div>
<div class="ns-title-content">
<p class="ns-multi-line-hiding">{$coupon_list_v.coupon_name}</p>
</div>
</div>
</td>
{if $coupon_list_v.type == 'reward'}
<td>满减</td>
{else/}
<td>折扣</td>
{/if}
{if $coupon_list_v.type == 'reward'}
<td class="layui-elip coupon-money">{$coupon_list_v.money}元</td>
{else/}
<td class="layui-elip coupon-money">{$coupon_list_v.discount}折</td>
{/if}
{if $coupon_list_v.goods_type == '1'}
<td>全部商品</td>
{else/}
<td>指定商品</td>
{/if}
<td>{$coupon_list_v.max_fetch}</td>
<td>{$coupon_list_v.lead_count}/{$coupon_list_v.count}</td>
{if $coupon_list_v.validity_type == 0}
<td class="layui-elip coupon-end-time">{:time_to_date($coupon_list_v.end_time)}</td>
{else/}
<td class="layui-elip coupon-end-time">领取之日起{$coupon_list_v.fixed_term}天有效</td>
{/if}
</tr>
{/foreach}
</tbody>
</table>
</div>
<button class="layui-btn ns-bg-color" onclick="couponSelected()">确定</button>
</div>
</script>
{/block}

View File

@ -0,0 +1,662 @@
{extend name="base"/}
{block name="resources"}
<style>
.ns-form {margin-top: 0;}
.coupon-box{
padding: 20px;
}
.coupon-box .layui-form{
padding: 0!important;
}
.layui-layer-page .layui-layer-content{
overflow: auto !important;
}
.ns-del-btn {
cursor: pointer;
}
.ns-level-equity .layui-input {
display: inline-block;
}
.gods-box table:first-of-type{
margin-bottom: 0;
}
.gods-box table:last-of-type{
margin-top: 0;
display: block;
max-height: 323px;
overflow: auto;
}
.coupon-box .ns-single-filter-box{
padding-top: 0;
}
</style>
{/block}
{block name="main"}
<div class="layui-form">
<div class="layui-card ns-card-common ns-card-brief">
<div class="layui-card-header">
<span class="ns-card-title">基础信息</span>
</div>
<div class="layui-card-body">
<div class="layui-form-item">
<label class="layui-form-label"><span class="required">*</span>等级名称:</label>
<div class="layui-input-block">
<input name="level_name" value="{$level_info.level_name}" type="text" lay-verify="required" class="layui-input ns-len-long">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">等级说明:</label>
<div class="layui-input-block ns-len-long">
<textarea name="remark" class="layui-textarea">{$level_info.remark}</textarea>
</div>
</div>
{if $level_info.is_default == 0}
<div class="gratis-wrap {if $level_info['level_type'] == 1}layui-hide{/if}">
<div class="layui-form-item">
<label class="layui-form-label"><span class="required">*</span>所需成长值:</label>
<div class="layui-input-block">
<input name="growth" value="{$level_info.growth}" type="number" {if $level_info['level_type'] == 0}lay-verify="required"{/if} min="0" class="layui-input ns-len-short">
</div>
<div class="ns-word-aux">修改等级所需成长值后,部分客户会因无法达到该成长值要求而发生会员等级的变化</div>
</div>
</div>
{/if}
</div>
</div>
{if $level_info.is_default == 0}
<div class="layui-card ns-card-common ns-card-brief ns-level-equity">
<div class="layui-card-header">
<span class="ns-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="is_free_shipping" value="1" {if $level_info.is_free_shipping == 1} checked {/if} lay-skin="switch" />
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label"><span class="required">*</span>消费折扣:</label>
<div class="layui-input-block">
<input type="number" name="consume_discount" value="{$level_info.consume_discount}" lay-verify="fl" min="0" max="100" autocomplete="off" class="layui-input ns-len-short"> %
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">积分回馈倍率:</label>
<div class="layui-input-block">
<input type="number" name="point_feedback" value="{$level_info.point_feedback}" lay-verify="jf" min="0" max="100" autocomplete="off" class="layui-input ns-len-short">
</div>
<div class="ns-word-aux">回馈积分 = 消费金额 * 积分回馈倍率</div>
</div>
</div>
</div>
<div class="layui-card ns-card-common ns-card-brief">
<div class="layui-card-header">
<span class="ns-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 name="send_point" value="{$level_info.send_point}" type="number" lay-verify="num" min="0" class="layui-input ns-len-short">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">赠送红包:</label>
<div class="layui-input-block ns-len-long">
<input name="send_balance" value="{$level_info.send_balance}" type="number" lay-verify="num" min="0" class="layui-input ns-len-short">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">赠送优惠券:</label>
<div class="layui-input-block">
<table class="layui-table" id="coupon_selected" lay-skin="line" lay-size="lg">
<colgroup>
<col width="45%">
<col width="15%">
<col width="25%">
<col width="15%">
</colgroup>
<thead>
<tr>
<th>优惠券名称</th>
<th>优惠金额/折扣</th>
<th>结束时间</th>
<th>操作</th>
</tr>
</thead>
<tbody>
{if condition="isset($level_info.coupon_list)"}
{foreach $level_info.coupon_list.data as $coupon_list_k => $coupon_list_v}
<tr>
<td>
<div class="ns-table-title">
<input type="hidden" value="{$coupon_list_v.coupon_type_id}">
<div class="ns-title-pic">
{if condition="$coupon_list_v.image"}
<img src="{:img($coupon_list_v.image)}">
{else/}
<img src="__ROOT__/upload/resources/game/coupon.png">
{/if}
</div>
<div class="ns-title-content">
<p class="ns-multi-line-hiding">{$coupon_list_v.coupon_name}</p>
</div>
</div>
</td>
{if $coupon_list_v.type == 'reward'}
<td class="layui-elip coupon-money">{$coupon_list_v.money}元</td>
{else/}
<td class="layui-elip coupon-money">{$coupon_list_v.discount}折</td>
{/if}
{if $coupon_list_v.validity_type == 0}
<td class="layui-elip coupon-end-time">{:time_to_date($coupon_list_v.end_time)}</td>
{else/}
<td class="layui-elip coupon-end-time">领取之日起{$coupon_list_v.fixed_term}天有效</td>
{/if}
<td class="layui-elip"><a class="default ns-del-btn" onclick="delCoupon(this)">删除</a></td>
</tr>
{/foreach}
{else/}
<tr>
<td class="ns-goods-null" colspan="4">
<div class="goods-null">尚未选择赠送优惠券</div>
</td>
</tr>
{/if}
</tbody>
</table>
<button class="layui-btn ns-bg-color" onclick="addCoupon()">添加优惠券</button>
</div>
</div>
</div>
</div>
{/if}
<input type="hidden" name="level_id" value="{$level_info.level_id}">
<div class="layui-card ns-card-common">
<div class="layui-card-body">
<div class="ns-form-row">
<button class="layui-btn ns-bg-color" lay-submit lay-filter="save">保存</button>
<button class="layui-btn layui-btn-primary" onclick="back()">返回</button>
</div>
</div>
</div>
</div>
{/block}
{block name="script"}
<script type="text/javascript" src="__STATIC__/ext/colorPicker/js/colorpicker.js"></script>
<script>
var coupon_id = [], addCoupon;
var form;
layui.use(['form', 'laytpl'], function() {
form = layui.form;
var laytpl = layui.laytpl,
repeat_flag = false; //防重复标识
form.render();
couponId();
/**
* 监听保存
*/
form.on('submit(save)', function(data) {
data.field.send_coupon = coupon_id.toString();
if(repeat_flag) return false;
repeat_flag = true;
$.ajax({
url: ns.url("member://shop/memberlevel/editLevel"),
data: data.field,
type: "POST",
dataType: "JSON",
success: function(res) {
repeat_flag = false;
if (res.code == 0) {
layer.confirm('编辑成功', {
title:'操作提示',
btn: ['返回列表', '继续操作'],
yes: function(){
location.href = ns.url("member://shop/memberlevel/levelList")
},
btn2: function() {
location.reload();
}
});
}else{
layer.msg(res.message);
}
}
});
});
/**
* 表单验证
*/
form.verify({
num: function(value) {
var arrMen = value.split(".");
var val = 0;
if (arrMen.length == 2) {
val = arrMen[1];
}
if (value == "") {
return false;
}
if (value < 0 || val.length > 2) {
return '请输入大于0的数保留小数点后两位'
}
},
fl: function(value, item) {
var str = $(item).parents(".layui-form-item").find("label").text().split("*").join("");
str = str.substring(0, str.length - 1);
if (isNaN(parseFloat(value))) {
return "请设置" + str;
}
if (value <= 0) {
return str + "不能小于等于0";
}
if (value > 100) {
return str + "不能大于100";
}
var arrMen = value.split(".");
var val = 0;
if (arrMen.length == 2) {
val = arrMen[1];
}
if (val.length > 2) {
return str + "最多可保留两位小数";
}
},
jf: function(value, item) {
var str = $(item).parents(".layui-form-item").find("label").text().split("*").join("");
str = str.substring(0, str.length - 1);
if (value < 0) {
return str + "不能小于0";
}
if (value > 100) {
return str + "不能大于100";
}
var arrMen = value.split(".");
var val = 0;
if (arrMen.length == 2) {
val = arrMen[1];
}
if (val.length > 2) {
return str + "最多可保留两位小数";
}
}
});
//优惠券选择
addCoupon = function() {
var data = {};
data.coupon_id = coupon_id;
laytpl($("#couponList").html()).render(data, function(html) {
coupon_list = layer.open({
title: '优惠券列表',
skin: 'layer-tips-class',
type: 1,
area: ['1100px', '600px'],
content: html,
});
if ($("tbody tr input:checked").length == $(".coupon-box tbody tr").length) {
$("input[lay-filter='selectAll']").prop("checked", true);
}
form.render();
});
/**
* 监听全选按钮
*/
form.on('checkbox(selectAll)', function(data) {
if (data.elem.checked) {
$("tr .ns-check-box input:checkbox").each(function(index) {
$(this).prop("checked", true);
});
} else {
$("tr .ns-check-box input:checkbox").each(function() {
$(this).prop("checked", false);
});
}
form.render();
});
/**
* 监听每一行的多选按钮
*/
var len = $(".coupon-box tbody tr").length;
for (var i = 0; i < len; i++) {
form.on('checkbox(select' + i + ')', function(data) {
if ($("tbody tr input:checked").length == len) {
$("input[lay-filter='selectAll']").prop("checked", true);
} else {
$("input[lay-filter='selectAll']").prop("checked", false);
}
form.render();
});
}
}
});
function couponSelected() {
layer.closeAll('page');
coupon_id = [];
var _len = $("tbody tr input:checked").length;
$("#coupon_selected tbody").empty();
$("#goods tbody tr").each(function(){
var bool = $(this).find("input[type='checkbox']").is(":checked");
if (bool) {
coupon_id.push($(this).find("#coupon_id").val());
var html = '';
var _id = $(this).find("#coupon_id").val(),
image = $(this).find(".ns-title-pic img").attr("src"),
coupon_name = $(this).find(".ns-title-content p").text(),
money = $(this).find(".coupon-money").text(),
end_time = $(this).find(".coupon-end-time").text();
html += '<tr>'+
'<td>'+
'<div class="ns-table-title">'+
'<input type="hidden" value="'+ _id +'" />'+
'<div class="ns-title-pic">';
if (image) {
html += '<img src="'+ image +'">';
}
html += '</div>'+
'<div class="ns-title-content">'+
'<p class="ns-multi-line-hiding">'+ coupon_name +'</p>'+
'</div>'+
'</div>'+
'</td>'+
'<td class="layui-elip coupon-money">'+ money +'</td>'+
'<td class="layui-elip coupon-end-time">'+ end_time +'</td>'+
'<td class="layui-elip"><div class="ns-table-btn"><a class="layui-btn ns-del-btn" onclick="delCoupon(this)">删除</a></div></td>'+
'</tr>';
$("#coupon_selected tbody").append(html);
}
if (_len == 0) {
var html = '<tr>'+
'<td class="ns-goods-null" colspan="4">'+
'<div class="goods-null">尚未选择赠送优惠券</div>'+
'</td>'+
'</tr>';
$("#coupon_selected tbody").append(html);
}
});
}
//删除优惠券
function delCoupon(e) {
$(e).parents("tr").remove();
var _len = $("#coupon_selected tbody tr").length;
if(_len == 0) {
var html = '<tr>'+
'<td class="ns-goods-null" colspan="4">'+
'<div class="goods-null">尚未选择赠送优惠券</div>'+
'</td>'+
'</tr>';
$("#coupon_selected tbody").append(html);
}
couponId();
}
//coupon_id
function couponId() {
coupon_id = [];
$("#coupon_selected tbody tr").each(function(){
coupon_id.push($(this).find(".ns-table-title input").val());
});
}
function back(){
location.href = ns.url("member://shop/memberlevel/levelList");
}
//添加付费规则
function addRule() {
let level_select = {:json_encode($level_time, JSON_UNESCAPED_UNICODE)};;
$('#level-rule tr').each(function (i, e) {
if($(e).find('select').val() && $(e).find('select').val() != undefined){
delete level_select[$(e).find('select').val()];
}
})
var select_html = '';
for (let i in level_select){
select_html += '<option value="'+i+'">'+level_select[i]+'</option>';
}
var html = `
<tr>
<td>
<div class="ns-len-short">
<select lay-filter="selectRule">
${select_html}
</select>
</div>
</td>
<td class="align-center">
<input type="text" value="0" lay-verify="num" class="layui-input ns-len-short price" placeholder="价格/元">
</td>
<td>
<a href="javascript:void(0)" class="ns-text-color" onclick="deleteRule(this)">删除</a>
</td>
</tr>
`;
$('#level-rule tbody').append(html);
if($('#level-rule tr').length == 5){
$('#add_rule_btn').hide()
}
form.render();
form.on('select(selectRule)', function(data){
let num = 0;
$('#level-rule tr').each(function (i, e) {
if($(e).find('select').val() == data.value){
num++;
$('.delete-rule').removeClass('delete-rule');
$(e).find('select').addClass('delete-rule');
}
})
if(num > 1) deleteRule($('.delete-rule'));
});
form.verify({
num: function (value) {
var arrmen = value.split(".");
var val = 0;
if (arrmen.length == 2) {
val = arrmen[1];
}
if (value == "") {
return false;
}
if (value <= 0 || val.length > 2) {
return '请输入大于0的数保留小数点后两位'
}
}
})
return false;
}
function deleteRule(obj) {
$(obj).parents('tr').remove();
if($('#level-rule tr').length < 5){
$('#add_rule_btn').show()
}
}
</script>
<!-- 优惠券 -->
<script type="text/html" id="couponList">
<div class="coupon-box">
<div class="ns-single-filter-box">
<div class="layui-form">
<div class="layui-input-inline">
<input type="text" name="coupon_name" placeholder="请输入优惠券名称" class="layui-input">
<button type="button" class="layui-btn layui-btn-primary" lay-filter="coupon-search" lay-submit>
<i class="layui-icon">&#xe615;</i>
</button>
</div>
</div>
</div>
<div class="gods-box">
<table class="layui-table" lay-skin="line" lay-size="lg">
<colgroup>
<col width="10%">
<col width="10%">
<col width="10%">
<col width="10%">
<col width="10%">
<col width="10%">
<col width="40%">
</colgroup>
<thead>
<tr>
<th class="ns-check-box">
<div class="layui-form">
<input type="checkbox" name="" lay-filter="selectAll" lay-skin="primary">
</div>
</th>
<th class="layui-elip">优惠券名称</th>
<th class="layui-elip">类型</th>
<th class="layui-elip">优惠金额/折扣</th>
<th class="layui-elip">适用商品</th>
<th class="layui-elip">领取人限制</th>
<th class="layui-elip">已领取/发放数</th>
<th class="layui-elip">结束时间</th>
</tr>
</thead>
</table>
<table class="layui-table" id="goods" lay-skin="line" lay-size="lg">
<colgroup>
<col width="8%">
<col width="10%">
<col width="15%">
<col width="15%">
<col width="20%">
<col width="20%">
<col width="27%">
</colgroup>
<tbody>
{foreach $coupon_list.data as $coupon_list_k => $coupon_list_v}
<tr>
<td class="ns-check-box">
<div class="layui-form">
{{# var a = {$coupon_list_v.coupon_type_id} }}
{{# if($.inArray(a.toString(), d.coupon_id) != -1){ }}
<input type="checkbox" name="" lay-filter="select{$coupon_list_k}" lay-skin="primary" checked>
{{# }else{ }}
<input type="checkbox" name="" lay-filter="select{$coupon_list_k}" lay-skin="primary">
{{# } }}
<input type="hidden" id="coupon_id" value="{$coupon_list_v.coupon_type_id}">
</div>
</td>
<td>
<div class="ns-table-title">
<div class="ns-title-pic">
{if condition="$coupon_list_v.image"}
<img src="{:img($coupon_list_v.image)}">
{else/}
<img src="__ROOT__/upload/resources/game/coupon.png">
{/if}
</div>
<div class="ns-title-content">
<p class="ns-multi-line-hiding">{$coupon_list_v.coupon_name}</p>
</div>
</div>
</td>
{if $coupon_list_v.type == 'reward'}
<td class="layui-elip">满减</td>
{else/}
<td class="layui-elip">折扣</td>
{/if}
{if $coupon_list_v.type == 'reward'}
<td class="layui-elip coupon-money">{$coupon_list_v.money}元</td>
{else/}
<td class="layui-elip coupon-money">{$coupon_list_v.discount}折</td>
{/if}
{if $coupon_list_v.goods_type == 1}
<td class="layui-elip">全部商品</td>
{else/}
<td class="layui-elip">指定商品</td>
{/if}
<td class="layui-elip">{$coupon_list_v.max_fetch}</td>
{if $coupon_list_v.count == -1}
<td class="layui-elip coupon-stock">{$coupon_list_v.lead_count}/不限量</td>
{else/}
<td class="layui-elip coupon-stock">{$coupon_list_v.lead_count}/{$coupon_list_v.count}</td>
{/if}
{if $coupon_list_v.validity_type == 0}
<td class="layui-elip coupon-end-time">{:time_to_date($coupon_list_v.end_time)}</td>
{else/}
<td class="layui-elip coupon-end-time">领取之日起{$coupon_list_v.fixed_term}天有效</td>
{/if}
</tr>
{/foreach}
</tbody>
</table>
</div>
<button class="layui-btn ns-bg-color" onclick="couponSelected()">确定</button>
</div>
</script>
{/block}

View File

@ -0,0 +1,159 @@
{extend name="base"/}
{block name="resources"}
{/block}
{block name="main"}
<div class="layui-collapse ns-tips">
<div class="layui-colla-item">
<h2 class="layui-colla-title">操作提示</h2>
<ul class="layui-colla-content layui-show">
<li>会员等级按照会员的成长值进行自动升级,请谨慎设置会员等级。</li>
<li>商城可以根据会员等级设置相应的活动优惠。</li>
</ul>
</div>
</div>
<!-- 搜索框 -->
<div class="ns-single-filter-box">
<button class="layui-btn ns-bg-color" onclick="addLevel()">添加会员等级</button>
<div class="layui-form">
<div class="layui-input-inline">
<input type="text" name="search_text" placeholder="请输入会员等级名称" autocomplete="off" class="layui-input">
<button type="button" class="layui-btn layui-btn-primary" lay-filter="search" lay-submit>
<i class="layui-icon">&#xe615;</i>
</button>
</div>
</div>
</div>
<table id="level_list" lay-filter="level_list"></table>
<!-- 操作 -->
<script type="text/html" id="operation">
<div class="ns-table-btn">
<a class="layui-btn" lay-event="edit">编辑</a>
{{# if(d.is_default == 0){ }}
<a class="layui-btn" lay-event="del">删除</a>
{{# } }}
</div>
</script>
{/block}
{block name="script"}
<script>
layui.use(['form'], function() {
var table,
form = layui.form,
repeat_flag = false; //防重复标识
table = new Table({
elem: '#level_list',
url: ns.url("member://shop/memberlevel/levelList"),
cols: [
[{
title: '会员等级',
width: '12%',
unresize: 'false',
templet: function (data) {
return "VIP"+data.LAY_INDEX;
}
},{
field: 'level_name',
title: '等级名称',
width: '15%',
unresize: 'false'
},{
field: 'growth',
title: '成长值',
width: '20%',
unresize: 'false'
},{
field: 'member_num',
title: '持有人数',
width: '10%',
unresize: 'false'
},{
field: '',
title: '等级权益',
width: '30%',
unresize: 'false',
templet: function (data) {
var text = '';
if (data.is_free_shipping == 1) text += '购物享商品包邮;';
if (data.consume_discount != 100) text += '购物享'+ (data.consume_discount / 10) +'折优惠;';
if (data.point_feedback > 0) text += '购物享'+ data.point_feedback +'倍积分回馈;';
return text;
}
}, {
title: '操作',
width: '10%',
unresize: 'false',
toolbar: '#operation'
}]
]
});
/**
* 工具栏操作,编辑、删除
*/
table.tool(function(obj) {
var data = obj.data,
event = obj.event;
switch (event) {
case 'edit':
location.href = ns.url("member://shop/memberlevel/editLevel?level_id=" + data.level_id);
break;
case 'del':
delMemberLevel(data.level_id);
}
});
/**
* 搜索功能
*/
form.on('submit(search)', function(data) {
data
table.reload( {
page: {
curr: 1
},
where: data.field
});
});
// 删除方法
function delMemberLevel(level_id) {
if(repeat_flag) return false;
repeat_flag = true;
layer.confirm('确定要删除该卡吗?', function() {
$.ajax({
type: 'POST',
url: ns.url("member://shop/memberlevel/deleteLevel"),
data: {level_id},
dataType: 'JSON',
success: function(res) {
layer.msg(res.message);
repeat_flag = false;
if(res.code == 0){
table.reload();
}
}
});
}, function () {
layer.close();
repeat_flag = false;
});
}
});
/**
* 点击跳转添加会员卡页面
*/
function addLevel() {
location.href = ns.url("member://shop/memberlevel/addLevel");
}
</script>
{/block}

View File

@ -0,0 +1,133 @@
{extend name="base"/}
{block name="resources"}
<style>
.layui-table-view .layui-table[lay-size=lg] .layui-table-cell{line-height: 2}
</style>
{/block}
{block name="main"}
<!-- 搜索框 -->
<div class="ns-single-filter-box">
<div class="layui-form">
<div class="layui-input-inline">
<select class="" name="change_type">
<option value="">请选择变更方式</option>
{foreach $level_change_type as $k => $v}
<option value="{$k}">{$v}</option>
{/foreach}
</select>
</div>
<div class="layui-input-inline">
<input type="text" name="search_text" placeholder="请输入会员名称/手机号" autocomplete="off" class="layui-input">
<button type="button" class="layui-btn layui-btn-primary" lay-filter="search" lay-submit>
<i class="layui-icon">&#xe615;</i>
</button>
</div>
</div>
</div>
<script type="text/html" id="member_info">
<div class="ns-table-title">
<div class="ns-title-pic">
<img layer-src src="{{ns.img(d.headimg)}}" onerror="this.src = 'SHOP_IMG/default_headimg.png' "/>
</div>
<div class="ns-title-content">
<a href="javascript:;" class="ns-multi-line-hiding ns-text-color"
title="{{d.nickname}}">{{d.nickname}}</a>
</div>
</div>
</script>
<table id="records_list" lay-filter="records_list"></table>
{/block}
{block name="script"}
<script>
layui.use(['form'], function() {
var table,
form = layui.form,
repeat_flag = false; //防重复标识
/**
* 加载表格
*/
table = new Table({
elem: '#records_list',
url: ns.url("member://shop/memberlevel/levelrecords"),
cols: [
[{
field: 'level_name',
title: '会员信息',
width: '16%',
unresize: 'false',
templet: '#member_info'
},{
field: 'before_level_name',
title: '变更前',
width: '12%',
unresize: 'false',
templet: function (data) {
let html = '类型:';
html += data.before_level_type == 0 ? '免费卡': '付费卡';
html += '<br>名称:'+data.before_level_name;
return html
}
},{
field: 'after_level_name',
title: '变更后',
width: '12%',
unresize: 'false',
templet: function (data) {
let html = '类型:';
html += data.after_level_type == 0 ? '免费卡': '付费卡';
html += '<br>名称:'+data.after_level_name;
return html
}
}, {
field: 'change_time',
title: '变更时间',
width: '15%',
unresize: 'false',
templet: function (data) {
return ns.time_to_date(data.change_time);
}
},{
field: 'action_type',
title: '操作人类型',
width: '10%',
unresize: 'false',
templet: function (data) {
return data.action_type == 'user' ? '后台用户': '会员自身';
}
},{
field: 'action_name',
title: '操作人',
width: '10%',
unresize: 'false'
}, {
field:'change_type_name',
title: '变更方式',
width: '10%',
unresize: 'false',
}]
]
});
/**
* 搜索功能
*/
form.on('submit(search)', function(data) {
table.reload( {
page: {
curr: 1
},
where: data.field
});
});
});
</script>
{/block}

View File

@ -0,0 +1,281 @@
{extend name="base"/}
{block name="resources"}
{/block}
{block name="main"}
<div class="ns-screen layui-collapse" lay-filter="selection_panel">
<div class="layui-colla-item">
<form class="layui-form layui-colla-content layui-form layui-show" lay-filter="order_list" action="javascript:;">
<div class="layui-form-item">
<div class="layui-inline">
<label class="layui-form-label">订单号:</label>
<div class="layui-input-inline">
<input type="text" class="layui-input" name="order_no">
</div>
</div>
<div class="layui-inline">
<label class="layui-form-label">购买人昵称:</label>
<div class="layui-input-inline">
<input type="text" class="layui-input" name="nickname">
</div>
</div>
</div>
<div class="layui-form-item">
<div class="layui-inline">
<label class="layui-form-label">下单时间:</label>
<div class="layui-input-inline">
<input type="text" class="layui-input" name="start_time" placeholder="开始时间" id="start_time" readonly>
<i class="ns-calendar"></i>
</div>
<div class="layui-form-mid">-</div>
<div class="layui-input-inline">
<input type="text" class="layui-input" name="end_time" placeholder="结束时间" id="end_time" readonly>
<i class="ns-calendar"></i>
</div>
<button class="layui-btn layui-btn-primary date-picker-btn" onclick="datePick(7, this);return false;">近7天</button>
<button class="layui-btn layui-btn-primary date-picker-btn" onclick="datePick(30, this);return false;">近30天</button>
</div>
</div>
<div class="layui-form-item">
<div class="layui-inline">
<label class="layui-form-label">订单状态:</label>
<div class="layui-input-inline">
<select name="status" lay-filter="status">
<option value="">全部</option>
<option value="0">待支付</option>
<option value="1">已支付</option>
<option value="-1">已关闭</option>
</select>
</div>
</div>
</div>
<div class="ns-form-row">
<button class="layui-btn ns-bg-color" lay-submit lay-filter="search">筛选</button>
<button type="reset" class="layui-btn layui-btn-primary">重置</button>
</div>
</form>
</div>
</div>
<!-- 订单列表 -->
<table id="order_list" lay-filter="order_list"></table>
<!-- 操作 -->
<script type="text/html" id="operation">
<div class="ns-table-btn">
{{# if(d.order_status == 0 ){ }}
<a class="layui-btn" lay-event="offlinepay">线下支付</a>
{{# } }}
<a class="layui-btn" lay-event="detail">详情</a>
</div>
</script>
<!-- 用户信息 -->
<script type="text/html" id="member_info">
<div class="ns-table-title">
<div class='ns-title-pic'>
{{# if(d.headimg){ }}
<img layer-src src="{{ns.img(d.headimg)}}" onerror="this.src = 'SHOP_IMG/default_headimg.png' "/>
{{# } }}
</div>
<div class='ns-title-content'>
<p class="ns-multi-line-hiding">{{d.nickname}}</p>
</div>
</div>
</script>
{/block}
{block name="script"}
<script>
var table,
laydate,
form,
repeat_flag = false; //防重复标识
layui.use(['form', 'laydate'], function() {
laydate = layui.laydate;
form = layui.form;
form.render();
//渲染时间
laydate.render({
elem: '#start_time'
,type: 'datetime'
,change: function(value, date, endDate){
$(".date-picker-btn").removeClass("selected");
}
});
laydate.render({
elem: '#end_time'
,type: 'datetime'
,change: function(value, date, endDate){
$(".date-picker-btn").removeClass("selected");
}
});
/**
* 加载表格
*/
table = new Table({
elem: '#order_list',
url: ns.url("member://shop/memberlevel/order"),
cols: [
[{
field: 'order_no',
title: '订单号',
width: '14%',
unresize: 'false'
},
{
title: '购买人信息',
width: '12%',
templet: "#member_info"
},
{
field: 'level_name',
title: '卡名称',
width: '12%',
unresize: 'false'
}, {
title: '订单类型',
width: '8%',
templet: function (data) {
return (data.order_type == 1 ? '开卡' : '续费');
}
},
{
title: '购买时长',
width: '8%',
unresize: 'false',
templet: function (data) {
switch (data.period_unit) {
case 'week':
return '一周';
break;
case 'month':
return '一月';
break;
case 'quarter':
return '一季';
break;
case 'year':
return '一年';
break;
}
}
}, {
title: '订单金额',
width: '8%',
unresize: 'false',
templet: function (data) {
return data.order_money;
}
},
{
title: '下单时间',
width: '10%',
unresize: 'false',
templet: function (data) {
return ns.time_to_date(data.create_time);
}
},
{
title: '订单状态',
width: '8%',
templet: function (data) {
switch (data.order_status) {
case 0:
return '待支付';
break;
case 1:
return '已支付';
break;
case -1:
return '已关闭';
break;
}
}
},{
title: '操作',
width: '10%',
unresize: 'false',
toolbar: '#operation'
}]
]
});
/**
* 工具栏操作,编辑、删除
*/
table.tool(function(obj) {
var data = obj.data,
event = obj.event;
switch (event) {
case 'offlinepay':
$.ajax({
url: ns.url("member://shop/memberlevel/offlinepay"),
data: {
out_trade_no: data.out_trade_no
},
type: "POST",
dataType: "JSON",
success: function(res) {
if (res.code == 0) {
table.reload();
}else{
layer.msg(res.message);
}
}
});
break;
case 'detail':
location.href = ns.url("member://shop/memberlevel/orderdetail?order_id=" + data.order_id);
break;
}
});
/**
* 搜索功能
*/
form.on('submit(search)', function(data) {
table.reload( {
page: {
curr: 1
},
where: data.field
});
});
});
function datePick(date_num,event_obj){
$(".date-picker-btn").removeClass("selected");
$(event_obj).addClass('selected');
Date.prototype.Format = function (fmt,date_num) { //author: meizz
this.setDate(this.getDate()-date_num);
var o = {
"M+": this.getMonth() + 1, //月份
"d+": this.getDate(), //日
"H+": this.getHours(), //小时
"m+": this.getMinutes(), //分
"s+": this.getSeconds(), //秒
"q+": Math.floor((this.getMonth() + 3) / 3), //季度
"S": this.getMilliseconds() //毫秒
};
if (/(y+)/.test(fmt)) fmt = fmt.replace(RegExp.$1, (this.getFullYear() + "").substr(4 - RegExp.$1.length));
for (var k in o)
if (new RegExp("(" + k + ")").test(fmt)) fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length)));
return fmt;
};
var now_time = new Date().Format("yyyy-MM-dd 23:59:59",0);//当前日期
var before_time = new Date().Format("yyyy-MM-dd 00:00:00",date_num-1);//前几天日期
$("input[name=start_time]").val(before_time,0);
$("input[name=end_time]").val(now_time,date_num-1);
}
</script>
{/block}

View File

@ -0,0 +1,129 @@
{extend name="base"/}
{block name="resources"}
<style>
.layui-colla-content li { line-height: 30px; }
</style>
{/block}
{block name="main"}
<div class="layui-card ns-card-common ns-card-brief">
<div class="layui-card-header">
<span class="ns-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 ns-len-mid">
<p class="ns-input-text ns-len-mid">{$order.data.order_no}</p>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">交易号:</label>
<div class="layui-input-block ns-len-mid">
<p class="ns-input-text ns-len-mid">{$order.data.out_trade_no}</p>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">订单类型:</label>
<div class="layui-input-block ns-len-mid">
<p class="ns-input-text ns-len-mid">{$order.data.order_type == 1 ? '开卡' : '续费'}</p>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">订单状态:</label>
<div class="layui-input-block ns-len-mid">
<p class="ns-input-text ns-len-mid">
{switch name="$order.data.order_status"}
{case value="0"}待支付{/case}
{case value="1"}已支付{/case}
{case value="-1"}已关闭{/case}
{/switch}
</p>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">客户头像:</label>
<div class="layui-input-block ns-len-mid">
<p class="ns-input-text ns-len-mid">
<img class="member_img" src="{:img($order.data.headimg)}" width="40px" onerror="this.src = 'SHOP_IMG/default_headimg.png' ">
</p>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">客户昵称:</label>
<div class="layui-input-block ns-len-mid">
<p class="ns-input-text ns-len-mid">{$order.data.nickname}</p>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">会员卡名称:</label>
<div class="layui-input-block ns-len-mid">
<p class="ns-input-text ns-len-mid">{$order.data.level_name}</p>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">购买时长:</label>
<div class="layui-input-block ns-len-mid">
<p class="ns-input-text ns-len-mid">
{switch name="$order.data.period_unit"}
{case value="week"}一周{/case}
{case value="month"}一月{/case}
{case value="quarter"}一季{/case}
{case value="year"}一年{/case}
{/switch}
</p>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">订单金额:</label>
<div class="layui-input-block ns-len-mid">
<p class="ns-input-text ns-len-mid">{$order.data.order_money}</p>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">下单时间:</label>
<div class="layui-input-block ns-len-mid">
<p class="ns-input-text ns-len-mid">{:time_to_date($order.data.create_time)}</p>
</div>
</div>
{if $order.data.order_status eq 1}
<div class="layui-form-item">
<label class="layui-form-label">支付方式:</label>
<div class="layui-input-block ns-len-mid">
<p class="ns-input-text ns-len-mid">{$order.data.pay_type_name}</p>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">支付时间:</label>
<div class="layui-input-block ns-len-mid">
<p class="ns-input-text ns-len-mid">{:date('Y-m-d H:i:s', $order.data.pay_time)}</p>
</div>
</div>
{/if}
<div class="ns-form-row">
<button class="layui-btn layui-btn-primary" onclick="back()">返回</button>
</div>
</div>
</div>
{/block}
{block name="script"}
<script>
function back() {
location.href = ns.url("memberrecharge://shop/memberrecharge/order_lists");
}
</script>
{/block}

View File

@ -0,0 +1,118 @@
{extend name="base"/}
{block name="resources"}
{/block}
{block name="main"}
<div class="layui-form ns-form">
<div class="layui-form-item">
<label class="layui-form-label">是否启用提现:</label>
<div class="layui-input-block">
<input type="checkbox" name="is_use" lay-filter="is_use" value="1" lay-skin="switch" {if !empty($config) && $config.is_use==1 } checked {/if} >
</div>
<div class="ns-word-aux">会员可以将<span class="ns-text-color">可提现余额账户</span>的金额申请提现</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">提现审核:</label>
<div class="layui-input-block">
<input type="checkbox" name="is_auto_audit" lay-filter="is_auto_audit" value="1" lay-skin="switch" {if !empty($config.value) && $config.value.is_auto_audit==1 } checked {/if} >
</div>
</div>
{if $is_exist}
<div class="layui-form-item">
<label class="layui-form-label">自动转账:</label>
<div class="layui-input-block">
<input type="checkbox" name="is_auto_transfer" lay-filter="is_auto_transfer" value="1" lay-skin="switch" {if !empty($config.value) && $config.value.is_auto_transfer==1 } checked {/if} >
</div>
<div class="ns-word-aux">只有微信和支付宝支付支持自动转账</div>
</div>
{/if}
<div class="layui-form-item">
<label class="layui-form-label">提现手续费比率:</label>
<div class="layui-input-block">
<div class="layui-input-inline">
<input type="number" name="rate" value="{if condition="!empty($config.value)"}{$config.value.rate}{else/}0{/if}" lay-verify="positivEinteger" autocomplete="off" class="layui-input ns-len-short">
</div>
<span class="layui-form-mid">%</span>
</div>
<div class="ns-word-aux">比率必须为0-100的整数</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">最低提现额度:</label>
<div class="layui-input-block">
<div class="layui-input-inline">
<input type="number" name="min" value="{if condition="!empty($config.value)"}{$config.value.min ?: 0}{else/}0{/if}" lay-verify="growthInteger" autocomplete="off" class="layui-input ns-len-short">
</div>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">提现最低倍数:</label>
<div class="layui-input-block">
<div class="layui-input-inline">
<input type="number" name="money_multiple" value="{if condition="!empty($config.value)"}{$config.value.money_multiple ?: 0}{else/}0{/if}" lay-verify="growthInteger" autocomplete="off" class="layui-input ns-len-short">
</div>
</div>
<div class="ns-word-aux">提现倍数,用户最低提现为提现金额的倍数</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">转账方式:</label>
<div class="layui-input-block">
<div class="layui-input-inline">
{foreach $transfer_type_list as $k => $v}
<input type="checkbox" name="transfer_type[]" title="{$v}" lay-skin="primary" value="{$k}" {if !empty($config['value']) && stripos($config['value']['transfer_type'], $k) !== false}checked{/if}>
{/foreach}
</div>
</div>
</div>
<div class="ns-form-row">
<button class="layui-btn ns-bg-color" lay-submit lay-filter="save">保存</button>
</div>
</div>
{/block}
{block name="script"}
<script >
layui.use('form', function(){
var form = layui.form,
repeat_flag = false; //防重复标识
form.render();
form.on('submit(save)', function(data){
if (repeat_flag) return;
repeat_flag = true;
$.ajax({
type: 'POST',
dataType: 'JSON',
url: ns.url("member://shop/memberwithdraw/config"),
data: data.field,
success: function(res) {
repeat_flag = false;
if (res.code == 0) {
layer.msg(res.message);
}else{
layer.msg(res.message);
}
}
});
});
// 验证正整数
form.verify({
positivEinteger: function(value){
if(!new RegExp("^(\\d|[1-9]\\d|100)$").test(value)){
return '请输入0-100之间的正整数';
}
},
growthInteger: function (value) {
if(!new RegExp("(^[1-9]\\d*$)").test(value)){
return '请输入正整数';
}
}
});
});
</script>
{/block}

View File

@ -0,0 +1,145 @@
{extend name="base"/}
{block name="resources"}
<style>
.ns-form-row {
margin-top: 0;
margin-left: 220px;
}
</style>
{/block}
{block name="main"}
<div style="height:30px;"></div>
<div class="layui-card ns-card-common ns-card-brief">
<div class="layui-card-header">
<span class="ns-card-title">提现信息</span>
</div>
<div class="layui-card-body">
<div class="layui-form-item">
<label class="layui-form-label img-upload-lable">提现状态:</label>
<div class="layui-input-block">
<p>
{$withdraw_info.status_name}
</p>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label img-upload-lable">申请提现金额:</label>
<div class="layui-input-block">
<p>
{$withdraw_info.apply_money}
</p>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label img-upload-lable">提现手续费:</label>
<div class="layui-input-block">
<p>
{$withdraw_info.service_money}
</p>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label img-upload-lable">提现到账金额:</label>
<div class="layui-input-block">
<p>
{$withdraw_info.money}
</p>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label img-upload-lable">提现申请时间:</label>
<div class="layui-input-block">
<p>
{:time_to_date($withdraw_info.apply_time)}
</p>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label img-upload-lable">提现方式:</label>
<div class="layui-input-block">
<p>
{$withdraw_info.transfer_type_name}
</p>
</div>
</div>
{if $withdraw_info.transfer_type == "bank"}
<div class="layui-form-item">
<label class="layui-form-label img-upload-lable">银行名称:</label>
<div class="layui-input-block">
<p>
{$withdraw_info['bank_name']}
</p>
</div>
</div>
{/if}
<div class="layui-form-item">
<label class="layui-form-label img-upload-lable">提现收款账号:</label>
<div class="layui-input-block">
<p>
{$withdraw_info.account_number}
</p>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label img-upload-lable">真实姓名:</label>
<div class="layui-input-block">
<p>
{$withdraw_info.realname}
</p>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label img-upload-lable">手机号:</label>
<div class="layui-input-block">
<p>
{$withdraw_info.mobile}
</p>
</div>
</div>
</div>
</div>
{if $withdraw_info['status'] == 2}
<div class="layui-card ns-card-common ns-card-brief">
<div class="layui-card-header">
<span class="ns-card-title">转账信息</span>
</div>
<div class="layui-card-body">
{if !empty($withdraw_info['certificate'])}
<div class="layui-form-item">
<label class="layui-form-label img-upload-lable">转账凭证:</label>
<div class="layui-input-block img-upload">
<div class="upload-img-block icon">
<div class="upload-img-box" >
<img layer-src src="{:img($withdraw_info['certificate'])}" alt="转账凭证" />
</div>
</div>
</div>
</div>
{/if}
<div class="layui-form-item">
<label class="layui-form-label img-upload-lable">凭证说明:</label>
<div class="layui-input-block">
<p>
{$withdraw_info.certificate_remark}
</p>
</div>
</div>
</div>
</div>
{/if}
<div class="ns-form-row">
<button class="layui-btn layui-btn-primary" onclick="back()">返回</button>
</div>
{/block}
{block name="script"}
<script>
function back() {
location.href = ns.url("member://shop/memberwithdraw/lists");
}
</script>
{/block}

View File

@ -0,0 +1,578 @@
{extend name="base"/}
{block name="resources"}
<style>
.ns-card-common:first-of-type{margin-top: 0;}
.layui-card-body{display: flex;padding-bottom: 0 !important;padding-right: 50px !important;padding-left: 50px !important;flex-wrap: wrap;}
.layui-card-body .content{width: 33.3%;display: flex;flex-direction: column;margin-bottom: 30px;justify-content: center;}
.layui-card-body .money{font-size: 20px;color: #666;font-weight: bold;margin-top: 10px;max-width: 250px;}
.layui-card-body .subhead{font-size: 12px;margin-left: 3px;cursor: pointer;}
.ns-single-filter-box {background-color: transparent;}
</style>
{/block}
{block name="main"}
<div class="layui-card ns-card-common ns-card-brief">
<div class="layui-card-header">
<div>
<span class="ns-card-title">提现概况</span>
</div>
</div>
<div class="layui-card-body">
<div class="content">
<p class="title">会员可提现余额(元)</p>
<p class="money">{$member_balance_sum.balance_money}</p>
</div>
<div class="content">
<p class="title">会员已提现余额(元)</p>
<p class="money">{$member_balance_sum.balance_withdraw}</p>
</div>
<div class="content">
<p class="title">会员提现中余额(元)</p>
<p class="money">{$member_balance_sum.balance_withdraw_apply}</p>
</div>
</div>
</div>
<!-- 搜索框 -->
<div class="ns-screen layui-collapse" lay-filter="selection_panel">
<div class="layui-colla-item">
<h2 class="layui-colla-title"></h2>
<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">
<input type="text" name="member_name" placeholder="会员用户名" autocomplete="off" class="layui-input ">
</div>
</div>
<div class="layui-inline">
<label class="layui-form-label">提现方式</label>
<div class="layui-input-inline">
<select name="transfer_type">
<option value="">全部</option>
{foreach $transfer_type_list as $transfer_type_k=> $transfer_type_v}
<option value="{$transfer_type_k}">{$transfer_type_v}</option>
{/foreach}
</select>
</div>
</div>
<div class="layui-inline">
<label class="layui-form-label">状态</label>
<div class="layui-input-inline">
<select name="status">
<option value="all">全部</option>
<option value="0">待审核</option>
<option value="1">待转账</option>
<option value="2">已转账</option>
<option value="-1">已拒绝</option>
</select>
</div>
</div>
</div>
<div class="layui-form-item">
<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_time" placeholder="请输入开始时间" autocomplete="off" readonly>
</div>
<div class="layui-input-inline ns-split">-</div>
<div class="layui-input-inline end-time">
<input type="text" class="layui-input" name="end_date" id="end_time" placeholder="请输入结束时间" autocomplete="off" readonly>
</div>
</div>
</div>
<div class="ns-form-row">
<button class="layui-btn ns-bg-color" lay-submit lay-filter="search">筛选</button>
</div>
</form>
</div>
</div>
<!-- 列表 -->
<table id="withdraw_list" lay-filter="withdraw_list"></table>
<script type="text/html" id="status">
{{# if(d.status == 0){ }}
<div class="layui-elip" style="color: red">待审核</div>
{{# }else if(d.status == 1){ }}
<div class="layui-elip" style="color: blue">待转账</div>
{{# }else if(d.status == 2){ }}
<div class="layui-elip" style="color: green">已转账</div>
{{# }else if(d.status == -1){ }}
<div class="layui-elip" style="color: gray">已拒绝</div>
{{# } }}
</script>
<!--操作-->
<script type="text/html" id="operation">
<div class="ns-table-btn">
<a class="layui-btn" lay-event="detail">查看</a>
{{# if(d.status == 0){ }}
<a href="javascript:;" class="layui-btn" lay-event="agree">同意</a>
<a href="javascript:;" class="layui-btn" lay-event="refuse">拒绝</a>
{{# }else if(d.status == 1){ }}
{{# if(d.transfer_type != "bank"){ }}
{if $is_exist}
<a href="javascript:;" class="layui-btn" lay-event="transfer">在线转账</a>
{/if}
{{# } }}
<a href="javascript:;" class="layui-btn" lay-event="actiontransfer">手动转账</a>
{{# } }}
</div>
</script>
<!-- 用户信息 -->
<script type="text/html" id="member_info">
<div class='ns-table-title'>
<div class='ns-title-pic'>
<img layer-src src="{{ns.img(d.member_headimg)}}" onerror="this.src = 'SHOP_IMG/default_headimg.png' ">
</div>
<div class='ns-title-content'>
<p class="layui-elip">{{d.member_name}}</p>
</div>
</div>
</script>
<!--时间-->
<script type="text/html" id="apply_time">
<div class="layui-elip">{{ns.time_to_date(d.apply_time)}}</div>
</script>
{/block}
{block name="script"}
<script>
var table,upload;
layui.use(['form', 'laydate','laytpl'], function() {
var form = layui.form,
laydate = layui.laydate,
currentDate = new Date(),
laytpl = layui.laytpl,
minDate = "";
form.render();
currentDate.setDate(currentDate.getDate() - 7);
//开始时间
laydate.render({
elem: '#start_time',
type: 'datetime'
});
//结束时间
laydate.render({
elem: '#end_time',
type: 'datetime'
});
/**
* 重新渲染结束时间
*/
function reRender(){
$("#end_time").remove();
$(".end-time").html('<input type="text" class="layui-input" placeholder="结束时间" name="end_date" id="end_time" >');
laydate.render({
elem: '#end_time',
type: 'datetime',
min: minDate
});
}
/**
* 表格加载
*/
table = new Table({
elem: '#withdraw_list',
url: ns.url("member://shop/memberwithdraw/lists"),
cols: [
[{
field: 'member_info',
title: '会员信息',
width: '17%',
unresize: 'false',
templet: '#member_info'
}, {
field: 'transfer_type_name',
title: '提现方式',
width: '10%',
unresize: 'false',
}, {
field: 'apply_money',
title: '申请提现金额',
width: '12%',
unresize: 'false',
align: 'right',
templet: function(data) {
return '¥'+ data.apply_money
}
}, {
field: 'service_money',
title: '提现手续费',
width: '12%',
unresize: 'false',
align: 'right',
templet: function(data) {
return '¥'+ data.service_money
}
}, {
field: 'money',
title: '实际转账金额',
width: '12%',
unresize: 'false',
align: 'right',
templet: function(data) {
return '¥'+ data.money
}
}, {
field: 'status_name',
title: '提现状态',
width: '12%',
unresize: 'false',
templet: '#status'
}, {
title: '申请时间',
unresize: 'false',
width: '15%',
templet: '#apply_time'
}, {
title: '操作',
width: '10%',
toolbar: '#operation',
unresize: 'false'
}]
]
});
/**
* 搜索功能
*/
form.on('submit(search)', function(data) {
table.reload({
page: {
curr: 1
},
where: data.field
});
return false;
});
/**
* 监听工具栏操作
*/
table.tool(function(obj) {
var data = obj.data;
switch(obj.event){
case 'detail':
detail(data);
break;
case 'agree':
agree(data);
break;
case 'refuse':
refuse(data);
break;
{if $is_exist}
case 'transfer':
transfer(data);
break;
{/if}
case 'actiontransfer':
laytpl($("#actiontransfer_html").html()).render(data, function(html) {
layer_pass = layer.open({
title: '提现转账',
skin: 'layer-tips-class',
type: 1,
area: ['800px'],
content: html,
});
});
//转账凭证
upload = new Upload({
elem: '#certificate'
});
// return false;
// actiontransfer(data);
break;
}
});
//提交
form.on('submit(actiontransfer)', function(data) {
actiontransfer(data.field);
return false;
});
});
/**
* 查看详情
*/
function detail(field) {
location.href = ns.url("member://shop/memberwithdraw/detail",{id:field.id});
}
{if $is_exist}
/**
* 自动转账
*/
var transfer_repeat_flag = false;
function transfer(field) {
if(transfer_repeat_flag) return false;
transfer_repeat_flag = true;
layer.confirm('确定要进行自动转账吗?', function() {
$.ajax({
url: ns.url("memberwithdraw://shop/withdraw/transfer"),
data: field,
dataType: 'JSON', //服务器返回json格式数据
type: 'POST', //HTTP请求类型
success: function(res) {
transfer_repeat_flag = false;
if (res.code >= 0) {
table.reload({
page: {
curr: 1
}
});
layer.closeAll();
} else {
layer.closeAll();
layer.msg(res.message);
}
}
});
}, function () {
layer.close();
transfer_repeat_flag = false;
});
}
{/if}
/**
* 手动转账
*/
var actiontransfer_repeat_flag = false;
function actiontransfer(field) {
if(actiontransfer_repeat_flag) return false;
actiontransfer_repeat_flag = true;
// 删除图片
// if(!data.field.certificate) upload.delete();
$.ajax({
url: ns.url("member://shop/memberwithdraw/transferfinish"),
data: field,
dataType: 'JSON', //服务器返回json格式数据
type: 'POST', //HTTP请求类型
success: function(res) {
actiontransfer_repeat_flag = false;
if (res.code >= 0) {
table.reload({
page: {
curr: 1
}
});
layer.closeAll();
}else{
layer.msg(res.message);
}
}
});
}
/**
* 同意
*/
var agree_repeat_flag = false;
function agree(field) {
if(agree_repeat_flag) return false;
agree_repeat_flag = true;
layer.confirm('确定要通过该转账申请吗?', function() {
$.ajax({
url: ns.url("member://shop/memberwithdraw/agree"),
data: field,
dataType: 'JSON', //服务器返回json格式数据
type: 'POST', //HTTP请求类型
success: function(res) {
agree_repeat_flag = false;
if (res.code >= 0) {
table.reload({
page: {
curr: 1
}
});
layer.closeAll();
} else {
layer.closeAll();
layer.msg(res.message);
}
}
});
}, function () {
layer.closeAll();
agree_repeat_flag = false;
});
}
/**
* 拒绝
*/
var refuse_repeat_flag = false;
function refuse(field) {
layer.prompt({
title: '拒绝理由',
formType: 2,
yes: function(index, layero) {
var value = layero.find(".layui-layer-input").val();
if (value) {
if(refuse_repeat_flag) return false;
refuse_repeat_flag = true;
field.refuse_reason = value;
$.ajax({
url: ns.url("member://shop/memberwithdraw/refuse"),
data: field,
dataType: 'JSON', //服务器返回json格式数据
type: 'POST', //HTTP请求类型
success: function(res) {
layer.msg(res.message);
refuse_repeat_flag = false;
if (res.code >= 0) {
table.reload({
page: {
curr: 1
},
});
}
}
});
layer.close(index);
} else {
layer.msg('请输入拒绝理由!', {icon: 5, anim: 6});
}
}
});
}
function closePass() {
layer.close(layer_pass);
}
</script>
<!-- 在线转账html -->
<script type="text/html" id="actiontransfer_html">
<div class="layui-form" lay-filter="form">
<div class="layui-form-item">
<label class="layui-form-label">真实姓名:</label>
<div class="layui-input-block">
<p class="ns-input-text ">{{ d.realname }}</p>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">联系电话:</label>
<div class="layui-input-block">
<p class="ns-input-text ">{{ d.mobile }}</p>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">提现类型:</label>
<div class="layui-input-block">
<p class="ns-input-text ">{{d.transfer_type_name}}</p>
</div>
</div>
{{# if(d.transfer_type == "bank"){ }}
<div class="layui-form-item">
<label class="layui-form-label">账户名称:</label>
<div class="layui-input-block">
<p class="ns-input-text ">{{d.bank_name}}</p>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">银行账号:</label>
<div class="layui-input-block">
<p class="ns-input-text ">{{d.account_number}}</p>
</div>
</div>
{{# }else if(d.transfer_type == "alipay"){ }}
<div class="layui-form-item">
<label class="layui-form-label">支付宝账号:</label>
<div class="layui-input-block">
<p class="ns-input-text ">{{d.account_number}}</p>
</div>
</div>
{{# } }}
<div class="layui-form-item">
<label class="layui-form-label">申请提现金额:</label>
<div class="layui-input-block">
<p class="ns-input-text ">{{d.apply_money}}</p>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">提现手续费:</label>
<div class="layui-input-block">
<p class="ns-input-text ">{{d.service_money}}</p>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">提现金额:</label>
<div class="layui-input-block">
<p class="ns-input-text ">{{d.money}}</p>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label img-upload-lable">转账凭证:</label>
<div class="layui-input-block img-upload">
<div class="upload-img-block">
<div class="upload-img-box">
<div class="ns-upload-default" id="certificate">
<div class="upload">
<img src="SHOP_IMG/upload_img.png" />
<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="certificate" >
</div>
<!-- <p id="certificate" class="no-replace">替换</p>
<input type="hidden" name="certificate" >
<i class="del">x</i> -->
</div>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">转账凭证说明:</label>
<div class="layui-input-block ns-len-long">
<textarea name="certificate_remark" class="layui-textarea"></textarea>
</div>
</div>
<input type="hidden" name="id" value="{{ d.id }}">
<div class="ns-form-row">
<button class="layui-btn ns-bg-color" lay-submit lay-filter="actiontransfer">确定</button>
<button class="layui-btn layui-btn-primary" onclick="closePass()">返回</button>
</div>
</div>
</script>
{/block}

Some files were not shown because too many files have changed in this diff Show More