Kirin 3 年之前
父节点
当前提交
e3a3c97b64

+ 102 - 23
app/admin/controller/company/Finance.php

@@ -3,19 +3,11 @@
 namespace app\admin\controller\company;
 namespace app\admin\controller\company;
 
 
 use app\admin\controller\AuthController;
 use app\admin\controller\AuthController;
-use app\admin\model\order\StoreOrder as StoreOrderModel;
-use app\admin\model\store\{
-    StoreProduct as ProductModel
-};
-use app\admin\model\ump\StoreBargain;
-use app\admin\model\ump\StoreCombination;
-use app\admin\model\ump\StoreSeckill;
-use crmeb\services\{JsonService, JsonService as Json, UtilService as Util, FormBuilder as Form};
+
+use crmeb\services\{JsonService, JsonService as Json, UtilService as Util, FormBuilder as Form, UtilService};
 use crmeb\traits\CurdControllerTrait;
 use crmeb\traits\CurdControllerTrait;
 use think\facade\Route as Url;
 use think\facade\Route as Url;
-use app\admin\model\system\{
-    SystemAttachment, ShippingTemplates
-};
+use app\admin\model\system\{StoreBill, StoreExtract, SystemAttachment, ShippingTemplates, SystemStore};
 
 
 
 
 /**
 /**
@@ -28,28 +20,115 @@ class Finance extends AuthController
 
 
     use CurdControllerTrait;
     use CurdControllerTrait;
 
 
-    protected $bindModel = ProductModel::class;
+    protected $store;
+
+    protected $main_where = [];
+
+    public function initialize()
+    {
+        parent::initialize(); // TODO: Change the autogenerated stub
+        $store_id = $this->adminInfo['store_id'];
+        $this->store = SystemStore::where('id', $store_id)->find();
+        if ($this->store && $this->store['is_triple']) {
+            $this->main_where['store_id'] = $store_id;
+        }
+    }
 
 
     /**
     /**
-     * @return mixed
+     * 显示资金记录
      */
      */
     public function index()
     public function index()
     {
     {
-        $this->assign([
-            'year' => get_month(),
-            'real_name' => $this->request->get('real_name', ''),
-            'status' => $this->request->param('status', ''),
-            'orderCount' => StoreOrderModel::orderCount(),
-            'payTypeCount' => StoreOrderModel::payTypeCount(),
-        ]);
+        $list = StoreBill::where($this->main_where)
+            ->field(['title', 'type'])
+            ->group('type')
+            ->distinct(true)
+            ->select()
+            ->toArray();
+        if ($this->adminInfo['store_id'] > 0) {
+            $balance = SystemStore::where('id', $this->adminInfo['store_id'])->value('money');
+        }
+        $this->assign('selectList', $list);
+        $this->assign('balance', $balance ?? 0);
         return $this->fetch();
         return $this->fetch();
     }
     }
-    public function lst()
-    {
 
 
+    /**
+     * 显示资金记录ajax列表
+     */
+    public function billlist()
+    {
+        $where = Util::getMore([
+            ['start_time', ''],
+            ['end_time', ''],
+            ['nickname', ''],
+            ['limit', 20],
+            ['page', 1],
+            ['type', ''],
+        ]);
+        Json::successlayui(StoreBill::getBillList($where));
     }
     }
 
 
+    /**
+     * 添加/修改分组页面
+     * @param int $id
+     * @return string
+     */
+    public function extract($type = 'alipay')
+    {
+        $store_info = SystemStore::where('id', $this->adminInfo['store_id'])->find();
+        if (!$store_info) $this->failed('门店不存在');
+        $f = array();
+        $f[] = Form::number('money', '提现金额', '')->step(0.01)->max($store_info['money'])->min(0)->required();
+        $f[] = Form::hidden('extract_type', $type);
+        switch ($type) {
+            case 'alipay':
+                $f[] = Form::input('name', '姓名')->required();
+                $f[] = Form::input('alipay_code', '支付宝账号')->required();
+                break;
+            case 'bank':
+                $f[] = Form::input('name', '姓名')->required();
+                $f[] = Form::input('bankname', '开户行')->required();
+                $f[] = Form::input('cardnum', '银行卡号')->required();
+                break;
+            case 'weixin':
+                $f[] = Form::input('name', '姓名')->required();
+                $f[] = Form::input('weixin', '微信号')->required();
+                break;
+            default:
+                $this->failed('不允许的提现方式');
+                break;
+        }
+        $form = Form::make_post_form('申请提现', $f, Url::buildUrl('saveExtract'));
+        $this->assign(compact('form'));
+        return $this->fetch('public/form-builder');
+    }
 
 
-
+    /**
+     * 添加/修改
+     * @param int $id
+     */
+    public function saveExtract()
+    {
+        $store_info = SystemStore::where('id', $this->adminInfo['store_id'])->find();
+        if (!$store_info) Json::fail('门店不存在');
+        $data = UtilService::postMore([
+            ['alipay_code', ''],
+            ['extract_type', ''],
+            ['money', 0],
+            ['name', ''],
+            ['bankname', ''],
+            ['cardnum', ''],
+            ['weixin', ''],
+        ]);
+        if ($data['money'] > $store_info['money']) Json::fail('可提余额不足');
+        if (!$data['cardnum'] == '')
+            if (!preg_match('/^([1-9]{1})(\d{14}|\d{18})$/', $data['cardnum']))
+                Json::fail('银行卡号输入有误');
+        if (StoreExtract::userExtract($store_info, $data))
+            Json::success('申请提现成功!');
+        else
+            Json::fail(StoreExtract::getErrorInfo('提现失败'));
+    }
 
 
 }
 }

+ 191 - 0
app/admin/controller/finance/StoreExtract.php

@@ -0,0 +1,191 @@
+<?php
+/**
+ * Created by PhpStorm.
+ * User: lianghuan
+ * Date: 2018-03-03
+ * Time: 16:37
+ */
+
+namespace app\admin\controller\finance;
+
+use app\admin\controller\AuthController;
+use app\admin\model\wechat\WechatUser;
+use app\models\system\SystemStoreMember;
+use app\models\user\UserBill;
+use think\facade\Route as Url;
+use crmeb\services\JsonService;
+use app\admin\model\user\UserExtract as UserExtractModel;
+use crmeb\services\{UtilService as Util, FormBuilder as Form, WechatService};
+
+/**
+ * 用户提现管理
+ * Class UserExtract
+ * @package app\admin\controller\finance
+ */
+class StoreExtract extends AuthController
+{
+    public function index()
+    {
+        $where = Util::getMore([
+            ['status', ''],
+            ['nickname', ''],
+            ['extract_type', ''],
+            ['nireid', ''],
+            ['date', ''],
+        ], $this->request);
+        $limitTimeList = [
+            'today' => implode(' - ', [date('Y/m/d'), date('Y/m/d', strtotime('+1 day'))]),
+            'week' => implode(' - ', [
+                date('Y/m/d', (time() - ((date('w') == 0 ? 7 : date('w')) - 1) * 24 * 3600)),
+                date('Y-m-d', (time() + (7 - (date('w') == 0 ? 7 : date('w'))) * 24 * 3600))
+            ]),
+            'month' => implode(' - ', [date('Y/m') . '/01', date('Y/m') . '/' . date('t')]),
+            'quarter' => implode(' - ', [
+                date('Y') . '/' . (ceil((date('n')) / 3) * 3 - 3 + 1) . '/01',
+                date('Y') . '/' . (ceil((date('n')) / 3) * 3) . '/' . date('t', mktime(0, 0, 0, (ceil((date('n')) / 3) * 3), 1, date('Y')))
+            ]),
+            'year' => implode(' - ', [
+                date('Y') . '/01/01', date('Y/m/d', strtotime(date('Y') . '/01/01 + 1year -1 day'))
+            ])
+        ];
+        $this->assign('where', $where);
+        $this->assign('limitTimeList', $limitTimeList);
+        $this->assign(UserExtractModel::extractStatistics());
+        $this->assign(UserExtractModel::systemPage($where));
+        return $this->fetch();
+    }
+
+    public function edit($id)
+    {
+        if (!$id) return $this->failed('数据不存在');
+        $UserExtract = UserExtractModel::get($id);
+        if (!$UserExtract) return JsonService::fail('数据不存在!');
+        $f = array();
+        $f[] = Form::input('real_name', '姓名', $UserExtract['real_name']);
+        $f[] = Form::number('extract_price', '提现金额', $UserExtract['extract_price'])->precision(2);
+        if ($UserExtract['extract_type'] == 'alipay') {
+            $f[] = Form::input('alipay_code', '支付宝账号', $UserExtract['alipay_code']);
+        } else if ($UserExtract['extract_type'] == 'weixin') {
+            $f[] = Form::input('wechat', '微信号', $UserExtract['wechat']);
+        } else {
+            $f[] = Form::input('bank_code', '银行卡号', $UserExtract['bank_code']);
+            $f[] = Form::input('bank_address', '开户行', $UserExtract['bank_address']);
+        }
+        $f[] = Form::input('mark', '备注', $UserExtract['mark'])->type('textarea');
+        $form = Form::make_post_form('编辑', $f, Url::buildUrl('update', array('id' => $id)));
+        $this->assign(compact('form'));
+        return $this->fetch('public/form-builder');
+    }
+
+    public function update($id)
+    {
+        $UserExtract = UserExtractModel::get($id);
+        if (!$UserExtract) return JsonService::fail('数据不存在!');
+        if ($UserExtract['extract_type'] == 'alipay') {
+            $data = Util::postMore([
+                'real_name',
+                'mark',
+                'extract_price',
+                'alipay_code',
+            ]);
+            if (!$data['real_name']) return JsonService::fail('请输入姓名');
+            if ($data['extract_price'] <= -1) return JsonService::fail('请输入提现金额');
+            if (!$data['alipay_code']) return JsonService::fail('请输入支付宝账号');
+        } else if ($UserExtract['extract_type'] == 'weixin') {
+            $data = Util::postMore([
+                'real_name',
+                'mark',
+                'extract_price',
+                'wechat',
+            ]);
+//            if(!$data['real_name']) return JsonService::fail('请输入姓名');
+            if ($data['extract_price'] <= -1) return JsonService::fail('请输入提现金额');
+            if (!$data['wechat']) return JsonService::fail('请输入微信账号');
+        } else {
+            $data = Util::postMore([
+                'real_name',
+                'extract_price',
+                'mark',
+                'bank_code',
+                'bank_address',
+            ]);
+            if (!$data['real_name']) return JsonService::fail('请输入姓名');
+            if ($data['extract_price'] <= -1) return JsonService::fail('请输入提现金额');
+            if (!$data['bank_code']) return JsonService::fail('请输入银行卡号');
+            if (!$data['bank_address']) return JsonService::fail('请输入开户行');
+        }
+        if (!UserExtractModel::edit($data, $id))
+            return JsonService::fail(UserExtractModel::getErrorInfo('修改失败'));
+        else
+            return JsonService::successful('修改成功!');
+    }
+
+    public function fail($id)
+    {
+        if (!UserExtractModel::be(['id' => $id, 'status' => 0])) return JsonService::fail('操作记录不存在或状态错误!');
+        $fail_msg = request()->post();
+        $extract = UserExtractModel::get($id);
+        if (!$extract) return JsonService::fail('操作记录不存在!');
+        if ($extract->status == 1) return JsonService::fail('已经提现,错误操作');
+        if ($extract->status == -1) return JsonService::fail('您的提现申请已被拒绝,请勿重复操作!');
+        $res = UserExtractModel::changeFail($id, $fail_msg['message']);
+        if ($res) {
+            return JsonService::successful('操作成功!');
+        } else {
+            return JsonService::fail('操作失败!');
+        }
+    }
+
+    public function succ($id)
+    {
+        if (!UserExtractModel::be(['id' => $id, 'status' => 0]))
+            return JsonService::fail('操作记录不存在或状态错误!');
+        UserExtractModel::beginTrans();
+        $extract = UserExtractModel::get($id);
+        if (!$extract) return JsonService::fail('操作记录不存!');
+        if ($extract->status == 1) return JsonService::fail('您已提现,请勿重复提现!');
+        if ($extract->status == -1) return JsonService::fail('您的提现申请已被拒绝!');
+        $res = UserExtractModel::changeSuccess($id);
+        if ($extract['commission_consumer'] > 0) {
+            $res = $res && UserBill::income('提现转换(消费券)', $extract['uid'], 'consumer', 'extract_get_consumer', $extract['commission_consumer'], $extract['id'], \app\admin\model\user\User::where('uid', $extract['uid'])->value('consumer') + $extract['commission_consumer'], '提现申请通过,其中部分佣金转换为消费券' . $extract['commission_consumer']);
+            $res = $res && \app\admin\model\user\User::where('uid', $extract['uid'])->inc('consumer', $extract['commission_consumer'])->update();
+        }
+        if ($extract['commission_yue'] > 0) {
+            $res = $res && UserBill::income('提现转换(余额)', $extract['uid'], 'now_money', 'extract_get_now_money', $extract['commission_yue'], $extract['id'], \app\admin\model\user\User::where('uid', $extract['uid'])->value('now_money') + $extract['commission_yue'], '提现申请通过,其中部分佣金转换为余额' . $extract['commission_yue']);
+            $res = $res && \app\admin\model\user\User::where('uid', $extract['uid'])->inc('now_money', $extract['commission_yue'])->update();
+        }
+        if ($extract['commission_gf'] > 0) {
+            $res = $res && UserBill::income('提现转换(股份)', $extract['uid'], 'gf', 'extract_get_gf', $extract['commission_gf'], $extract['id'], \app\admin\model\user\User::where('uid', $extract['uid'])->value('gf') + $extract['commission_gf'], '提现申请通过,其中部分佣金转换为股份' . $extract['commission_gf']);
+            $res = $res && \app\admin\model\user\User::where('uid', $extract['uid'])->inc('gf', $extract['commission_gf'])->update();
+        }
+
+        $real_get = $extract['extract_price'] - $extract['commission_gf'] - $extract['commission_consumer'] - $extract['commission_yue'] - $extract['commission'];
+
+        if ($real_get >= 0.3 && $extract['extract_type'] == 'weixin') {
+            $open_id = WechatUser::where('uid', $extract['uid'])->find();
+            if ($open_id['openid']) {
+                try {
+                    WechatService::paymentService()->batches(
+                        'ex' . date('YmdHis') . $extract['id'],
+                        $open_id['openid'],
+                        $real_get * 100,
+                        sys_config('site_name') . '-' . '用户提现到账'
+                    );
+                } catch (\Exception $e) {
+                    UserExtractModel::rollbackTrans();
+                    return JsonService::fail($e->getMessage());
+                }
+            }
+        }
+//        if ($extract['commission_gf'] > 0 && SystemStoreMember::be(['uid' => $extract['uid']])) {
+//            $res = $res && SystemStoreMember::where('uid', $extract['uid'])->inc('consume_rights', $extract['commission_gf'])->update();
+//        }
+        if ($res) {
+            UserExtractModel::commitTrans();
+            return JsonService::successful('操作成功!');
+        } else {
+            UserExtractModel::rollbackTrans();
+            return JsonService::fail('操作失败!');
+        }
+    }
+}

+ 27 - 2
app/admin/model/system/StoreBill.php

@@ -1,10 +1,9 @@
 <?php
 <?php
 
 
-namespace app\admin\model\user;
+namespace app\admin\model\system;
 
 
 use crmeb\traits\ModelTrait;
 use crmeb\traits\ModelTrait;
 use crmeb\basic\BaseModel;
 use crmeb\basic\BaseModel;
-use think\facade\Db;
 
 
 /**
 /**
  * 用户消费新增金额明细 model
  * 用户消费新增金额明细 model
@@ -45,4 +44,30 @@ class StoreBill extends BaseModel
         $add_time = date("Y-m-d H:i:s");
         $add_time = date("Y-m-d H:i:s");
         return self::create(compact('title', 'store_id', 'link_id', 'type', 'number', 'balance', 'mark', 'pm', 'add_time', 'id'));
         return self::create(compact('title', 'store_id', 'link_id', 'type', 'number', 'balance', 'mark', 'pm', 'add_time', 'id'));
     }
     }
+
+    public static function getBillList($where)
+    {
+        $whereModel = self::setWhereList($where);
+        $count = $whereModel->count();
+        $data = ($data = $whereModel->page((int)$where['page'], (int)$where['limit'])->select()) && count($data) ? $data->toArray() : [];
+        return compact('data', 'count');
+    }
+
+    public static function setWhereList($where)
+    {
+        $time['data'] = '';
+        if ($where['start_time'] != '' && $where['end_time'] != '') {
+            $time['data'] = $where['start_time'] . ' - ' . $where['end_time'];
+        }
+        $model = self::getModelTime($time, self::alias('A')
+            ->join('system_store B', 'B.id=A.store_id')
+            ->order('A.add_time desc,A.id desc'), 'A.add_time');
+        if (trim($where['type']) != '') {
+            $model = $model->where('A.type', $where['type']);
+        }
+        if ($where['nickname'] != '') {
+            $model = $model->where('B.name|B.id', 'like', "%$where[nickname]%");
+        }
+        return $model->field(['A.*', 'A.add_time', 'B.id', 'B.name']);
+    }
 }
 }

+ 117 - 0
app/admin/model/system/StoreExtract.php

@@ -0,0 +1,117 @@
+<?php
+/**
+ *
+ * @author: xaboy<365615158@qq.com>
+ * @day: 2018/3/3
+ */
+
+namespace app\admin\model\system;
+
+use crmeb\basic\BaseModel;
+use crmeb\services\workerman\ChannelService;
+use crmeb\traits\ModelTrait;
+
+
+/**
+ * TODO 用户提现
+ * Class UserExtract
+ * @package app\models\user
+ */
+class StoreExtract extends BaseModel
+{
+    /**
+     * 数据表主键
+     * @var string
+     */
+    protected $pk = 'id';
+
+    /**
+     * 模型名称
+     * @var string
+     */
+    protected $name = 'store_extract';
+
+    use ModelTrait;
+
+    //审核中
+    const AUDIT_STATUS = 0;
+    //未通过
+    const FAIL_STATUS = -1;
+    //已提现
+    const SUCCESS_STATUS = 1;
+
+    protected static $extractType = ['alipay', 'bank', 'weixin'];
+
+    protected static $extractTypeMsg = ['alipay' => '支付宝', 'bank' => '银行卡', 'weixin' => '微信'];
+
+    protected static $status = array(
+        -1 => '未通过',
+        0 => '审核中',
+        1 => '已提现'
+    );
+
+    /**
+     * 用户自主提现记录提现记录,后台执行审核
+     * @param array $userInfo 用户个人信息
+     * @param array $data 提现详细信息
+     * @return bool
+     */
+    public static function userExtract($userInfo, $data)
+    {
+        if (!in_array($data['extract_type'], self::$extractType))
+            return self::setErrorInfo('提现方式不存在');
+        $userInfo = SystemStore::get($userInfo['id']);
+        $extractPrice = $userInfo['money'];
+        if ($extractPrice < 0) return self::setErrorInfo('提现余额不足' . $data['money']);
+        if ($data['money'] > $extractPrice) return self::setErrorInfo('提现余额不足' . $data['money']);
+        if ($data['money'] <= 0) return self::setErrorInfo('提现余额大于0');
+        $balance = bcsub($userInfo['money'], $data['money'], 2);
+        $commission = bcmul($data['money'], bcdiv(sys_config('store_commission', 0, true), 100, 3), 2);
+        if ($balance < 0) $balance = 0;
+        $insertData = [
+            'uid' => $userInfo['uid'],
+            'extract_type' => $data['extract_type'],
+            'extract_price' => $data['money'],
+            'add_time' => time(),
+            'balance' => $balance,
+            'status' => self::AUDIT_STATUS,
+            'commission' => $commission,
+        ];
+        if (isset($data['name']) && strlen(trim($data['name']))) $insertData['real_name'] = $data['name'];
+        else $insertData['real_name'] = $userInfo['nickname'];
+        if (isset($data['cardnum'])) $insertData['bank_code'] = $data['cardnum'];
+        else $insertData['bank_code'] = '';
+        if (isset($data['bankname'])) $insertData['bank_address'] = $data['bankname'];
+        else $insertData['bank_address'] = '';
+        if (isset($data['weixin'])) $insertData['wechat'] = $data['weixin'];
+        else $insertData['wechat'] = $userInfo['nickname'];
+        if ($data['extract_type'] == 'alipay') {
+            if (!$data['alipay_code']) return self::setErrorInfo('请输入支付宝账号');
+            $insertData['alipay_code'] = $data['alipay_code'];
+            $mark = '使用支付宝提现' . $insertData['extract_price'] . '元,手续费:' . $insertData['commission'] . ",实际到账:" . bcsub($insertData['extract_price'], $insertData['commission'], 2);
+        } else if ($data['extract_type'] == 'bank') {
+            if (!$data['cardnum']) return self::setErrorInfo('请输入银行卡账号');
+            if (!$data['bankname']) return self::setErrorInfo('请输入开户行信息');
+            $mark = '使用银联卡' . $insertData['bank_code'] . '提现' . $insertData['extract_price'] . '元,手续费:' . $insertData['commission'] . ",实际到账:" . bcsub($insertData['extract_price'], $insertData['commission'], 2);
+        } else {
+            if (!$data['weixin']) return self::setErrorInfo('请输入微信账号');
+            $mark = '使用微信提现' . $insertData['extract_price'] . '元';
+        }
+        self::beginTrans();
+        try {
+            $res1 = self::create($insertData);
+            if (!$res1) return self::setErrorInfo('提现失败');
+            $res2 = SystemStore::edit(['money' => $balance], $userInfo['id'], 'id');
+            $res3 = StoreBill::expend('提现', $userInfo['id'], 'extract', $data['money'], $res1['id'], $balance, $mark);
+            $res = $res2 && $res3;
+            if ($res) {
+                self::commitTrans();
+                //发送模板消息
+                return true;
+            } else return self::setErrorInfo('提现失败!');
+        } catch (\Exception $e) {
+            self::rollbackTrans();
+            return self::setErrorInfo('提现失败!');
+        }
+    }
+}

+ 144 - 0
app/admin/view/company/finance/index.php

@@ -0,0 +1,144 @@
+{extend name="public/container"}
+{block name="content"}
+<div class="layui-fluid">
+    <div class="layui-row layui-col-space15" id="app">
+        <div class="layui-col-md12">
+            <div class="layui-card">
+                <div class="layui-card-header">搜索条件</div>
+                <div class="layui-card-body">
+                    <form class="layui-form layui-form-pane" action="">
+                        <div class="layui-form-item">
+                            <div class="layui-inline">
+                                <label class="layui-form-label">店铺名称/ID</label>
+                                <div class="layui-input-block">
+                                    <input type="text" name="nickname" class="layui-input">
+                                </div>
+                            </div>
+                            <!--                            <div class="layui-inline">-->
+                            <!--                                <label class="layui-form-label">时间范围</label>-->
+                            <!--                                <div class="layui-input-inline" style="width: 200px;">-->
+                            <!--                                    <input type="text" name="start_time" placeholder="开始时间" id="start_time" class="layui-input">-->
+                            <!--                                </div>-->
+                            <!--                                <div class="layui-form-mid">-</div>-->
+                            <!--                                <div class="layui-input-inline" style="width: 200px;">-->
+                            <!--                                    <input type="text" name="end_time" placeholder="结束时间" id="end_time" class="layui-input">-->
+                            <!--                                </div>-->
+                            <!--                            </div>-->
+                            <div class="layui-inline">
+                                <label class="layui-form-label">筛选类型</label>
+                                <div class="layui-input-block">
+                                    <select name="type">
+                                        <option value=" ">全部</option>
+                                        {volist name='selectList' id='val'}
+                                        <option value="{$val.type}">{$val.title}</option>
+                                        {/volist}
+                                    </select>
+                                </div>
+                            </div>
+                            <div class="layui-inline">
+                                <div class="layui-input-inline" style="width: auto">
+                                    <button class="layui-btn layui-btn-sm layui-btn-normal" lay-submit="search"
+                                            lay-filter="search">
+                                        <i class="layui-icon layui-icon-search"></i>搜索
+                                    </button>
+                                    {gt name="balance" value="0"}
+                                    <button class="layui-btn layui-btn-primary layui-btn-sm"
+                                            lay-submit="extract"
+                                            lay-filter="extract">
+                                        余额:{$balance} - 提现
+                                    </button>
+                                    {/gt}
+                                    <!--                                    <button class="layui-btn layui-btn-primary layui-btn-sm export"  lay-submit="export" lay-filter="export">-->
+                                    <!--                                        <i class="fa fa-floppy-o" style="margin-right: 3px;"></i>导出</button>-->
+                                </div>
+                            </div>
+                        </div>
+                    </form>
+                </div>
+            </div>
+        </div>
+        <div class="layui-col-md12">
+            <div class="layui-card">
+                <div class="layui-card-header">店铺资金监控日志</div>
+                <div class="layui-card-body">
+                    <table class="layui-hide" id="userList" lay-filter="userList"></table>
+                    <script type="text/html" id="number">
+                        {{#  if(d.pm ==0 && d.type !='share'){ }}
+                        <span style="color:#FF5722">-{{d.number}}</span>
+                        {{# }else if(d.pm && d.type != 'share'){ }}
+                        <span style="color:#009688">{{d.number}}</span>
+                        {{# }else{ }}
+                        <span style="color:#009688">0</span>
+                        {{# } }}
+                    </script>
+                    <script type="text/html" id="status">
+                        {{#  if(d.status ==0 ){ }}
+                        <span style="color:#FF5722">待发放</span>
+                        {{# }else{ }}
+                        <span style="color:#009688">已发放</span>
+                        {{# } }}
+                    </script>
+                </div>
+            </div>
+        </div>
+    </div>
+</div>
+<script src="{__ADMIN_PATH}js/layuiList.js"></script>
+<script>
+    layList.form.render();
+    layList.date({elem: '#start_time', theme: '#393D49', type: 'datetime'});
+    layList.date({elem: '#end_time', theme: '#393D49', type: 'datetime'});
+    layList.tableList('userList', "{:Url('billlist')}", function () {
+        return [
+            {field: 'id', title: 'ID', sort: true, event: 'id', align: "center", width: "10%"},
+            {field: 'name', title: '店铺名', align: "center", width: "16%"},
+            {field: 'number', title: '金额', sort: true, templet: '#number', align: "center", width: "10%"},
+            {field: 'title', title: '类型', align: "center", width: "10%"},
+            {field: 'mark', title: '备注', align: "center"},
+            // {field: 'status', title: '状态',templet:'#status',align:"center"},
+            {field: 'add_time', title: '创建时间', align: "center", width: "16%"},
+        ];
+    });
+    layList.search('search', function (where) {
+        if (where.start_time != '') {
+            if (where.end_time == '') {
+                layList.msg('请选择结束时间');
+                return;
+            }
+        }
+        if (where.end_time != '') {
+            if (where.start_time == '') {
+                layList.msg('请选择开始时间');
+                return;
+            }
+        }
+        layList.reload(where, true);
+    });
+    layList.search('export', function (where) {
+        location.href = layList.U({
+            a: 'save_bell_export',
+            q: {type: where.type, start_time: where.start_time, end_time: where.end_time, nickname: where.nickname}
+        });
+    });
+    layList.search('extract', function () {
+        layer.open({
+            title: '请选择提现方式',
+            formType: 0,
+            content: "<select id='extract_type' class='layui-input'>" +
+                "<option value='alipay'>支付宝</option>" +
+                "<option value='bank'>银行卡</option>" +
+                "<option value='weixin'>微信</option>" +
+                "</select>",
+            yes: function (index) {
+                var extract_type = $('#extract_type').val();
+                layer.close(index);
+                $eb.createModalFrame('提现', layList.U({a: 'extract', q: {type: extract_type}}), {
+                    h: 550,
+                    w: 720
+                },
+                );
+            }
+        });
+    });
+</script>
+{/block}

+ 339 - 0
app/admin/view/finance/store_extract/index.php

@@ -0,0 +1,339 @@
+{extend name="public/container"}
+{block name="head_top"}
+<link rel="stylesheet" href="{__PLUG_PATH}daterangepicker/daterangepicker.css">
+<script src="{__PLUG_PATH}moment.js"></script>
+<script src="{__PLUG_PATH}daterangepicker/daterangepicker.js"></script>
+{/block}
+{block name="content"}
+<div class="row">
+    <div class="col-sm-12">
+        <div class="ibox">
+            <div class="ibox-content">
+                <div class="row">
+                    <div class="m-b m-l">
+                        <form action="" class="form-inline">
+                            <div class="search-item" data-name="date">
+                                <span>选择时间:</span>
+                                <button type="button" class="btn btn-outline btn-link" data-value="">全部</button>
+                                <button type="button" class="btn btn-outline btn-link"
+                                        data-value="{$limitTimeList.today}">今天
+                                </button>
+                                <button type="button" class="btn btn-outline btn-link"
+                                        data-value="{$limitTimeList.week}">本周
+                                </button>
+                                <button type="button" class="btn btn-outline btn-link"
+                                        data-value="{$limitTimeList.month}">本月
+                                </button>
+                                <button type="button" class="btn btn-outline btn-link"
+                                        data-value="{$limitTimeList.quarter}">本季度
+                                </button>
+                                <button type="button" class="btn btn-outline btn-link"
+                                        data-value="{$limitTimeList.year}">本年
+                                </button>
+                                <div class="datepicker" style="display: inline-block;">
+                                    <button type="button" class="btn btn-outline btn-link"
+                                            data-value="{$where.date?:'no'}">自定义时间
+                                    </button>
+                                </div>
+                                <input class="search-item-value" type="hidden" name="date" value="{$where.date}"/>
+                            </div>
+                            <select name="status" aria-controls="editable" class="form-control input-sm">
+                                <option value="">提现状态</option>
+                                <option value="-1" {eq name="where.status" value="-1" }selected="selected" {
+                                /eq}>未通过</option>
+                                <option value="0" {eq name="where.status" value="0" }selected="selected" {
+                                /eq}>未提现</option>
+                                <option value="1" {eq name="where.status" value="1" }selected="selected" {
+                                /eq}>已通过</option>
+                            </select>
+                            <select name="extract_type" class="form-control input-sm">
+                                <option value="">提现方式</option>
+                                <option value="alipay" {eq name="where.extract_type" value="alipay" }selected="selected"
+                                        {
+                                /eq}>支付宝</option>
+                                <option value="bank" {eq name="where.extract_type" value="bank" }selected="selected" {
+                                /eq}>银行卡</option>
+                                <option value="weixin" {eq name="where.extract_type" value="weixin" }selected="selected"
+                                        {
+                                /eq}>微信</option>
+                            </select>
+                            <div class="input-group">
+                                  <span class="input-group-btn">
+                                      <input type="text" name="nireid" value="{$where.nireid}"
+                                             placeholder="微信昵称/姓名/支付宝账号/银行卡号" class="input-sm form-control" size="38"/>
+                                      <button type="submit" class="btn btn-sm btn-primary"> 搜索</button>
+                                  </span>
+                            </div>
+                        </form>
+                    </div>
+                    <div class="col-sm-3 ui-sortable">
+                        <div class="ibox float-e-margins">
+                            <div class="ibox-title">
+                                <span class="label label-success pull-right">¥</span>
+                                <h5>已提现金额</h5>
+                            </div>
+                            <div class="ibox-content">
+                                <h1 class="no-margins">{$data.priced}</h1>
+                            </div>
+                        </div>
+                    </div>
+                    <div class="col-sm-3 ui-sortable">
+                        <div class="ibox float-e-margins">
+                            <div class="ibox-title">
+                                <span class="label label-danger pull-right">急</span>
+                                <h5>待提现金额</h5>
+                            </div>
+                            <div class="ibox-content">
+                                <h1 class="no-margins">{$data.price}</h1>
+                            </div>
+                        </div>
+                    </div>
+                    <div class="col-sm-3 ui-sortable">
+                        <div class="ibox float-e-margins">
+                            <div class="ibox-title">
+                                <span class="label label-success pull-right">待</span>
+                                <h5>佣金总金额</h5>
+                            </div>
+                            <div class="ibox-content">
+                                <h1 class="no-margins">{$data.brokerage_count}</h1>
+                            </div>
+                        </div>
+                    </div>
+                    <div class="col-sm-3 ui-sortable">
+                        <div class="ibox float-e-margins">
+                            <div class="ibox-title">
+                                <span class="label label-success pull-right">待</span>
+                                <h5>未提现金额</h5>
+                            </div>
+                            <div class="ibox-content">
+                                <h1 class="no-margins">{$data.brokerage_not}</h1>
+                            </div>
+                        </div>
+                    </div>
+                </div>
+                <div class="table-responsive">
+                    <table class="table table-striped  table-bordered">
+                        <thead>
+                        <tr>
+                            <th class="text-center">编号</th>
+                            <th class="text-center">用户信息</th>
+                            <th class="text-center">提现金额</th>
+                            <th class="text-center">提现来源</th>
+                            <th class="text-center">提现方式</th>
+                            <th class="text-center">添加时间</th>
+                            <th class="text-center">备注</th>
+                            <th class="text-center">审核状态</th>
+                            <th class="text-center">操作</th>
+                        </tr>
+                        </thead>
+                        <tbody class="">
+                        {volist name="list" id="vo"}
+                        <tr>
+                            <td class="text-center">
+                                {$vo.id}
+                            </td>
+                            <td class="text-center">
+                                用户昵称: {$vo.nickname}/用户id:{$vo.uid}
+                            </td>
+                            <td class="text-center" style="color: #00aa00;">
+                                提现金额:{$vo.extract_price}<br>
+                                转换股份:{$vo.commission_gf}<br>
+                                转消费券:{$vo.commission_consumer}<br>
+                                转换余额:{$vo.commission_yue}<br>
+                                手 续 费:{$vo.commission}<br>
+                                实际到账:{$vo.extract_price-$vo.commission_gf-$vo.commission_consumer-$vo.commission_yue-$vo.commission}<br>
+                            </td>
+                            <td class="text-center" style="color: #00aa00;">
+                                {if condition="$vo['from'] eq 'brokerage_price'"}
+                                佣金
+                                {else/}
+                                余额
+                                {/if}
+                            </td>
+                            <td class="text-left">
+                                {if condition="$vo['extract_type'] eq 'bank'"}
+                                姓名:{$vo.real_name}<br>
+                                银行卡号:{$vo.bank_code}
+                                <br/>
+                                银行名称:{$vo.bank_address}
+                                {elseif condition="$vo['extract_type'] eq 'weixin'"/}
+                                微信昵称:{$vo.nickname}<br>
+<!--                                微信号:{$vo.wechat}-->
+                                {elseif condition="$vo['extract_type'] eq 'balance'"/}
+                                转余额
+                                {else/}
+                                姓名:{$vo.real_name}<br>
+                                支付宝号:{$vo.alipay_code}
+                                {/if}
+                            </td>
+                            <td class="text-center">
+                                {$vo.add_time|date='Y-m-d H:i:s'}
+                            </td>
+                            <td class="text-center">
+                                {$vo.mark}
+                            </td>
+                            <td class="text-center">
+                                {if condition="$vo['status'] eq 1"}
+                                提现通过<br/>
+                                {elseif condition="$vo['status'] eq -1"/}
+                                提现未通过<br/>
+                                未通过原因:{$vo.fail_msg}
+                                <br>
+                                未通过时间:{$vo.fail_time|date='Y-m-d H:i:s'}
+                                {else/}
+                                未提现<br/>
+                                <button data-url="{:url('fail',['id'=>$vo['id']])}" class="j-fail btn btn-danger btn-xs"
+                                        type="button"><i class="fa fa-close"></i> 无效
+                                </button>
+                                <button data-url="{:url('succ',['id'=>$vo['id']])}"
+                                        class="j-success btn btn-primary btn-xs" type="button"><i
+                                            class="fa fa-check"></i> 通过
+                                </button>
+                                {/if}
+                            </td>
+                            <td class="text-center">
+                                <button class="btn btn-info btn-xs" type="button"
+                                        onclick="$eb.createModalFrame('编辑','{:Url('edit',array('id'=>$vo['id']))}')"><i
+                                            class="fa fa-edit"></i> 编辑
+                                </button>
+                            </td>
+                        </tr>
+                        {/volist}
+                        </tbody>
+                    </table>
+                </div>
+                {include file="public/inner_page"}
+            </div>
+        </div>
+    </div>
+</div>
+{/block}
+{block name="script"}
+<script>
+    $(function init() {
+        $('.search-item>.btn').on('click', function () {
+            var that = $(this), value = that.data('value'), p = that.parent(), name = p.data('name'),
+                form = p.parents();
+            form.find('input[name="' + name + '"]').val(value);
+            $('input[name=export]').val(0);
+            form.submit();
+        });
+        $('.tag-item>.btn').on('click', function () {
+            var that = $(this), value = that.data('value'), p = that.parent(), name = p.data('name'),
+                form = p.parents(), list = $('input[name="' + name + '"]').val().split(',');
+            var bool = 0;
+            $.each(list, function (index, item) {
+                if (item == value) {
+                    bool = 1
+                    list.splice(index, 1);
+                }
+            })
+            if (!bool) list.push('' + value + '');
+            form.find('input[name="' + name + '"]').val(list.join(','));
+            $('input[name=export]').val(0);
+            form.submit();
+        });
+        $('.search-item>li').on('click', function () {
+            var that = $(this), value = that.data('value'), p = that.parent(), name = p.data('name'), form = $('#form');
+            form.find('input[name="' + name + '"]').val(value);
+            $('input[name=export]').val(0);
+            form.submit();
+        });
+        $('.search-item>li').each(function () {
+            var that = $(this), value = that.data('value'), p = that.parent(), name = p.data('name');
+            if ($where[name]) $('.' + name).css('color', '#1ab394');
+        });
+        $('.search-item-value').each(function () {
+            var that = $(this), name = that.attr('name'), value = that.val(),
+                dom = $('.search-item[data-name="' + name + '"] .btn[data-value="' + value + '"]');
+            dom.eq(0).removeClass('btn-outline btn-link').addClass('btn-primary btn-sm')
+                .siblings().addClass('btn-outline btn-link').removeClass('btn-primary btn-sm')
+        });
+    })
+    $('.j-fail').on('click', function () {
+        var url = $(this).data('url');
+        $eb.$alert('textarea', {
+            title: '请输入未通过原因',
+            value: '输入信息不完整或有误!',
+        }, function (value) {
+            $eb.axios.post(url, {message: value}).then(function (res) {
+                if (res.data.code == 200) {
+                    $eb.$swal('success', res.data.msg);
+                    setTimeout(function () {
+                        window.location.reload();
+                    }, 1000);
+                } else
+                    $eb.$swal('error', res.data.msg || '操作失败!');
+            });
+        });
+    });
+    $('.j-success').on('click', function () {
+        var url = $(this).data('url');
+        $eb.$swal('delete', function () {
+            $eb.axios.post(url).then(function (res) {
+                if (res.data.code == 200) {
+                    setTimeout(function () {
+                        window.location.reload();
+                    }, 1000);
+                    $eb.$swal('success', res.data.msg);
+                } else
+                    $eb.$swal('error', res.data.msg || '操作失败!');
+            });
+        }, {
+            title: '确定审核通过?',
+            text: '通过后无法撤销,请谨慎操作!',
+            confirm: '审核通过'
+        });
+    });
+    $('.btn-warning').on('click', function () {
+        window.t = $(this);
+        var _this = $(this), url = _this.data('url');
+        $eb.$swal('delete', function () {
+            $eb.axios.get(url).then(function (res) {
+                if (res.status == 200 && res.data.code == 200) {
+                    $eb.$swal('success', res.data.msg);
+                    _this.parents('tr').remove();
+                } else
+                    return Promise.reject(res.data.msg || '删除失败')
+            }).catch(function (err) {
+                $eb.$swal('error', err);
+            });
+        })
+    });
+    $(".open_image").on('click', function (e) {
+        var image = $(this).data('image');
+        $eb.openImage(image);
+    })
+    var dateInput = $('.datepicker');
+    dateInput.daterangepicker({
+        autoUpdateInput: false,
+        "opens": "center",
+        "drops": "down",
+        "ranges": {
+            '今天': [moment(), moment().add(1, 'days')],
+            '昨天': [moment().subtract(1, 'days'), moment()],
+            '上周': [moment().subtract(6, 'days'), moment()],
+            '前30天': [moment().subtract(29, 'days'), moment()],
+            '本月': [moment().startOf('month'), moment().endOf('month')],
+            '上月': [moment().subtract(1, 'month').startOf('month'), moment().subtract(1, 'month').endOf('month')]
+        },
+        "locale": {
+            applyLabel: '确定',
+            cancelLabel: '取消',
+            fromLabel: '起始时间',
+            toLabel: '结束时间',
+            format: 'YYYY/MM/DD',
+            customRangeLabel: '自定义',
+            daysOfWeek: ['日', '一', '二', '三', '四', '五', '六'],
+            monthNames: ['一月', '二月', '三月', '四月', '五月', '六月',
+                '七月', '八月', '九月', '十月', '十一月', '十二月'],
+            firstDay: 1
+        }
+    });
+    dateInput.on('apply.daterangepicker', function (ev, picker) {
+        $("input[name=date]").val(picker.startDate.format('YYYY/MM/DD') + ' - ' + picker.endDate.format('YYYY/MM/DD'));
+        $('form').submit();
+    });
+</script>
+{/block}
+

+ 4 - 4
app/models/store/StoreProduct.php

@@ -626,20 +626,20 @@ class StoreProduct extends BaseModel
         }
         }
 
 
         foreach ($sumProductPrice as $k => $v) {
         foreach ($sumProductPrice as $k => $v) {
-            $sumProductPrice[$k] = bcsub($sumProductPrice[$k], $oneBrokerage[$k], 2);
-            $sumProductPrice[$k] = bcsub($sumProductPrice[$k], $twoBrokerage[$k], 2);
+            $sumProductPrice[$k] = bcsub($sumProductPrice[$k], $oneBrokerage[$k] ?? 0, 2);
+            $sumProductPrice[$k] = bcsub($sumProductPrice[$k], $twoBrokerage[$k] ?? 0, 2);
             $storeBrokerageRatio = sys_config('store_brokerage_ratio');
             $storeBrokerageRatio = sys_config('store_brokerage_ratio');
             //一级返佣比例 小于等于零时直接返回 不返佣
             //一级返佣比例 小于等于零时直接返回 不返佣
             if ($storeBrokerageRatio > 0) {
             if ($storeBrokerageRatio > 0) {
                 $brokerageRatio = bcdiv($storeBrokerageRatio, 100, 2);
                 $brokerageRatio = bcdiv($storeBrokerageRatio, 100, 2);
-                $brokeragePrice = bcmul($sumProductPriceBrokerage[$k], $brokerageRatio, 2);
+                $brokeragePrice = bcmul($sumProductPriceBrokerage[$k] ?? 0, $brokerageRatio, 2);
                 $sumProductPrice[$k] = bcsub($sumProductPrice[$k], $brokeragePrice, 2);
                 $sumProductPrice[$k] = bcsub($sumProductPrice[$k], $brokeragePrice, 2);
             }
             }
             $storeBrokerageTwo = sys_config('store_brokerage_two');
             $storeBrokerageTwo = sys_config('store_brokerage_two');
             //二级返佣比例小于等于0 直接返回
             //二级返佣比例小于等于0 直接返回
             if ($storeBrokerageTwo > 0) {
             if ($storeBrokerageTwo > 0) {
                 $brokerageRatio = bcdiv($storeBrokerageTwo, 100, 2);
                 $brokerageRatio = bcdiv($storeBrokerageTwo, 100, 2);
-                $brokeragePrice = bcmul($sumProductPriceBrokerage[$k], $brokerageRatio, 2);
+                $brokeragePrice = bcmul($sumProductPriceBrokerage[$k] ?? 0, $brokerageRatio, 2);
                 $sumProductPrice[$k] = bcsub($sumProductPrice[$k], $brokeragePrice, 2);
                 $sumProductPrice[$k] = bcsub($sumProductPrice[$k], $brokeragePrice, 2);
             }
             }
         }
         }

+ 23 - 16
app/models/user/User.php

@@ -3,12 +3,13 @@
 
 
 namespace app\models\user;
 namespace app\models\user;
 
 
-use app\admin\model\user\StoreBill;
+use app\admin\model\system\StoreBill;
 use app\models\store\StoreOrder;
 use app\models\store\StoreOrder;
 use app\models\store\StoreProduct;
 use app\models\store\StoreProduct;
 use app\models\system\SystemStore;
 use app\models\system\SystemStore;
 use app\models\system\SystemStoreMember;
 use app\models\system\SystemStoreMember;
 use crmeb\services\SystemConfigService;
 use crmeb\services\SystemConfigService;
+use think\Exception;
 use think\facade\Db;
 use think\facade\Db;
 use think\facade\Log;
 use think\facade\Log;
 use think\facade\Session;
 use think\facade\Session;
@@ -364,24 +365,30 @@ class User extends BaseModel
         $cartId = is_string($orderInfo['cart_id']) ? json_decode($orderInfo['cart_id'], true) : $orderInfo['cart_id'];
         $cartId = is_string($orderInfo['cart_id']) ? json_decode($orderInfo['cart_id'], true) : $orderInfo['cart_id'];
         $brokeragePrice = StoreProduct::getStoreProductPrice($cartId);
         $brokeragePrice = StoreProduct::getStoreProductPrice($cartId);
         //TODO 返佣金额小于等于0 直接返回不返佣金
         //TODO 返佣金额小于等于0 直接返回不返佣金
+//        var_dump($brokeragePrice);
         if (!count($brokeragePrice)) return true;
         if (!count($brokeragePrice)) return true;
         SystemStore::beginTrans();
         SystemStore::beginTrans();
-        $res = true;
-        foreach ($brokeragePrice as $k => $v) {
-            $store_info = SystemStore::get($k);
-            if ($store_info && $store_info['is_triple'] && $v > 0) {
-                $balance = bcadd($store_info['money'], $v, 2);
-                $mark = '订单【' . $orderInfo['order_id'] . '】内,存在店铺商品,扣除佣金后获得销售额' . $v . '元';
-                $res1 = StoreBill::income('商品销售额', $store_info['id'], 'product_sale', $v, $orderInfo['id'], $balance, $mark);
-                $res2 = SystemStore::bcInc($store_info['id'], 'money', $v, 'id');
-                $res = $res && $res1 && $res2;
+        try {
+            $res = true;
+            foreach ($brokeragePrice as $k => $v) {
+                $store_info = SystemStore::get($k);
+                if ($store_info && $store_info['is_triple'] && $v > 0) {
+                    $balance = bcadd($store_info['money'], $v, 2);
+                    $mark = '订单【' . $orderInfo['order_id'] . '】内,存在店铺商品,扣除佣金后获得销售额' . $v . '元';
+                    $res1 = StoreBill::income('商品销售额', $store_info['id'], 'product_sale', $v, $orderInfo['id'], $balance, $mark);
+                    $res2 = SystemStore::bcInc($store_info['id'], 'money', $v, 'id');
+                    $res = $res && $res1 && $res2;
+                }
             }
             }
-        }
-        self::checkTrans($res);
-        if ($res) {
-            return true;
-        } else {
-            return self::setErrorInfo('销售额发放失败');
+            SystemStore::checkTrans($res);
+            if ($res) {
+                return true;
+            } else {
+                return self::setErrorInfo('销售额发放失败');
+            }
+        } catch (Exception $e) {
+            SystemStore::rollbackTrans();
+            return self::setErrorInfo($e->getMessage());
         }
         }
     }
     }