浏览代码

更新2.6.13版本

liaofei 6 年之前
父节点
当前提交
61a5e38f3c
共有 100 个文件被更改,包括 6287 次插入1691 次删除
  1. 9 9
      application/admin/common.php
  2. 18 13
      application/admin/controller/Index.php
  3. 229 37
      application/admin/controller/agent/AgentManage.php
  4. 33 46
      application/admin/controller/article/Article.php
  5. 6 7
      application/admin/controller/article/ArticleCategory.php
  6. 5 108
      application/admin/controller/finance/Finance.php
  7. 4 2
      application/admin/controller/finance/UserExtract.php
  8. 25 8
      application/admin/controller/finance/UserRecharge.php
  9. 95 21
      application/admin/controller/order/StoreOrder.php
  10. 1 1
      application/admin/controller/record/StoreStatistics.php
  11. 11 17
      application/admin/controller/setting/SystemGroupData.php
  12. 83 44
      application/admin/controller/setting/SystemMenus.php
  13. 885 0
      application/admin/controller/store/CopyTaobao.php
  14. 10 11
      application/admin/controller/store/StoreCategory.php
  15. 11 13
      application/admin/controller/store/StoreProduct.php
  16. 17 14
      application/admin/controller/system/SystemAttachment.php
  17. 2 0
      application/admin/controller/system/SystemDatabackup.php
  18. 16 17
      application/admin/controller/ump/StoreSeckill.php
  19. 204 4
      application/admin/controller/user/User.php
  20. 5 3
      application/admin/controller/user/UserLevel.php
  21. 1 0
      application/admin/controller/user/UserNotice.php
  22. 5 2
      application/admin/controller/wechat/Reply.php
  23. 8 7
      application/admin/controller/wechat/StoreService.php
  24. 77 42
      application/admin/controller/widget/Images.php
  25. 29 1
      application/admin/model/article/ArticleCategory.php
  26. 138 37
      application/admin/model/order/StoreOrder.php
  27. 76 13
      application/admin/model/store/StoreProduct.php
  28. 6 1
      application/admin/model/store/StoreProductAttrValue.php
  29. 59 11
      application/admin/model/system/SystemAttachment.php
  30. 13 6
      application/admin/model/system/SystemAttachmentCategory.php
  31. 13 1
      application/admin/model/system/SystemConfig.php
  32. 1 0
      application/admin/model/system/SystemUserLevel.php
  33. 17 7
      application/admin/model/ump/StoreSeckill.php
  34. 77 23
      application/admin/model/user/User.php
  35. 9 1
      application/admin/model/user/UserBill.php
  36. 85 23
      application/admin/model/user/UserExtract.php
  37. 21 5
      application/admin/model/user/UserLevel.php
  38. 1 1
      application/admin/model/user/UserRecharge.php
  39. 3 1
      application/admin/model/wechat/WechatReply.php
  40. 465 79
      application/admin/model/wechat/WechatUser.php
  41. 338 569
      application/admin/view/agent/agent_manage/index.php
  42. 190 37
      application/admin/view/agent/agent_manage/stair.php
  43. 206 0
      application/admin/view/agent/agent_manage/stair_order.php
  44. 1 1
      application/admin/view/article/article/create.php
  45. 6 4
      application/admin/view/finance/finance/commission_list.php
  46. 3 17
      application/admin/view/index/index.php
  47. 11 9
      application/admin/view/index/main.php
  48. 56 24
      application/admin/view/order/store_order/index.php
  49. 93 0
      application/admin/view/order/store_order/order_goods.php
  50. 90 2
      application/admin/view/public/edit_content.php
  51. 4 2
      application/admin/view/public/form-builder.php
  52. 2 2
      application/admin/view/record/record/chart_order.php
  53. 1 1
      application/admin/view/setting/system_group/create.php
  54. 314 0
      application/admin/view/store/copy_taobao/index.php
  55. 2 1
      application/admin/view/store/store_product/attr.php
  56. 11 8
      application/admin/view/store/store_product/index.php
  57. 38 5
      application/admin/view/store/store_product_reply/index.php
  58. 7 1
      application/admin/view/system/system_databackup/index.php
  59. 109 11
      application/admin/view/user/user/index.php
  60. 1 1
      application/admin/view/user/user_level/index.php
  61. 2 2
      application/admin/view/wechat/menus/index.php
  62. 386 98
      application/admin/view/widget/images.php
  63. 9 0
      application/core/behavior/UserBehavior.php
  64. 2 5
      application/core/model/ApiMenus.php
  65. 22 23
      application/core/model/system/SystemUserTask.php
  66. 9 0
      application/core/model/user/User.php
  67. 11 2
      application/core/model/user/UserBill.php
  68. 11 7
      application/core/model/user/UserLevel.php
  69. 34 1
      application/core/model/user/UserTaskFinish.php
  70. 2 0
      application/core/traits/LogicTrait.php
  71. 12 14
      application/core/util/MiniProgramService.php
  72. 5 1
      application/core/util/ProgramTemplateService.php
  73. 1 1
      application/ebapi/controller/ApiException.php
  74. 2 2
      application/ebapi/controller/AuthApi.php
  75. 288 0
      application/ebapi/controller/BargainApi.php
  76. 10 4
      application/ebapi/controller/Basic.php
  77. 204 0
      application/ebapi/controller/PinkApi.php
  78. 28 21
      application/ebapi/controller/PublicApi.php
  79. 4 2
      application/ebapi/controller/SeckillApi.php
  80. 27 12
      application/ebapi/controller/StoreApi.php
  81. 57 23
      application/ebapi/controller/UserApi.php
  82. 194 0
      application/ebapi/model/store/StoreBargain.php
  83. 14 4
      application/ebapi/model/store/StoreCart.php
  84. 1 0
      application/ebapi/model/store/StoreCategory.php
  85. 187 0
      application/ebapi/model/store/StoreCombination.php
  86. 7 2
      application/ebapi/model/store/StoreCouponIssue.php
  87. 227 41
      application/ebapi/model/store/StoreOrder.php
  88. 2 2
      application/ebapi/model/store/StorePink.php
  89. 61 11
      application/ebapi/model/store/StoreProduct.php
  90. 6 2
      application/ebapi/model/store/StoreSeckill.php
  91. 102 30
      application/ebapi/model/user/User.php
  92. 16 3
      application/ebapi/model/user/UserExtract.php
  93. 10 4
      application/ebapi/model/user/WechatUser.php
  94. 2 2
      application/version.php
  95. 57 25
      application/wap/controller/AuthApi.php
  96. 1 1
      application/wap/controller/AuthController.php
  97. 1 1
      application/wap/controller/My.php
  98. 9 10
      application/wap/controller/PublicApi.php
  99. 8 4
      application/wap/controller/Store.php
  100. 0 0
      application/wap/controller/WapBasic.php

+ 9 - 9
application/admin/common.php

@@ -34,13 +34,13 @@ function attrFormat($arr){
                             //替代变量3
                             $rep3 = explode('_', $h);
                             //替代变量4
-                            $rep4['detail'][$rep3[0]] = $rep3[1];
+                            $rep4['detail'][$rep3[0]] = isset($rep3[1]) ? $rep3[1] : '';
                         }
                         $res[] = $rep4;
                     }
                 }
             }
-            $data = $tmp;
+            $data = isset($tmp) ? $tmp : [];
         }
     }else{
         $dataArr = [];
@@ -102,18 +102,18 @@ function clearfile($path,$ext = '*.log')
     }
     return true;
 }
+
 /**获取当前类方法
  * @param $class
  * @return array
  */
-function get_this_class_methods($class,$array4 = []) {
-    $array1 = get_class_methods($class);
+function get_this_class_methods($class,$unarray = []) {
+    $arrayall = get_class_methods($class);
     if ($parent_class = get_parent_class($class)) {
-        $array2 = get_class_methods($parent_class);
-        $array3 = array_diff($array1, $array2);//去除父级的
+        $arrayparent = get_class_methods($parent_class);
+        $arraynow = array_diff($arrayall, $arrayparent);//去除父级的
     } else {
-        $array3 = $array1;
+        $arraynow = $arrayall;
     }
-    $array5 = array_diff($array3, $array4);//去除无用的
-    return $array5;
+    return array_diff($arraynow, $unarray);//去除无用的
 }

+ 18 - 13
application/admin/controller/Index.php

@@ -11,6 +11,7 @@ use app\admin\model\user\UserExtract as UserExtractModel;//分销
 use app\admin\model\user\User as UserModel;//用户
 use app\admin\model\store\StoreProductReply as StoreProductReplyModel;//评论
 use app\admin\model\store\StoreProduct as ProductModel;//产品
+use app\core\util\SystemConfigService;
 use FormBuilder\Json;
 use think\DB;
 
@@ -28,11 +29,10 @@ class Index extends AuthController
         $adminInfo = $this->adminInfo->toArray();
         $roles  = explode(',',$adminInfo['roles']);
         $site_logo = SystemConfig::getOneConfig('menu_name','site_logo')->toArray();
-//        dump(SystemMenus::menuList());
-//        exit();
         $this->assign([
             'menuList'=>SystemMenus::menuList(),
             'site_logo'=>json_decode($site_logo['value'],true),
+            'new_order_audio_link'=>str_replace('\\','/',SystemConfigService::get('new_order_audio_link')),
             'role_name'=>SystemRole::where('id',$roles[0])->field('role_name')->find()
         ]);
         return $this->fetch();
@@ -545,32 +545,37 @@ class Index extends AuthController
         $data = [];
         $chartdata['legend'] = ['用户数'];//分类
         $chartdata['yAxis']['maxnum'] = 0;//最大值数量
-        if(empty($user_list))return Json::fail('无数据');
-        foreach ($user_list as $k=>$v){
-            $data['day'][] = $v['day'];
-            $data['count'][] = $v['count'];
-            if($chartdata['yAxis']['maxnum'] < $v['count'])
-                $chartdata['yAxis']['maxnum'] = $v['count'];
+        $chartdata['xAxis'] = [date('m-d')];//X轴值
+        $chartdata['series'] = [0];//分类1值
+        if(!empty($user_list)) {
+            foreach ($user_list as $k=>$v){
+                $data['day'][] = $v['day'];
+                $data['count'][] = $v['count'];
+                if($chartdata['yAxis']['maxnum'] < $v['count'])
+                    $chartdata['yAxis']['maxnum'] = $v['count'];
+            }
+            $chartdata['xAxis'] = $data['day'];//X轴值
+            $chartdata['series'] = $data['count'];//分类1值
         }
-        $chartdata['xAxis'] = $data['day'];//X轴值
-        $chartdata['series'] = $data['count'];//分类1值
-
         return Json::succ('ok',$chartdata);
     }
 
     /**待办事统计
      * @param Request|null $request
      */
-    public function Jnotice()
+    public function Jnotice($newTime=30)
     {
         header('Content-type:text/json');
         $data = [];
         $data['ordernum'] = StoreOrderModel::statusByWhere(1)->count();//待发货
         $replenishment_num = SystemConfig::getValue('store_stock') > 0 ? SystemConfig::getValue('store_stock') : 2;//库存预警界限
         $data['inventory'] = ProductModel::where('stock','<=',$replenishment_num)->where('is_show',1)->where('is_del',0)->count();//库存
-        $data['commentnum'] = StoreProductReplyModel::where('is_reply',0)->count();//评论
+        $data['commentnum'] = StoreProductReplyModel::where(['is_reply'=>0,'is_del'=>0])->count();//评论
         $data['reflectnum'] = UserExtractModel::where('status',0)->count();;//提现
         $data['msgcount'] = intval($data['ordernum'])+intval($data['inventory'])+intval($data['commentnum'])+intval($data['reflectnum']);
+        //新订单提醒
+        $data['newOrderId']=StoreOrderModel::statusByWhere(1)->where('is_remind',0)->column('order_id');
+        if(count($data['newOrderId'])) StoreOrderModel::where('order_id','in',$data['newOrderId'])->update(['is_remind'=>1]);
         return Json::succ('ok',$data);
     }
 }

+ 229 - 37
application/admin/controller/agent/AgentManage.php

@@ -4,10 +4,14 @@ namespace app\admin\controller\agent;
 
 use app\admin\controller\AuthController;
 use app\admin\model\order\StoreOrder;
+use app\admin\model\system\SystemAttachment;
 use app\admin\model\user\User;
 use app\admin\model\wechat\WechatUser as UserModel;
 use app\admin\library\FormBuilder;
+use app\core\model\routine\RoutineQrcode;
 use app\core\model\user\UserBill;
+use service\JsonService;
+use service\UploadService;
 use service\UtilService as Util;
 
 /**
@@ -23,63 +27,250 @@ class AgentManage extends AuthController
      */
     public function index()
     {
-        $where = Util::getMore([
+        $this->assign( 'year',getMonth('y'));
+        $this->assign('store_brokerage_statu',\app\core\util\SystemConfigService::get('store_brokerage_statu'));
+        return $this->fetch();
+    }
+    public function get_spread_list()
+    {
+        $where=Util::getMore([
             ['nickname',''],
-            ['data',''],
-            ['tagid_list',''],
-            ['groupid','-1'],
+            ['start_time',''],
+            ['end_time',''],
             ['sex',''],
-            ['export',''],
-            ['stair',''],
-            ['second',''],
-            ['order_stair',''],
-            ['order_second',''],
+            ['excel',''],
             ['subscribe',''],
-            ['now_money',''],
-            ['is_promoter',1],
-        ],$this->request);
-        $this->assign([
-            'where'=>$where,
+            ['order',''],
+            ['data',''],
+            ['page',1],
+            ['limit',20],
+            ['user_type',''],
         ]);
-        $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'))
-            ])
-        ];
-        $uidAll = UserModel::getAll($where);
-        $this->assign(compact('limitTimeList','uidAll'));
-        $this->assign(UserModel::agentSystemPage($where));
+        return JsonService::successlayui(UserModel::agentSystemPage($where));
+    }
+
+    public function get_badge()
+    {
+        $where = Util::postMore([
+            ['data',''],
+            ['nickname',''],
+            ['excel',''],
+        ]);
+        return JsonService::successful(UserModel::getSpreadBadge($where));
+    }
+
+    /**
+     * 推荐人页面
+     * @return mixed
+     */
+    public function stair($uid = '')
+    {
+        if($uid == '') return $this->failed('参数错误');
+        $this->assign('uid',$uid ? : 0);
+        $this->assign( 'year',getMonth('y'));
         return $this->fetch();
     }
 
+    /*
+     *  统计推广订单
+     * @param int $uid
+     * */
+    public function stair_order($uid = 0)
+    {
+        if($uid == '') return $this->failed('参数错误');
+        $this->assign('uid',$uid ? : 0);
+        $this->assign( 'year',getMonth('y'));
+        return $this->fetch();
+    }
+
+    public function get_stair_order_list(){
+        $where = Util::getMore([
+            ['uid',$this->request->param('uid',0)],
+            ['data',''],
+            ['order_id',''],
+            ['type',''],
+            ['page',1],
+            ['limit',20],
+        ]);
+        return JsonService::successlayui(UserModel::getStairOrderList($where));
+    }
+
+    public function get_stair_order_badge()
+    {
+        $where = Util::getMore([
+            ['uid',''],
+            ['data',''],
+            ['order_id',''],
+            ['type',''],
+        ]);
+        return JsonService::successful(UserModel::getStairOrderBadge($where));
+    }
+
+    public function get_stair_list()
+    {
+        $where = Util::getMore([
+            ['uid',$this->request->param('uid',0)],
+            ['data',''],
+            ['nickname',''],
+            ['type',''],
+            ['page',1],
+            ['limit',20],
+        ]);
+        return JsonService::successlayui(UserModel::getStairList($where));
+    }
+
+    public function get_stair_badge()
+    {
+        $where = Util::getMore([
+            ['uid',''],
+            ['data',''],
+            ['nickname',''],
+            ['type',''],
+        ]);
+        return JsonService::successful(UserModel::getSairBadge($where));
+    }
     /**
-     * 一级推荐人页面
+     * 级推荐人页面
      * @return mixed
      */
-    public function stair($uid = ''){
+    public function stair_two($uid = '')
+    {
         if($uid == '') return $this->failed('参数错误');
+        $spread_uid=User::where('spread_uid',$uid)->column('uid');
+        if(count($spread_uid))
+            $spread_uid_two=User::where('spread_uid','in',$spread_uid)->column('uid');
+        else
+            $spread_uid_two=[0];
         $list = User::alias('u')
-            ->where('u.spread_uid',$uid)
-            ->field('u.avatar,u.nickname,u.now_money,u.add_time,u.uid')
+            ->where('u.uid','in',$spread_uid_two)
+            ->field('u.avatar,u.nickname,u.now_money,u.spread_time,u.uid')
             ->where('u.status',1)
             ->order('u.add_time DESC')
             ->select()
             ->toArray();
         foreach ($list as $key=>$value) $list[$key]['orderCount'] = StoreOrder::getOrderCount($value['uid'])?:0;
         $this->assign('list',$list);
-        return $this->fetch();
+        return $this->fetch('stair');
+    }
+
+    /*
+     * 批量清除推广权限
+     * */
+    public function delete_promoter()
+    {
+        list($uids)=Util::postMore([
+            ['uids',[]]
+        ],$this->request,true);
+        if(!count($uids)) return JsonService::fail('请选择需要解除推广权限的用户!');
+        User::beginTrans();
+        try{
+            if(User::where('uid','in',$uids)->update(['is_promoter'=>0])){
+                User::commitTrans();
+                return JsonService::successful('解除成功');
+            }else{
+                User::rollbackTrans();
+                return JsonService::fail('解除失败');
+            }
+        }catch (\PDOException $e){
+            User::rollbackTrans();
+            return JsonService::fail('数据库操作错误',['line'=>$e->getLine(),'message'=>$e->getMessage()]);
+        }catch (\Exception $e){
+            User::rollbackTrans();
+            return JsonService::fail('系统错误',['line'=>$e->getLine(),'message'=>$e->getMessage()]);
+        }
+
+    }
+
+    /*
+     * 查看公众号推广二维码
+     * @param int $uid
+     * @return json
+     * */
+    public function look_code($uid='',$action='')
+    {
+        if(!$uid || !$action) return JsonService::fail('缺少参数');
+        try{
+            if(method_exists($this,$action)){
+                $res = $this->$action($uid);
+                if($res)
+                    return JsonService::successful($res);
+                else
+                    return JsonService::fail(isset($res['msg']) ? $res['msg'] : '获取失败,请稍后再试!' );
+            }else
+                return JsonService::fail('暂无此方法');
+        }catch (\Exception $e){
+            return JsonService::fail('获取推广二维码失败,请检查您的微信配置',['line'=>$e->getLine(),'messag'=>$e->getMessage()]);
+        }
+    }
+    /*
+     * 获取小程序二维码
+     * */
+    public function routine_code($uid)
+    {
+        $userInfo = User::getUserInfos($uid);
+        $name = $userInfo['uid'].'_'.$userInfo['is_promoter'].'_user.jpg';
+        $imageInfo = SystemAttachment::getInfo($name,'name');
+        if(!$imageInfo){
+            $res = \app\core\model\routine\RoutineCode::getShareCode($uid, 'spread', '', '');
+            if(!$res) throw new \think\Exception('二维码生成失败');
+            $imageInfo = UploadService::imageStream($name,$res['res'],'routine/spread/code');
+            if(!is_array($imageInfo)) return $imageInfo;
+            SystemAttachment::attachmentAdd($imageInfo['name'],$imageInfo['size'],$imageInfo['type'],$imageInfo['dir'],$imageInfo['thumb_path'],1,$imageInfo['image_type'],$imageInfo['time']);
+            RoutineQrcode::setRoutineQrcodeFind($res['id'],['status'=>1,'time'=>time(),'qrcode_url'=>$imageInfo['dir']]);
+            $urlCode = $imageInfo['dir'];
+        }else $urlCode = $imageInfo['att_dir'];
+        return ['code_src'=>$urlCode];
+    }
+
+    /*
+     *
+     * */
+    public function wechant_code($uid)
+    {
+        $qr_code = \app\core\util\QrcodeService::getForeverQrcode('spread',$uid);
+        if(isset($qr_code['url']))
+            return ['code_src'=>$qr_code['url']];
+        else
+            throw new \think\Exception('获取失败,请稍后再试!');
     }
 
+    /**
+     * TODO 查看小程序推广二维码
+     * @param string $uid
+     */
+    public function look_xcx_code($uid = '')
+    {
+        if(!strlen(trim($uid))) return JsonService::fail('缺少参数');
+        try{
+
+        }catch (\Exception $e){
+            return JsonService::fail('查看推广二维码失败!',['line'=>$e->getLine(),'meassge'=>$e->getMessage()]);
+        }
+    }
+    /*
+     * 解除单个用户的推广权限
+     * @param int $uid
+     * */
+    public function delete_spread($uid=0)
+    {
+        if(!$uid) return JsonService::fail('缺少参数');
+        if(User::where('uid',$uid)->update(['is_promoter'=>0]))
+            return JsonService::successful('解除成功');
+        else
+            return JsonService::fail('解除失败');
+    }
+
+    /*
+     * 清除自己的上级推广人
+     * */
+    public function empty_spread($uid=0)
+    {
+        if(!$uid) return JsonService::fail('缺少参数');
+        if(User::where('uid',$uid)->update(['spread_uid'=>0]))
+            return JsonService::successful('清除成功');
+        else
+            return JsonService::fail('清除失败');
+    }
     /**
      * 个人资金详情页面
      * @return mixed
@@ -95,4 +286,5 @@ class AgentManage extends AuthController
         $this->assign('list',$list);
         return $this->fetch();
     }
+
 }

+ 33 - 46
application/admin/controller/article/Article.php

@@ -20,10 +20,13 @@ use app\admin\model\system\SystemAttachment;
 class Article extends AuthController
 {
     /**
-     * 显示后台管理员添加的图文
+     * TODO 显示后台管理员添加的图文
      * @return mixed
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\ModelNotFoundException
+     * @throws \think\exception\DbException
      */
-    public function index($pid = 0)
+    public function index()
     {
         $where = Util::getMore([
             ['title',''],
@@ -32,34 +35,33 @@ class Article extends AuthController
         $pid = $this->request->param('pid');
         $this->assign('where',$where);
         $where['merchant'] = 0;//区分是管理员添加的图文显示  0 还是 商户添加的图文显示  1
-        $catlist = ArticleCategoryModel::where('is_del',0)->select()->toArray();
+        $cateList = ArticleCategoryModel::getArticleCategoryList();
+        $tree = [];
         //获取分类列表
-        if($catlist){
-            $tree = Phptree::makeTreeForHtml($catlist);
-            $this->assign(compact('tree'));
+        if(count($cateList)){
+            $tree = Phptree::makeTreeForHtml($cateList);
             if($pid){
                 $pids = Util::getChildrenPid($tree,$pid);
                 $where['cid'] = ltrim($pid.$pids);
             }
-        }else{
-            $tree = [];
-            $this->assign(compact('tree'));
         }
-
-
-        $this->assign('cate',ArticleCategoryModel::getTierList());
+        $this->assign(compact('tree'));
         $this->assign(ArticleModel::getAll($where));
         return $this->fetch();
     }
 
     /**
-     * 展示页面   添加和删除
+     * TODO 文件添加和修改
      * @return mixed
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\ModelNotFoundException
+     * @throws \think\exception\DbException
      */
     public function create(){
-        $id = input('id');
-        $cid = input('cid');
-        $news = array();
+        $id = $this->request->param('id');
+        $cid = $this->request->param('cid');
+        $news = [];
+        $all = [];
         $news['id'] = '';
         $news['image_input'] = '';
         $news['title'] = '';
@@ -69,30 +71,19 @@ class Article extends AuthController
         $news['content'] = '';
         $news['synopsis'] = '';
         $news['url'] = '';
-        $news['cid'] = array();
+        $news['cid'] = [];
+        $select =  0;
         if($id){
             $news = ArticleModel::where('n.id',$id)->alias('n')->field('n.*,c.content')->join('ArticleContent c','c.nid=n.id')->find();
             if(!$news) return $this->failedNotice('数据不存在!');
             $news['cid'] = explode(',',$news['cid']);
         }
-        $all = array();
-        $select =  0;
-        if(!$cid)
-            $cid = '';
-        else {
-            if($id){
-                $all = ArticleCategoryModel::where('id',$cid)->where('hidden','neq',0)->column('id,title');
-                $select = 1;
-            }else{
-                $all = ArticleCategoryModel::where('id',$cid)->column('id,title');
-                $select = 1;
-            }
-
+        if($cid && in_array($cid, ArticleCategoryModel::getArticleCategoryInfo(0,'id'))){
+            $all = ArticleCategoryModel::getArticleCategoryInfo($cid);
+            $select = 1;
         }
-        if(empty($all)){
-            $select =  0;
+        if(!$select){
             $list = ArticleCategoryModel::getTierList();
-            $all = [];
             foreach ($list as $menu){
                 $all[$menu['id']] = $menu['html'].$menu['title'];
             }
@@ -110,11 +101,9 @@ class Article extends AuthController
      */
     public function upload_image(){
         $res = Upload::Image($_POST['file'],'wechat/image/'.date('Ymd'));
-        //产品图片上传记录
-        $fileInfo = $res->fileInfo->getinfo();
-        SystemAttachment::attachmentAdd($res->fileInfo->getSaveName(),$fileInfo['size'],$fileInfo['type'],$res->dir,'',5);
-        if(!$res->status) return Json::fail($res->error);
-        return Json::successful('上传成功!',['url'=>$res->filePath]);
+        if(!is_array($res)) return Json::fail($res);
+        SystemAttachment::attachmentAdd($res['name'],$res['size'],$res['type'],$res['dir'],$res['thumb_path'],5,$res['image_type'],$res['time']);
+        return Json::successful('上传成功!',['url'=>$res['dir']]);
     }
 
     /**
@@ -146,15 +135,13 @@ class Article extends AuthController
         if($data['id']){
             $id = $data['id'];
             unset($data['id']);
+            $res = false;
             ArticleModel::beginTrans();
             $res1 = ArticleModel::edit($data,$id,'id');
             $res2 = ArticleModel::setContent($id,$content);
-            if($res1 && $res2)
+            if($res1 && $res2){
                 $res = true;
-            else
-                $res =false;
-//            dump($res);
-//            exit();
+            }
             ArticleModel::checkTrans($res);
             if($res)
                 return Json::successful('修改图文成功!',$id);
@@ -163,15 +150,15 @@ class Article extends AuthController
         }else{
             $data['add_time'] = time();
             $data['admin_id'] = $this->adminId;
+            $res = false;
             ArticleModel::beginTrans();
             $res1 = ArticleModel::set($data);
             $res2 = false;
             if($res1)
                 $res2 = ArticleModel::setContent($res1->id,$content);
-            if($res1 && $res2)
+            if($res1 && $res2){
                 $res = true;
-            else
-                $res =false;
+            }
             ArticleModel::checkTrans($res);
             if($res)
                 return Json::successful('添加图文成功!',$res1->id);

+ 6 - 7
application/admin/controller/article/ArticleCategory.php

@@ -3,6 +3,7 @@
 namespace app\admin\controller\article;
 
 use app\admin\controller\AuthController;
+use app\admin\model\system\SystemAttachment;
 use service\FormBuilder as Form;
 use service\UtilService as Util;
 use service\JsonService as Json;
@@ -59,7 +60,7 @@ class ArticleCategory extends AuthController
 //            }
 //            return $options;
 //        })->multiple(1)->filterable(1);
-        $f[] = Form::frameImageOne('image','分类图片',Url::build('admin/widget.images/index',array('fodder'=>'image')))->icon('image');
+        $f[] = Form::formFrameImageOne('image','分类图片');
         $f[] = Form::number('sort','排序',0);
         $f[] = Form::radio('status','状态',1)->options([['value'=>1,'label'=>'显示'],['value'=>0,'label'=>'隐藏']]);
         $form = Form::make_post_form('添加分类',$f,Url::build('save'));
@@ -73,11 +74,9 @@ class ArticleCategory extends AuthController
      * */
     public function upload(){
         $res = Upload::image('file','article');
-        $thumbPath = Upload::thumb($res->dir);
-        if($res->status == 200)
-            return Json::successful('图片上传成功!',['name'=>$res->fileInfo->getSaveName(),'url'=>Upload::pathToUrl($thumbPath)]);
-        else
-            return Json::fail($res->error);
+        if(!is_array($res)) return Json::fail($res);
+        SystemAttachment::attachmentAdd($res['name'],$res['size'],$res['type'],$res['dir'],$res['thumb_path'],5,$res['image_type'],$res['time']);
+        return Json::successful('图片上传成功!',['name'=>$res['name'],'url'=>Upload::pathToUrl($res['thumb_path'])]);
     }
 
     /**
@@ -136,7 +135,7 @@ class ArticleCategory extends AuthController
 //            }
 //            return $options;
 //        })->multiple(1)->filterable(1);
-        $f[] = Form::frameImageOne('image','分类图片',Url::build('admin/widget.images/index',array('fodder'=>'image')),$article['image'])->icon('image');
+        $f[] = Form::formFrameImageOne('image','分类图片',$article['image']);
         $f[] = Form::number('sort','排序',0);
         $f[] = Form::radio('status','状态',$article['status'])->options([['value'=>1,'label'=>'显示'],['value'=>0,'label'=>'隐藏']]);
         $form = Form::make_post_form('编辑分类',$f,Url::build('update',array('id'=>$id)));

+ 5 - 108
application/admin/controller/finance/Finance.php

@@ -28,64 +28,6 @@ class Finance extends AuthController
 
 {
 
-    /**
-     * 显示操作记录
-     */
-    public function index(){
-
-        //创建form
-        $form = Form::create('/save.php',[
-            Form::input('goods_name','商品名称')
-            ,Form::input('goods_name1','password')->type('password')
-            ,Form::input('goods_name2','textarea')->type('textarea')
-            ,Form::input('goods_name3','email')->type('email')
-            ,Form::input('goods_name4','date')->type('date')
-            ,Form::cityArea('address','cityArea',[
-                '陕西省','西安市'
-            ])
-            ,Form::dateRange('limit_time','dateRange',
-                strtotime('- 10 day'),
-                time()
-            )
-            ,Form::dateTime('add_time','dateTime')
-            ,Form::color('color','color','#ff0000')
-            ,Form::checkbox('checkbox','checkbox',[1])->options([['value'=>1,'label'=>'白色'],['value'=>2,'label'=>'红色'],['value'=>31,'label'=>'黑色']])
-            ,Form::date('riqi','date','2018-03-1')
-            ,Form::dateTimeRange('dateTimeRange','区间时间段')
-            ,Form::year('year','year')
-            ,Form::month('month','month')
-            ,Form::frame('frame','frame','http://baidu.com')
-            ,Form::frameInputs('month','frameInputs','http://baidu.com')
-            ,Form::frameFiles('month1','frameFiles','http://baidu.com')
-            ,Form::frameImages('month2','frameImages','http://baidu.com')
-            ,Form::frameInputOne('month3','frameInputOne','http://baidu.com')
-            ,Form::frameFileOne('month4','frameFileOne','http://baidu.com')
-            ,Form::frameImageOne('month5','frameImageOne','http://baidu.com')
-            ,Form::hidden('month6','hidden')
-            ,Form::number('month7','number')
-//            ,Form::input input输入框,其他type: text类型Form::text,password类型Form::password,textarea类型Form::textarea,url类型Form::url,email类型Form::email,date类型Form::idate
-            ,Form::radio('month8','radio')->options([['value'=>1,'label'=>'白色'],['value'=>2,'label'=>'红色'],['value'=>31,'label'=>'黑色']])
-            ,Form::rate('month9','rate')
-            ,Form::select('month10','select')->options([['value'=>1,'label'=>'白色'],['value'=>2,'label'=>'红色'],['value'=>31,'label'=>'黑色']])
-            ,Form::selectMultiple('month11','selectMultiple')
-            ,Form::selectOne('month12','selectOne')
-            ,Form::slider('month13','slider',2)
-            ,Form::sliderRange('month23','sliderRange',2,13)
-            ,Form::switches('month14','区间时间段')
-            ,Form::timePicker('month15','区间时间段')
-            ,Form::time('month16','区间时间段')
-            ,Form::timeRange('month17','区间时间段')
-//            ,Form::upload('month','区间时间段')
-//            ,Form::uploadImages('month','区间时间段')
-//            ,Form::uploadFiles('month','区间时间段')
-//            ,Form::uploadImageOne('month','区间时间段')
-//            ,Form::uploadFileOne('month','区间时间段')
-
-        ]);
-        $html = $form->setMethod('get')->setTitle('编辑商品')->view();
-        echo $html;
-
-    }
     /**
      * 显示资金记录
      */
@@ -126,41 +68,7 @@ class Finance extends AuthController
         ]);
         FinanceModel::SaveExport($where);
     }
-//    /**
-//     * 显示佣金记录
-//     */
-//    public function commission_list(){
-//
-//        //创建form
-//        $form = Form::create('/save.php',[
-//            Form::input('goods_name','商品名称')
-//            ,Form::input('goods_name1','password')->type('password')
-//            ,Form::input('goods_name3','email')->type('email')
-//            ,Form::input('goods_name4','date')->type('date')
-//            ,Form::cityArea('address','cityArea',[
-//                '陕西省','西安市'
-//            ])
-//            ,Form::dateRange('limit_time','dateRange',
-//                strtotime('- 10 day'),
-//                time()
-//            )
-//            ,Form::dateTime('add_time','dateTime')
-//            ,Form::color('color','color','#ff0000')
-//            ,Form::checkbox('checkbox','checkbox',[1])->options([['value'=>1,'label'=>'白色'],['value'=>2,'label'=>'红色'],['value'=>31,'label'=>'黑色']])
-//            ,Form::date('riqi','date','2018-03-1')
-//            ,Form::dateTimeRange('dateTimeRange','区间时间段')
-//            ,Form::year('year','year')
-//
-//            ,Form::hidden('month6','hidden')
-//            ,Form::number('month7','number')
-//
-//
-//        ]);
-//        $rule = $form->setMethod('post')->setTitle('编辑商品')->getRules();
-//        $action = Url::build('save');
-//        $this->assign(compact('form','rule','action'));
-//        return $this->fetch();
-//    }
+
     /**
      * 显示佣金记录
      */
@@ -168,6 +76,7 @@ class Finance extends AuthController
         $this->assign('is_layui',true);
         return $this->fetch();
     }
+
     /**
      * 佣金记录异步获取
      */
@@ -178,24 +87,12 @@ class Finance extends AuthController
             ['nickname',''],
             ['price_max',''],
             ['price_min',''],
-            ['order','']
+            ['order',''],
+            ['excel',''],
         ]);
         return Json::successlayui(User::getCommissionList($get));
     }
-    /**
-     * 保存excel表格
-     */
-    public function save_export(){
-        $get=Util::getMore([
-            ['page',1],
-            ['limit',20],
-            ['nickname',''],
-            ['price_max',''],
-            ['price_min',''],
-            ['order','']
-        ]);
-        User::setUserWhere($get,true);
-    }
+
     /**
      * 显示操作记录
      */

+ 4 - 2
application/admin/controller/finance/UserExtract.php

@@ -113,12 +113,14 @@ class UserExtract extends AuthController
         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('您的提现申请已被拒绝!');
+        if($extract->status == 1)  return JsonService::fail('您已提现,请勿重复提现!');
+        if($extract->status == -1)  return JsonService::fail('您的提现申请已被拒绝!');
         $res = UserExtractModel::changeSuccess($id);
         if($res){
+            UserExtractModel::commitTrans();
             return JsonService::successful('操作成功!');
         }else{
+            UserExtractModel::rollbackTrans();
             return JsonService::fail('操作失败!');
         }
     }

+ 25 - 8
application/admin/controller/finance/UserRecharge.php

@@ -1,7 +1,9 @@
 <?php
 namespace app\admin\controller\finance;
 use app\admin\controller\AuthController;
+use app\admin\model\user\User;
 use app\admin\model\user\UserRecharge as UserRechargeModel;
+use app\core\model\routine\RoutineTemplate;
 use app\core\model\user\UserBill;
 use service\UtilService as Util;
 use service\JsonService as Json;
@@ -72,19 +74,34 @@ class UserRecharge extends AuthController
 //        $refund_data['refund_account']='REFUND_SOURCE_RECHARGE_FUNDS';
 
         try{
+
             HookService::listen('user_recharge_refund',$UserRecharge['order_id'],$refund_data,true,PaymentBehavior::class);
         }catch(\Exception $e){
             return Json::fail($e->getMessage());
         }
         UserRechargeModel::edit($data,$id);
-        WechatTemplateService::sendTemplate(WechatUserWap::uidToOpenid($UserRecharge['uid']),WechatTemplateService::ORDER_REFUND_STATUS, [
-            'first'=>'亲,您充值的金额已退款,本次退款'.
-                $data['refund_price'].'金额',
-            'keyword1'=>$UserRecharge['order_id'],
-            'keyword2'=>$UserRecharge['price'],
-            'keyword3'=>date('Y-m-d H:i:s',$UserRecharge['add_time']),
-            'remark'=>'点击查看订单详情'
-        ],Url::build('wap/My/balance','',true,true));
+        User::bcDec($UserRecharge['uid'],'now_money',$refund_price,'uid');
+        switch (strtolower($UserRecharge['recharge_type'])){
+            case 'weixin':
+                WechatTemplateService::sendTemplate(WechatUserWap::where('uid',$UserRecharge['uid'])->value('openid'),WechatTemplateService::ORDER_REFUND_STATUS, [
+                    'first'=>'亲,您充值的金额已退款,本次退款'.
+                        $data['refund_price'].'金额',
+                    'keyword1'=>$UserRecharge['order_id'],
+                    'keyword2'=>$UserRecharge['price'],
+                    'keyword3'=>date('Y-m-d H:i:s',$UserRecharge['add_time']),
+                    'remark'=>'点击查看订单详情'
+                ],Url::build('wap/My/balance','',true,true));
+                break;
+            case 'routine':
+                RoutineTemplate::sendOut('ORDER_REFUND_SUCCESS',$UserRecharge['uid'],[
+                    'keyword1'=>$UserRecharge['order_id'],
+                    'keyword2'=>date('Y-m-d H:i:s',time()),
+                    'keyword3'=>$UserRecharge['price'],
+                    'keyword4'=>'余额充值退款',
+                    'keyword5'=>'亲,您充值的金额已退款,本次退款'. $data['refund_price'].'金额',
+                ]);
+                break;
+        }
         UserBill::expend('系统退款',$UserRecharge['uid'],'now_money','user_recharge_refund',$refund_price,$id,$UserRecharge['price'],'退款给用户'.$refund_price.'元');
         return Json::successful('退款成功!');
     }

+ 95 - 21
application/admin/controller/order/StoreOrder.php

@@ -42,6 +42,7 @@ class StoreOrder extends AuthController
         $this->assign([
             'year'=>getMonth('y'),
             'real_name'=>$this->request->get('real_name',''),
+            'status'=>$this->request->param('status',''),
             'orderCount'=>StoreOrderModel::orderCount(),
         ]);
         return $this->fetch();
@@ -80,6 +81,35 @@ class StoreOrder extends AuthController
         ]);
         return JsonService::successlayui(StoreOrderModel::OrderList($where));
     }
+
+    /*
+     * 发送货
+     * @param int $id
+     * @return html
+     * */
+    public function order_goods($id = 0)
+    {
+        $list =  Db::name('express')->where('is_show',1)->order('sort DESC')->column('id,name');
+        $this->assign([
+            'list'=>$list,
+            'id'=>$id
+        ]);
+        return $this->fetch();
+    }
+    /*
+     * 删除订单
+     * */
+    public function del_order($ids=[])
+    {
+        if(!count($ids)) return JsonService::fail('请选择需要删除的订单');
+        if(StoreOrderModel::where('is_del',0)->where('id','in',$ids)->count()) return JsonService::fail('您选择的的订单存在用户未删除的订单,无法删除用户未删除的订单');
+        $res=StoreOrderModel::where('id','in',$ids)->update(['is_system_del'=>1]);
+        if($res)
+            return JsonService::successful('删除成功');
+        else
+            return JsonService::fail('删除失败');
+    }
+
     public function orderchart(){
         $where = Util::getMore([
             ['status',''],
@@ -183,10 +213,12 @@ class StoreOrder extends AuthController
         StoreOrderStatus::setStatus($id,'order_edit','修改商品总价为:'.$data['total_price'].' 实际支付金额'.$data['pay_price']);
         return Json::successful('修改成功!');
     }
+
     /**
-     * 送货
+     * TODO 填写送货信息
      * @param $id
-     *  send
+     * @return mixed|void
+     * @throws \think\exception\DbException
      */
     public function delivery($id){
         if(!$id) return $this->failed('数据不存在');
@@ -196,36 +228,72 @@ class StoreOrder extends AuthController
             $f = array();
             $f[] = Form::input('delivery_name','送货人姓名')->required('送货人姓名不能为空','required:true;');
             $f[] = Form::input('delivery_id','送货人电话')->required('请输入正确电话号码','telephone');
-            $form = Form::make_post_form('修改订单',$f,Url::build('updateDelivery',array('id'=>$id)),5);
+            $form = Form::make_post_form('修改订单',$f,Url::build('updateDelivery',array('id'=>$id)),7);
             $this->assign(compact('form'));
             return $this->fetch('public/form-builder');
         }
         else $this->failedNotice('订单状态错误');
     }
 
-    /**送货
+    /**
+     * TODO 送货信息提交
      * @param Request $request
      * @param $id
      */
-    public function updateDelivery(Request $request, $id){
+    public function update_delivery(Request $request, $id){
         $data = Util::postMore([
+            ['type',1],
             'delivery_name',
             'delivery_id',
+            ['sh_delivery_name',''],
+            ['sh_delivery_id',''],
         ],$request);
-        $data['delivery_type'] = 'send';
-        if(!$data['delivery_name']) return Json::fail('请输入送货人姓名');
-        if(!(int)$data['delivery_id']) return Json::fail('请输入送货人电话号码');
-        else if(!preg_match("/^1[3456789]{1}\d{9}$/",$data['delivery_id']))  return Json::fail('请输入正确的送货人电话号码');
-        $data['status'] = 1;
-        StoreOrderModel::edit($data,$id);
-        HookService::afterListen('store_product_order_delivery',$data,$id,false,OrderBehavior::class);
-        StoreOrderStatus::setStatus($id,'delivery','已配送 发货人:'.$data['delivery_name'].' 发货人电话:'.$data['delivery_id']);
+        switch ((int)$data['type']){
+            case 1:
+                //发货
+                $data['delivery_type'] = 'express';
+                if(!$data['delivery_name']) return Json::fail('请选择快递公司');
+                if(!$data['delivery_id']) return Json::fail('请输入快递单号');
+                $data['status'] = 1;
+                StoreOrderModel::edit($data,$id);
+                HookService::afterListen('store_product_order_delivery_goods',$data,$id,false,OrderBehavior::class);
+                StoreOrderStatus::setStatus($id,'delivery_goods','已发货 快递公司:'.$data['delivery_name'].' 快递单号:'.$data['delivery_id']);
+                break;
+            case 2:
+                //送货
+                $data['delivery_type'] = 'send';
+                $data['delivery_name'] = $data['sh_delivery_name'];
+                $data['delivery_id'] = $data['sh_delivery_id'];
+                unset($data['sh_delivery_name'],$data['sh_delivery_id']);
+                if(!$data['delivery_name']) return Json::fail('请输入送货人姓名');
+                if(!(int)$data['delivery_id']) return Json::fail('请输入送货人电话号码');
+                else if(!preg_match("/^1[3456789]{1}\d{9}$/",$data['delivery_id']))  return Json::fail('请输入正确的送货人电话号码');
+                $data['status'] = 1;
+                StoreOrderModel::edit($data,$id);
+                HookService::afterListen('store_product_order_delivery',$data,$id,false,OrderBehavior::class);
+                StoreOrderStatus::setStatus($id,'delivery','已配送 发货人:'.$data['delivery_name'].' 发货人电话:'.$data['delivery_id']);
+                break;
+            case 3:
+                //虚拟发货
+                $data['delivery_type'] = 'fictitious';
+                $data['status'] = 1;
+                StoreOrderModel::edit($data,$id);
+                HookService::afterListen('store_product_order_delivery',$data,$id,false,OrderBehavior::class);
+                StoreOrderStatus::setStatus($id,'delivery_fictitious','已虚拟发货');
+                StoreOrderStatus::setStatus($id,'take_delivery','虚拟物品已收货');
+                break;
+            default:
+                return Json::fail('暂时不支持其他发货类型');
+                break;
+        }
         return Json::successful('修改成功!');
     }
+
     /**
-     * 发货
+     * TODO 填写发货信息
      * @param $id
-     *  express
+     * @return mixed|void
+     * @throws \think\exception\DbException
      */
     public function deliver_goods($id){
         if(!$id) return $this->failed('数据不存在');
@@ -242,14 +310,15 @@ class StoreOrder extends AuthController
                         return $menus;
                     })->filterable(1);
             $f[] = Form::input('delivery_id','快递单号');
-            $form = Form::make_post_form('修改订单',$f,Url::build('updateDeliveryGoods',array('id'=>$id)),5);
+            $form = Form::make_post_form('修改订单',$f,Url::build('updateDeliveryGoods',array('id'=>$id)),7);
             $this->assign(compact('form'));
             return $this->fetch('public/form-builder');
         }
         else return $this->failedNotice('订单状态错误');
     }
 
-    /**发货保存
+    /**
+     * TODO 发货信息提交
      * @param Request $request
      * @param $id
      */
@@ -306,7 +375,7 @@ class StoreOrder extends AuthController
             $f[] = Form::input('order_id','退款单号',$product->getData('order_id'))->disabled(1);
             $f[] = Form::number('refund_price','退款金额',$product->getData('pay_price'))->precision(2)->min(0.01);
             $f[] = Form::radio('type','状态',1)->options([['label'=>'直接退款','value'=>1],['label'=>'退款后,返回原状态','value'=>2]]);
-            $form = Form::make_post_form('退款处理',$f,Url::build('updateRefundY',array('id'=>$id)),5);
+            $form = Form::make_post_form('退款处理',$f,Url::build('updateRefundY',array('id'=>$id)),7);
             $this->assign(compact('form'));
             return $this->fetch('public/form-builder');
         }
@@ -373,7 +442,12 @@ class StoreOrder extends AuthController
         if($resEdit){
             $data['type'] = $type;
             if($data['type'] == 1)  StorePink::setRefundPink($id);
-            HookService::afterListen('store_product_order_refund_y',$data,$id,false,OrderBehavior::class);
+            try{
+                HookService::afterListen('store_product_order_refund_y',$data,$id,false,OrderBehavior::class);
+            }catch (\Exception $e){
+                ModelBasic::rollbackTrans();
+                return Json::fail($e->getMessage());
+            }
             StoreOrderStatus::setStatus($id,'refund_price','退款给用户'.$refund_price.'元');
             ModelBasic::commitTrans();
             return Json::successful('修改成功!');
@@ -444,7 +518,7 @@ class StoreOrder extends AuthController
             });
             $f[] = Form::input('delivery_id','快递单号',$product->getData('delivery_id'));
         }
-        $form = Form::make_post_form('配送信息',$f,Url::build('updateDistribution',array('id'=>$id)),5);
+        $form = Form::make_post_form('配送信息',$f,Url::build('updateDistribution',array('id'=>$id)),7);
         $this->assign(compact('form'));
         return $this->fetch('public/form-builder');
     }
@@ -540,7 +614,7 @@ class StoreOrder extends AuthController
             $f[] = Form::number('use_integral','使用的积分',$product->getData('use_integral'))->min(0)->disabled(1);
             $f[] = Form::number('use_integrals','已退积分',$product->getData('back_integral'))->min(0)->disabled(1);
             $f[] = Form::number('back_integral','可退积分',bcsub($product->getData('use_integral'),$product->getData('use_integral')))->min(0);
-            $form = Form::make_post_form('退积分',$f,Url::build('updateIntegralBack',array('id'=>$id)));
+            $form = Form::make_post_form('退积分',$f,Url::build('updateIntegralBack',array('id'=>$id)),7);
             $this->assign(compact('form'));
             return $this->fetch('public/form-builder');
         }else{

+ 1 - 1
application/admin/controller/record/StoreStatistics.php

@@ -75,7 +75,7 @@ class StoreStatistics extends AuthController
         ];
 
         $this->assign(StatisticsModel::systemTable($where));
-        $this->assign(compact('where','trans','orderCount','orderPrice','orderDays','header','Statistic','ordinary','pink','recharge','data','seckill'));
+        $this->assign(compact('where','trans','orderCount','orderDays','header','Statistic','ordinary','pink','recharge','data','seckill'));
         $this->assign('price',StatisticsModel::getOrderPrice($where));
 
         return $this->fetch();

+ 11 - 17
application/admin/controller/setting/SystemGroupData.php

@@ -69,19 +69,19 @@ class SystemGroupData extends AuthController
                     $f[] = Form::input($value["title"],$value["name"])->type('textarea')->placeholder($value['param']);
                     break;
                 case 'radio':
-                    $f[] = Form::radio($value["title"],$value["name"],$info[0]["value"])->options($info);
+                    $f[] = Form::radio($value["title"],$value["name"],isset($info[0]["value"]) ? $info[0]["value"] : '')->options($info);
                     break;
                 case 'checkbox':
-                    $f[] = Form::checkbox($value["title"],$value["name"],$info[0])->options($info);
+                    $f[] = Form::checkbox($value["title"],$value["name"],isset($info[0]) ? $info[0] : '')->options($info);
                     break;
                 case 'select':
-                    $f[] = Form::select($value["title"],$value["name"],$info[0])->options($info)->multiple(false);
+                    $f[] = Form::select($value["title"],$value["name"],isset($info[0]) ? $info[0] : '')->options($info)->multiple(false);
                     break;
                 case 'upload':
-                    $f[] = Form::frameImageOne($value["title"],$value["name"],Url::build('admin/widget.images/index',array('fodder'=>$value["title"],'big'=>1)))->icon('image');
+                    $f[] = Form::formFrameImageOne($value["title"],$value["name"]);
                     break;
                 case 'uploads':
-                    $f[] = Form::frameImages($value["title"],$value["name"],Url::build('admin/widget.images/index',array('fodder'=>$value["title"],'big'=>1)))->maxLength(5)->icon('images')->width('100%')->height('550px')->spin(0);
+                    $f[] = Form::formFrameImages($value["title"],$value["name"]);
                     break;
                 default:
                     $f[] = Form::input($value["title"],$value["name"]);
@@ -184,11 +184,11 @@ class SystemGroupData extends AuthController
                      }else{
                          $image = '';
                      }
-                     $f[] = Form::frameImageOne($value['title'],$value['name'],Url::build('admin/widget.images/index',array('fodder'=>$value['title'],'big'=>1)),$image)->icon('image');
+                     $f[] = Form::formFrameImageOne($value['title'],$value['name'],$image);
                     break;
                  case 'uploads':
                      $images = !empty($fvalue) ? $fvalue:[];
-                     $f[] = Form::frameImages($value['title'],$value['name'],Url::build('admin/widget.images/index', array('fodder' => $value['title'],'big'=>1)),$images)->maxLength(5)->icon('images')->width('100%')->height('550px')->spin(0);
+                     $f[] = Form::formFrameImages($value['title'],$value['name'],$images);
                     break;
                  case 'select':
                      $f[] = Form::select($value['title'],$value['name'],$fvalue)->setOptions($info);
@@ -221,7 +221,7 @@ class SystemGroupData extends AuthController
         foreach ($params as $key => $param) {
             foreach ($Fields['fields'] as $index => $field) {
                 if($key == $field["title"]){
-                    if(!$param)
+                    if(trim($param) == '')
                         return Json::fail($field["name"]."不能为空!");
                     else{
                         $value[$key]["type"] = $field["type"];
@@ -252,14 +252,8 @@ class SystemGroupData extends AuthController
     public function upload()
     {
         $res = Upload::image('file','common');
-        $thumbPath = Upload::thumb($res->dir);
-        //产品图片上传记录
-        $fileInfo = $res->fileInfo->getinfo();
-        SystemAttachment::attachmentAdd($res->fileInfo->getSaveName(),$fileInfo['size'],$fileInfo['type'],$res->dir,$thumbPath,6);
-
-        if($res->status == 200)
-            return Json::successful('图片上传成功!',['name'=>$res->fileInfo->getSaveName(),'url'=>Upload::pathToUrl($thumbPath)]);
-        else
-            return Json::fail($res->error);
+        if(!is_array($res)) return Json::fail($res);
+        SystemAttachment::attachmentAdd($res['name'],$res['size'],$res['type'],$res['dir'],$res['thumb_path'],6,$res['image_type'],$res['time']);
+        return Json::successful('图片上传成功!',['name'=>$res['name'],'url'=>Upload::pathToUrl($res['thumb_path'])]);
     }
 }

+ 83 - 44
application/admin/controller/setting/SystemMenus.php

@@ -51,29 +51,48 @@ class SystemMenus extends AuthController
      */
     public function create($cid = 0)
     {
-        $controller = '';
+        $field = [];
+        $field[] = Form::input('menu_name','按钮名称')->required('按钮名称必填');
+        $field[] = Form::select('pid','父级id',$cid)->setOptions(function(){
+            $list = (Util::sortListTier(MenusModel::all(function($m){
+                $m->order('sort DESC,id ASC');
+            })->toArray(),'顶级','pid','menu_name'));
+            $menus = [['value'=>0,'label'=>'顶级按钮']];
+            foreach ($list as $menu){
+                $menus[] = ['value'=>$menu['id'],'label'=>$menu['html'].$menu['menu_name']];
+            }
+            return $menus;
+        })->filterable(1);
+        $field[] = Form::select('module','模块名')->options([['label'=>'总后台','value'=>'admin']]);
         if($cid)$controller = MenusModel::where('id',$cid)->value('controller')?:'';
-//        var_dump(MenusModel::order('pid ASC,sort DESC,id DESC')->all()->toArray());
-        $field = [
-            Form::input('menu_name','按钮名称')->required('按钮名称必填'),
-            Form::select('pid','父级id',$cid)->setOptions(function(){
-                $list = (Util::sortListTier(MenusModel::all(function($m){
-                    $m->order('sort DESC,id ASC');
-                })->toArray(),'顶级','pid','menu_name'));
-                $menus = [['value'=>0,'label'=>'顶级按钮']];
-                foreach ($list as $menu){
-                    $menus[] = ['value'=>$menu['id'],'label'=>$menu['html'].$menu['menu_name']];
-                }
-                return $menus;
-            })->filterable(1),
-            Form::select('module','模块名')->options([['label'=>'总后台','value'=>'admin']]),
-            Form::input('controller','控制器名',$controller),
-            Form::input('action','方法名'),
-            Form::input('params','参数')->placeholder('举例:a/123/b/234'),
-            Form::frameInputOne('icon','图标',Url::build('admin/widget.widgets/icon',array('fodder'=>'icon')))->icon('ionic'),
-            Form::number('sort','排序',0),
-            Form::radio('is_show','是否菜单',0)->options([['value'=>0,'label'=>'隐藏'],['value'=>1,'label'=>'显示(菜单只显示三级)']])
-        ];
+        else $controller = '';
+        $field[] = Form::input('controller','控制器名',$controller);
+        if (!empty($controller))
+        {
+            $controller = preg_replace_callback('/([.]+([a-z]{1}))/i', function ($matches) {
+                return '\\' . strtoupper($matches[2]);
+            }, $controller);
+            if(class_exists('\app\admin\controller\\' . $controller))
+            {
+                $list = get_this_class_methods('\app\admin\controller\\' . $controller);
+
+                $field[] = Form::select('action','方法名')->setOptions(function()use($list){
+                    $menus = [['value'=>0,'label'=>'默认函数']];
+                    foreach ($list as $menu){
+                        $menus[] = ['value'=>$menu,'label'=>$menu];
+                    }
+                    return $menus;
+                })->filterable(1);
+            }else{
+                $field[] = Form::input('action','方法名');
+            }
+        }else{
+            $field[] = Form::input('action','方法名');
+        }
+        $field[] = Form::input('params','参数')->placeholder('举例:a/123/b/234');
+        $field[] = Form::frameInputOne('icon','图标',Url::build('admin/widget.widgets/icon',array('fodder'=>'icon')))->icon('ionic');
+        $field[] = Form::number('sort','排序',0);
+        $field[] = Form::radio('is_show','是否菜单',0)->options([['value'=>0,'label'=>'隐藏'],['value'=>1,'label'=>'显示(菜单只显示三级)']]);
         $form = Form::make_post_form('添加权限',$field,Url::build('save'),3);
         $this->assign(compact('form'));
         return $this->fetch('public/form-builder');
@@ -91,7 +110,7 @@ class SystemMenus extends AuthController
             'menu_name',
             'controller',
             ['module','admin'],
-            'action',
+            ['action',''],
             'icon',
             'params',
             ['pid',0],
@@ -112,27 +131,47 @@ class SystemMenus extends AuthController
     public function edit($id)
     {
         $menu = MenusModel::get($id);
-        if(!$menu) return Json::fail('数据不存在!');
-        $field = [
-            Form::input('menu_name','按钮名称',$menu['menu_name']),
-            Form::select('pid','父级id',(string)$menu->getData('pid'))->setOptions(function()use($id){
-                $list = (Util::sortListTier(MenusModel::all(function($m){
-                    $m->order('sort DESC,id ASC');
-                })->toArray(),'顶级','pid','menu_name'));
-                $menus = [['value'=>0,'label'=>'顶级按钮']];
-                foreach ($list as $menu){
-                    $menus[] = ['value'=>$menu['id'],'label'=>$menu['html'].$menu['menu_name']];
-                }
-                return $menus;
-            })->filterable(1),
-            Form::select('module','模块名',$menu['module'])->options([['label'=>'总后台','value'=>'admin']]),
-            Form::input('controller','控制器名',$menu['controller']),
-            Form::input('action','方法名',$menu['action']),
-            Form::input('params','参数',MenusModel::paramStr($menu['params']))->placeholder('举例:a/123/b/234'),
-            Form::frameInputOne('icon','图标',Url::build('admin/widget.widgets/icon',array('fodder'=>'icon')),$menu['icon'])->icon('ionic'),
-            Form::number('sort','排序',$menu['sort']),
-            Form::radio('is_show','是否菜单',$menu['is_show'])->options([['value'=>0,'label'=>'隐藏'],['value'=>1,'label'=>'显示(菜单只显示三级)']])
-        ];
+        if (!$menu) return Json::fail('数据不存在!');
+        $field = array();
+        $field[] = Form::input('menu_name','按钮名称',$menu['menu_name']);
+        $field[] = Form::select('pid','父级id',(string)$menu->getData('pid'))->setOptions(function()use($id){
+            $list = (Util::sortListTier(MenusModel::all(function($m){
+                $m->order('sort DESC,id ASC');
+            })->toArray(),'顶级','pid','menu_name'));
+            $menus = [['value'=>0,'label'=>'顶级按钮']];
+            foreach ($list as $menu){
+                $menus[] = ['value'=>$menu['id'],'label'=>$menu['html'].$menu['menu_name']];
+            }
+            return $menus;
+        })->filterable(1);
+        $field[] = Form::select('module','模块名',$menu['module'])->options([['label'=>'总后台','value'=>'admin']]);
+        $field[] = Form::input('controller','控制器名',$menu['controller']);
+        if (!empty($menu['controller']))
+        {
+            $controller = preg_replace_callback('/([.]+([a-z]{1}))/i', function ($matches) {
+                return '\\' . strtoupper($matches[2]);
+            }, $menu['controller']);
+            if(class_exists('\app\admin\controller\\' . $controller))
+            {
+                $list = get_this_class_methods('\app\admin\controller\\' . $controller);
+
+                $field[] = Form::select('action','方法名',(string)$menu->getData('action'))->setOptions(function()use($list){
+                    $menus = [['value'=>0,'label'=>'默认函数']];
+                    foreach ($list as $menu){
+                        $menus[] = ['value'=>$menu,'label'=>$menu];
+                    }
+                    return $menus;
+                })->filterable(1);
+            }else{
+                $field[] = Form::input('action','方法名',$menu['action']);
+            }
+        }else{
+            $field[] = Form::input('action','方法名');
+        }
+        $field[] = Form::input('params','参数',MenusModel::paramStr($menu['params']))->placeholder('举例:a/123/b/234');
+        $field[] = Form::frameInputOne('icon','图标',Url::build('admin/widget.widgets/icon',array('fodder'=>'icon')),$menu['icon'])->icon('ionic');
+        $field[] = Form::number('sort','排序',$menu['sort']);
+        $field[] = Form::radio('is_show','是否菜单',$menu['is_show'])->options([['value'=>0,'label'=>'隐藏'],['value'=>1,'label'=>'显示(菜单只显示三级)']]);
         $form = Form::make_post_form('添加权限',$field,Url::build('update',array('id'=>$id)),3);
         $this->assign(compact('form'));
         return $this->fetch('public/form-builder');

+ 885 - 0
application/admin/controller/store/CopyTaobao.php

@@ -0,0 +1,885 @@
+<?php
+/**
+ * Project: 快速复制 淘宝、天猫、1688、京东 商品到CRMEB系统
+ * Author: 有一片天 <810806442@qq.com>  微信:szktor
+ * Date: 2019-04-25
+ */
+namespace app\admin\controller\store;
+
+use service\HttpService;
+use service\UploadService;
+use think\exception\PDOException;
+use app\admin\controller\AuthController;
+use app\admin\model\system\SystemConfig;
+use traits\CurdControllerTrait;
+use service\JsonService;
+use service\UtilService;
+use app\admin\model\store\StoreCategory as CategoryModel;
+use app\admin\model\store\StoreProduct as ProductModel;
+use app\admin\model\system\SystemAttachment;
+use app\admin\model\system\SystemAttachmentCategory;
+
+/**
+ * 产品管理
+ * Class StoreProduct
+ * @package app\admin\controller\store
+ */
+class CopyTaobao extends AuthController
+{
+
+    use CurdControllerTrait;
+
+    protected $bindModel = ProductModel::class;
+    //错误信息
+    protected $errorInfo=true;
+    //产品默认字段
+    protected $productInfo=[
+        'cate_id'=>'',
+        'store_name' =>'',
+        'store_info' => '',
+        'unit_name' => '件',
+        'price' => 0,
+        'keyword' => '',
+        'ficti' => 0,
+        'ot_price' => 0,
+        'give_integral' => 0,
+        'postage' => 0,
+        'cost' => 0,
+        'image' => '',
+        'slider_image' => '',
+        'add_time' => 0,
+        'stock' => 0,
+        'description' => '',
+        'soure_link' => ''
+    ];
+    //抓取网站主域名
+    protected $grabName=[
+        'taobao',
+        '1688',
+        'tmall',
+        'jd'
+    ];
+    //远程下载附件图片分类名称
+    protected $AttachmentCategoryName='远程下载';
+    /**
+    * 显示资源
+     * @return html
+    */
+    public function index()
+    {
+        $list = CategoryModel::getTierList();
+        $menus=[];
+        foreach ($list as $menu){
+            $menus[] = ['value'=>$menu['id'],'label'=>$menu['html'].$menu['cate_name'],'disabled'=>$menu['pid']== 0];//,'disabled'=>$menu['pid']== 0];
+        }
+        $this->assign('menus',$menus);
+        $this->assign('is_layui',1);
+        return $this->fetch();
+    }
+    /*
+     * 设置错误信息
+     * @param string $msg 错误信息
+     * */
+    public  function setErrorInfo($msg='')
+    {
+        $this->errorInfo=$msg;
+        return false;
+    }
+    /*
+     * 设置字符串字符集
+     * @param string $str 需要设置字符集的字符串
+     * @return string
+     * */
+    public function Utf8String($str)
+    {
+        $encode=mb_detect_encoding($str, array("ASCII",'UTF-8',"GB2312","GBK",'BIG5'));
+        if(strtoupper($encode) != 'UTF-8') $str=mb_convert_encoding($str, 'utf-8',$encode);
+        return $str;
+    }
+    /**
+     * 获取资源,并解析出对应的商品参数
+     * @return json
+     */
+    public function get_request_contents()
+    {
+        list($link)=UtilService::postMore([
+            ['link','']
+        ],$this->request,true);
+        $url=$this->checkurl($link);
+        if($url===false) return JsonService::fail($this->errorInfo);
+        $this->errorInfo=true;
+        $html=$this->curl_Get($url,60);
+        if(!$html) return JsonService::fail('商品HTML信息获取失败');
+        $html=$this->Utf8String($html);
+        preg_match('/<title>([^<>]*)<\/title>/', $html, $title);
+        //商品标题
+        $this->productInfo['store_name'] = isset($title['1']) ? str_replace(['-淘宝网','-tmall.com天猫',' - 阿里巴巴',' ','-','【图片价格品牌报价】京东','京东','【行情报价价格评测】'],'',trim($title['1'])) :'';
+        $this->productInfo['store_info'] = $this->productInfo['store_name'];
+        try{
+            //获取url信息
+            $pathinfo=pathinfo($url);
+            if(!isset($pathinfo['dirname'])) return JsonService::fail('解析URL失败');
+            //提取域名
+            $parse_url=parse_url($pathinfo['dirname']);
+            if(!isset($parse_url['host'])) return JsonService::fail('获取域名失败');
+            //获取第一次.出现的位置
+            $strLeng=strpos($parse_url['host'],'.')+1;
+            //截取域名中的真实域名不带.com后的
+            $funsuffix=substr($parse_url['host'],$strLeng,strrpos($parse_url['host'],'.')-$strLeng);
+            if(!in_array($funsuffix,$this->grabName)) return JsonService::fail('您输入的地址不在复制范围内!');
+            //设拼接设置产品函数
+            $funName="setProductInfo".ucfirst($funsuffix);
+            //执行方法
+           if(method_exists($this,$funName))
+               $this->$funName($html);
+           else
+               return JsonService::fail('设置产品函数不存在');
+            if(!$this->productInfo['slider_image']) return JsonService::fail('未能获取到商品信息,请确保商品信息有效!');
+           return JsonService::successful($this->productInfo);
+        }catch (\Exception $e){
+            return JsonService::fail('系统错误',['line'=>$e->getLine(),'meass'=>$e->getMessage()]);
+        }
+    }
+
+    /*
+     * 淘宝设置产品
+     * @param string $html 网页内容
+     * */
+    public function setProductInfoTaobao($html)
+    {
+        //获取轮播图
+        $images = $this->getTaobaoImg($html);
+        $images = array_merge($images);
+        $this->productInfo['slider_image']=isset($images['gaoqing']) ? $images['gaoqing'] : (array)$images;
+        //获取产品详情请求链接
+        $link=$this->getTaobaoDesc($html);
+        //获取请求内容
+        $desc_json = HttpService::getRequest($link);
+        //转换字符集
+        $desc_json = $this->Utf8String($desc_json);
+        //截取掉多余字符
+        $this->productInfo['test']=$desc_json;
+        $desc_json = str_replace('var desc=\'','',$desc_json);
+        $desc_json = str_replace(["\n","\t","\r"],'',$desc_json);
+        $content = substr($desc_json,0,-2);
+        $this->productInfo['description']=$content;
+        //获取详情图
+        $description_images=$this->decodedesc($this->productInfo['description']);
+        $this->productInfo['description_images']=is_array($description_images) ? $description_images : [];
+        $this->productInfo['image']=is_array($this->productInfo['slider_image']) && isset($this->productInfo['slider_image'][0]) ? $this->productInfo['slider_image'][0] : '';
+    }
+
+    /*
+     * 天猫设置产品
+     * @param string $html 网页内容
+     * */
+    public function setProductInfoTmall($html)
+    {
+        //获取轮播图
+        $images = $this->getTianMaoImg($html);
+        $images = array_merge($images);
+        $this->productInfo['slider_image'] = $images;
+        $this->productInfo['image'] = is_array($this->productInfo['slider_image']) && isset($this->productInfo['slider_image'][0]) ? $this->productInfo['slider_image'][0] : '';
+        //获取产品详情请求链接
+        $link=$this->getTianMaoDesc($html);
+        //获取请求内容
+        $desc_json = HttpService::getRequest($link);
+        //转换字符集
+        $desc_json = $this->Utf8String($desc_json);
+        //截取掉多余字符
+        $desc_json = str_replace('var desc=\'','',$desc_json);
+        $desc_json = str_replace(["\n","\t","\r"],'',$desc_json);
+        $content = substr($desc_json,0,-2);
+        $this->productInfo['description']=$content;
+        //获取详情图
+        $description_images=$this->decodedesc($this->productInfo['description']);
+        $this->productInfo['description_images']=is_array($description_images) ? $description_images : [];
+    }
+    /*
+     * 1688设置产品
+     * @param string $html 网页内容
+     * */
+    public function setProductInfo1688($html)
+    {
+        //获取轮播图
+        $images = $this->get1688Img($html);
+        if(isset($images['gaoqing'])){
+            $images['gaoqing'] = array_merge($images['gaoqing']);
+            $this->productInfo['slider_image'] = $images['gaoqing'];
+        }else
+            $this->productInfo['slider_image'] = $images;
+        $this->productInfo['image'] = is_array($this->productInfo['slider_image']) && isset($this->productInfo['slider_image'][0]) ? $this->productInfo['slider_image'][0] : '';
+        //获取产品详情请求链接
+        $link = $this->get1688Desc($html);
+        //获取请求内容
+        $desc_json = HttpService::getRequest($link);
+        //转换字符集
+        $desc_json = $this->Utf8String($desc_json);
+        $this->productInfo['test']=$desc_json;
+        //截取掉多余字符
+        $desc_json = str_replace('var offer_details=','',$desc_json);
+        $desc_json = str_replace(["\n","\t","\r"],'',$desc_json);
+        $desc_json = substr($desc_json,0,-1);
+        $descArray = json_decode($desc_json,true);
+        if(!isset($descArray['content'])) $descArray['content'] = '';
+        $this->productInfo['description']=$descArray['content'];
+        //获取详情图
+        $description_images=$this->decodedesc($this->productInfo['description']);
+        $this->productInfo['description_images']=is_array($description_images) ? $description_images : [];
+    }
+    /*
+     * JD设置产品
+     * @param string $html 网页内容
+     * */
+    public function setProductInfoJd($html)
+    {
+        //获取产品详情请求链接
+        $desc_url = $this->getJdDesc($html);
+        //获取请求内容
+        $desc_json=HttpService::getRequest($desc_url);
+        //转换字符集
+        $desc_json = $this->Utf8String($desc_json);
+        //截取掉多余字符
+        if(substr($desc_json,0,8) == 'showdesc') $desc_json = str_replace('showdesc','',$desc_json);
+        $desc_json = str_replace('data-lazyload=','src=',$desc_json);
+        $descArray=json_decode($desc_json,true);
+        if(!$descArray) $descArray=['content'=>''];
+        //获取轮播图
+        $images=$this->getJdImg($html);
+        $images = array_merge($images);
+        $this->productInfo['slider_image']=$images;
+        $this->productInfo['image']=is_array($this->productInfo['slider_image']) ? $this->productInfo['slider_image'][0] : '';
+        $this->productInfo['description']=$descArray['content'];
+        //获取详情图
+        $description_images=$this->decodedesc($descArray['content']);
+        $this->productInfo['description_images']=is_array($description_images) ? $description_images : [];
+    }
+
+    /*
+    * 检查淘宝,天猫,1688的商品链接
+    * @return string
+    */
+    public function checkurl($link)
+    {
+        $link=strtolower($link);
+        if(!$link) return $this->setErrorInfo('请输入链接地址');
+        if(substr($link,0,4)!='http') return $this->setErrorInfo('链接地址必须以http开头');
+        $arrLine=explode('?',$link);
+        if(!count($arrLine)) return $this->setErrorInfo('链接地址有误(ERR:1001)');
+        if(!isset($arrLine[1])){
+            if(strpos($link,'1688')!==false && strpos($link,'offer')!==false) return trim($arrLine[0]);
+            else if(strpos($link,'item.jd')!==false) return trim($arrLine[0]);
+            else return $this->setErrorInfo('链接地址有误(ERR:1002)');
+        }
+        if(strpos($link,'1688')!==false && strpos($link,'offer')!==false) return trim($arrLine[0]);
+        if(strpos($link,'item.jd')!==false) return trim($arrLine[0]);
+        $arrLineValue = explode('&',$arrLine[1]);
+        if(!is_array($arrLineValue)) return $this->setErrorInfo('链接地址有误(ERR:1003)');
+        if(!strpos(trim($arrLine[0]),'item.htm')) $this->setErrorInfo('链接地址有误(ERR:1004)');
+        //链接参数
+        $lastStr='';
+        foreach ($arrLineValue as $k => $v){
+            if(substr(strtolower($v),0,3) == 'id='){
+                $lastStr = trim($v);
+                break;
+            }
+        }
+        if(!$lastStr) return $this->setErrorInfo('链接地址有误(ERR:1005)');
+        return trim($arrLine[0]) . '?' . $lastStr;
+    }
+
+    /*
+     * 保存图片保存产品信息
+     * */
+    public function save_product()
+    {
+        $data=UtilService::postMore([
+            ['cate_id',''],
+            ['store_name',''],
+            ['store_info',''],
+            ['keyword',''],
+            ['unit_name',''],
+            ['image',''],
+            ['slider_image',[]],
+            ['price',''],
+            ['ot_price',''],
+            ['give_integral',''],
+            ['postage',''],
+            ['sales',''],
+            ['ficti',''],
+            ['stock',''],
+            ['cost',''],
+            ['description_images',[]],
+            ['description',''],
+            ['is_show',0],
+            ['soure_link',''],
+        ]);
+        if(!$data['cate_id']) return JsonService::fail('请选择分类!');
+        if(!$data['store_name']) return JsonService::fail('请填写产品名称');
+        if(!$data['unit_name']) return JsonService::fail('请填写产品单位');
+        if(!$data['image']) return JsonService::fail('商品主图暂无,无法保存商品,您可选择其他链接进行复制产品');
+        if($data['price'] == '' || $data['price'] < 0) return JsonService::fail('请输入产品售价');
+        if($data['ot_price'] == '' || $data['ot_price'] < 0) return JsonService::fail('请输入产品市场价');
+        if($data['stock'] == '' || $data['stock'] < 0) return JsonService::fail('请输入库存');
+        //查询附件分类
+        $AttachmentCategory = SystemAttachmentCategory::where(['name' =>$this->AttachmentCategoryName])->find();
+        //不存在则创建
+        if(!$AttachmentCategory) $AttachmentCategory = SystemAttachmentCategory::set(['pid' =>'0','name' =>$this->AttachmentCategoryName,'enname'=>'']);
+        //生成附件目录
+        if(makePathToUrl('attach',3) == '') return JsonService::fail('无法创建文件夹,请检查您的上传目录权限:'.UPLOAD_PATH.'/attach/');
+        ini_set("max_execution_time", 600);
+        //开始图片下载处理
+        ProductModel::beginTrans();
+        try{
+            //放入主图
+            $images=[
+                ['w'=>305, 'h'=>305, 'line'=>$data['image'],'valuename'=>'image']
+            ];
+            //放入轮播图
+            foreach ($data['slider_image'] as $item){
+                $value=['w'=>640, 'h'=>640, 'line'=>$item,'valuename'=>'slider_image','isTwoArray'=>true];
+                array_push($images,$value);
+            }
+            //执行下载
+            $res=$this->uploadImage($images,false,0,$AttachmentCategory['id']);
+            if(!is_array($res)) return JsonService::fail($this->errorInfo ? $this->errorInfo : '保存图片失败');
+            if(isset($res['image'])) $data['image']=$res['image'];
+            if(isset($res['slider_image'])) $data['slider_image']=$res['slider_image'];
+            $data['slider_image']=count($data['slider_image']) ? json_encode($data['slider_image']) : '';
+            //替换并下载详情里面的图片默认下载全部图片
+            $data['description']=preg_replace('#<style>.*?</style>#is','',$data['description']);
+            $data['description']=$this->uploadImage($data['description_images'],$data['description'],1,$AttachmentCategory['id']);
+            unset($data['description_images']);
+            $data['add_time']=time();
+            $cate_id = explode(',',$data['cate_id']);
+            //产品存在
+            if($productInfo=ProductModel::where(['soure_link'=>$data['soure_link']])->find()){
+                $productInfo->description=$data['description'];
+                $productInfo->slider_image=$data['slider_image'];
+                $productInfo->image=$data['image'];
+                $productInfo->store_name=$data['store_name'];
+                $productInfo->save();
+                ProductModel::commitTrans();
+                return JsonService::successful('商品存在,信息已被更新成功');
+            }else {
+                //不存在时新增
+                if ($res = ProductModel::set($data)) {
+                    foreach ($cate_id as $cid) {
+                        \think\Db::name('store_product_cate')->insert(['product_id' => $res['id'], 'cate_id' => $cid, 'add_time' => time()]);
+                    }
+                    ProductModel::commitTrans();
+                    return JsonService::successful('生成产品成功');
+                } else {
+                    ProductModel::rollbackTrans();
+                    return JsonService::fail('生成产品失败');
+                }
+            }
+        }catch (PDOException $e){
+            ProductModel::rollbackTrans();
+            return JsonService::fail('插入数据库错误',['line'=>$e->getLine(),'messag'=>$e->getMessage()]);
+        }catch (\Exception $e){
+            ProductModel::rollbackTrans();
+            return JsonService::fail('系统错误',['line'=>$e->getLine(),'messag'=>$e->getMessage()]);
+        }
+    }
+    /*
+     * 上传图片处理
+     * @param array $image 图片路径
+     * @param int $uploadType 上传方式 0=远程下载
+     * */
+    public function uploadImage(array $images=[],$html='',$uploadType=0,$AttachmentCategoryId=0)
+    {
+        $uploadImage=[];
+        $siteUrl = SystemConfig::getValue('site_url');
+        switch ($uploadType){
+            case 0:
+                foreach ($images as $item){
+                    //下载图片文件
+                    if($item['w'] && $item['h'])
+                        $uploadValue=$this->downloadImage($item['line'],'',0,30,$item['w'],$item['h']);
+                    else
+                        $uploadValue=$this->downloadImage($item['line']);
+                    //下载成功更新数据库
+                    if(is_array($uploadValue)){
+                        //TODO 拼接图片地址
+                        if($uploadValue['image_type'] == 1) $imagePath=$siteUrl.$uploadValue['path'];
+                        else $imagePath = $uploadValue['path'];
+                        //写入数据库
+                        if(!$uploadValue['is_exists'] && $AttachmentCategoryId) SystemAttachment::attachmentAdd($uploadValue['name'],$uploadValue['size'],$uploadValue['mime'],$imagePath,$imagePath,$AttachmentCategoryId,$uploadValue['image_type'],time(),1);
+                        //组装数组
+                        if(isset($item['isTwoArray']) && $item['isTwoArray'])
+                            $uploadImage[$item['valuename']][]=$imagePath;
+                        else
+                            $uploadImage[$item['valuename']]=$imagePath;
+                    }
+                }
+                break;
+            case 1:
+                preg_match_all('#<img.*?src="([^"]*)"[^>]*>#i', $html, $match);
+                if(isset($match[1])){
+                    foreach ($match[1] as $item){
+                        if(is_int(strpos($item, 'http')))
+                            $arcurl = $item;
+                         else
+                            $arcurl = 'http://'.ltrim($item,'\//');
+                        $uploadValue=$this->downloadImage($arcurl);
+                        //下载成功更新数据库
+                        if(is_array($uploadValue)){
+                            //TODO 拼接图片地址
+                            if($uploadValue['image_type'] == 1) $imagePath=$siteUrl.$uploadValue['path'];
+                            else $imagePath = $uploadValue['path'];
+                            //写入数据库
+                            if(!$uploadValue['is_exists'] && $AttachmentCategoryId) SystemAttachment::attachmentAdd($uploadValue['name'],$uploadValue['size'],$uploadValue['mime'],$imagePath,$imagePath,$AttachmentCategoryId,$uploadValue['image_type'],time(),1);
+                            //替换图片
+                            $html=str_replace($item,$imagePath,$html);
+                        }else{
+                            //替换掉没有下载下来的图片
+                            $html=preg_replace('#<img.*?src="'.$item.'"*>#i','',$html);
+                        }
+                    }
+                }
+                return $html;
+                break;
+            default:
+                return $this->setErrorInfo('上传方式错误');
+                break;
+        }
+        return $uploadImage;
+    }
+
+    //提取商品描述中的所有图片
+    public function decodedesc($desc = '')
+    {
+        $desc =trim($desc);
+        if(!$desc) return '';
+        preg_match_all('/<img[^>]*?src="([^"]*?)"[^>]*?>/i',$desc,$match);
+        if(!isset($match[1]) || count($match[1]) <= 0){
+            preg_match_all('/:url(([^"]*?));/i',$desc,$match);
+            if(!isset($match[1]) || count($match[1]) <= 0) return $desc;
+        }else{
+            preg_match_all('/:url(([^"]*?));/i',$desc,$newmatch);
+            if(isset($newmatch[1]) && count($newmatch[1]) > 0) $match[1] = array_merge($match[1],$newmatch[1]);
+        }
+        $match[1] = array_unique($match[1]); //去掉重复
+        foreach($match[1] as $k => &$v) {
+            $_tmp_img = str_replace([')','(',';'],'',$v);
+            $_tmp_img = strpos($_tmp_img,'http') ? $_tmp_img : 'http:' . $_tmp_img;
+            if(strpos($v,'?')) {
+                $_tarr = explode('?',$v);
+                $_tmp_img = trim($_tarr[0]);
+            }
+            $_urls = str_replace(['\'','"'],'',$_tmp_img);
+            if($this->_img_exists($_urls)) $v = $_urls;
+        }
+        return $match[1];
+    }
+    //获取京东商品组图
+    public function getJdImg($html = '')
+    { 
+      //获取图片服务器网址
+      preg_match('/<img(.*?)id="spec-img"(.*?)data-origin=\"(.*?)\"[^>]*>/', $html, $img);
+      if(!isset($img[3])) return '';
+      $info = parse_url(trim($img[3]));
+      if(!$info['host']) return '';
+      if(!$info['path']) return '';
+      $_tmparr = explode('/',trim($info['path']));
+      $url = 'http://' . $info['host'] . '/' . $_tmparr[1] . '/' . str_replace(['jfs',' '],'',trim($_tmparr[2]));
+      preg_match('/imageList:(.*?)"],/is', $html, $img);
+      if(!isset($img[1]))
+      {
+         return '';
+      }
+      $_arr = explode(',',$img[1]);
+      foreach ($_arr as $k => &$v){
+         $_str = $url . str_replace(['"','[',']',' '],'',trim($v));
+         if(strpos($_str,'?'))
+         {
+             $_tarr = explode('?',$_str);
+             $_str = trim($_tarr[0]);
+         }
+         if($this->_img_exists($_str))
+         {
+           $v = $_str;
+         }else{
+           unset($_arr[$k]);
+         }
+      }
+      return array_unique($_arr);
+    }
+    //获取京东商品描述
+    public function getJdDesc($html = '')
+    {
+      preg_match('/,(.*?)desc:([^<>]*)\',/i', $html, $descarr);
+      if(!isset($descarr[1]) && !isset($descarr[2])) return '';
+      $tmpArr = explode(',',$descarr[2]);
+      if(count($tmpArr) > 0)
+      {
+        $descarr[2] = trim($tmpArr[0]);
+      }
+      $replace_arr = ['\'','\',',' ',',','/*','*/'];
+      if(isset($descarr[2]))
+      {
+        $d_url = str_replace($replace_arr,'',$descarr[2]);
+        return $this->formatDescUrl(strpos($d_url,'http') ? $d_url : 'http:' . $d_url);
+      }
+      $d_url = str_replace($replace_arr,'',$descarr[1]);
+      $d_url = $this->formatDescUrl($d_url);
+      $d_url = rtrim(rtrim($d_url,"?"),"&");
+      return substr($d_url,0,4) == 'http' ? $d_url : 'http:' . $d_url;
+    }
+    //处理下京东商品描述网址
+    public function formatDescUrl($url = '')
+    {
+      if(!$url) return '';
+      $url = substr($url,0,4) == 'http' ? $url : 'http:' . $url;
+      if(!strpos($url,'&'))
+      {
+        $_arr = explode('?',$url);
+        if(!is_array($_arr) || count($_arr) <= 0) return $url;
+        return trim($_arr[0]);
+      }else{
+        $_arr = explode('&',$url);
+      }
+      if(!is_array($_arr) || count($_arr) <= 0) return $url;
+      unset($_arr[count($_arr)-1]);
+      $new_url = '';
+      foreach ($_arr as $k => $v) {
+        $new_url .= $v . '&';
+      }
+      return !$new_url ? $url : $new_url;
+    }
+
+    //获取1688商品组图
+    public function get1688Img($html = '')
+    { 
+      preg_match('/<ul class=\"nav nav-tabs fd-clr\">(.*?)<\/ul>/is', $html, $img);
+      if(!isset($img[0]))
+      {
+         return '';
+      }
+      preg_match_all('/preview":"(.*?)\"\}\'>/is', $img[0], $arrb);
+      if(!isset($arrb[1]) || count($arrb[1]) <= 0)
+      {
+         return '';
+      }
+      $thumb = [];
+      $gaoqing = [];
+      $res = ['thumb' => '', 'gaoqing' => ''];  //缩略图片和高清图片
+      foreach($arrb[1] as $k => $v)
+      {
+         $_str = str_replace(['","original":"'],'*',$v);
+         $_arr = explode('*',$_str);
+         if(is_array($_arr) && isset($_arr[0]) && isset($_arr[1]))
+         {
+           if(strpos($_arr[0],'?'))
+           {
+             $_tarr = explode('?',$_arr[0]);
+             $_arr[0] = trim($_tarr[0]);
+           }
+           if(strpos($_arr[1],'?'))
+           {
+             $_tarr = explode('?',$_arr[1]);
+             $_arr[1] = trim($_tarr[0]);
+           }
+           if($this->_img_exists($_arr[0])) $thumb[] = trim($_arr[0]);
+           if($this->_img_exists($_arr[1])) $gaoqing[] = trim($_arr[1]);
+         }
+      }
+      $res = ['thumb' => array_unique($thumb), 'gaoqing' => array_unique($gaoqing)];  //缩略图片和高清图片
+      return $res;
+    }
+    //获取1688商品描述
+    public function get1688Desc($html = '')
+    {
+      preg_match('/data-tfs-url="([^<>]*)data-enable="true"/', $html, $descarr);
+      if(!isset($descarr[1]))  return '';
+      return str_replace(['"',' '],'',$descarr[1]);
+    }
+
+    //获取天猫商品组图
+    public function getTianMaoImg($html = '')
+    {
+      $pic_size = '430';
+      preg_match('/<img[^>]*id="J_ImgBooth"[^r]*rc=\"([^"]*)\"[^>]*>/', $html, $img);
+      if(isset($img[1]))
+      {
+        $_arr = explode('x',$img[1]);
+        $filename = $_arr[count($_arr)-1];
+        $pic_size = intval(substr($filename,0,3));
+      }
+      preg_match('|<ul id="J_UlThumb" class="tb-thumb tm-clear">(.*)</ul>|isU',$html, $match);
+      preg_match_all('/<img src="(.*?)" \//',$match[1],$images);
+      if(!isset($images[1])) return '';
+      foreach($images[1] as $k => &$v)
+      {
+        $tmp_v = trim($v);
+        $_arr = explode('x',$tmp_v);
+        $_fname = $_arr[count($_arr)-1];
+        $_size = intval(substr($_fname,0,3));
+        if(strpos($tmp_v,'://'))
+        {
+           $_arr = explode(':',$tmp_v);
+           $r_url = trim($_arr[1]);
+        }else{
+           $r_url = $tmp_v;
+        }
+        $str = str_replace($_size, $pic_size, $r_url);
+        if(strpos($str,'?'))
+        {
+           $_tarr = explode('?',$str);
+           $str = trim($_tarr[0]);
+        }
+        $_i_url = strpos($str,'http') ? $str : 'http:' . $str; 
+        if($this->_img_exists($_i_url))
+        {
+          $v = $_i_url;
+        }else{
+          unset($images[1][$k]);
+        }
+      }
+      return array_unique($images[1]);
+    }
+    //获取天猫商品描述
+    public function getTianMaoDesc($html = '')
+    {
+      preg_match('/descUrl":"([^<>]*)","httpsDescUrl":"/', $html, $descarr);
+      if(!isset($descarr[1]))
+      {
+        preg_match('/httpsDescUrl":"([^<>]*)","fetchDcUrl/', $html, $descarr);
+        if(!isset($descarr[1])) return '';
+      }
+      return strpos($descarr[1],'http') ? $descarr[1] : 'http:' . $descarr[1];
+    }
+
+    //获取淘宝商品组图
+    public function getTaobaoImg($html = '')
+    {
+      preg_match('/auctionImages([^<>]*)"]/', $html, $imgarr);
+      if(!isset($imgarr[1])) return '';
+      $arr = explode(',', $imgarr[1]);
+      foreach($arr as $k => &$v)
+      {
+        $str = trim($v);
+        $str = str_replace(['"',' ','',':['], '', $str);
+        if(strpos($str,'?'))
+        {
+           $_tarr = explode('?',$str);
+           $str = trim($_tarr[0]);
+        }
+        $_i_url = strpos($str,'http') ? $str : 'http:' . $str;
+        if($this->_img_exists($_i_url))
+        {
+          $v = $_i_url;
+        }else{
+          unset($arr[$k]);
+        }
+      }
+      return array_unique($arr);
+    }
+    //获取淘宝商品描述
+    public function getTaobaoDesc($html = '')
+    {
+      preg_match('/descUrl([^<>]*)counterApi/', $html, $descarr);
+      if(!isset($descarr[1])) return '';
+      $arr = explode(':', $descarr[1]);
+      $url = [];
+      foreach($arr as $k => $v)
+      {
+        if(strpos($v,'//'))
+        {
+           $str = str_replace(['\'',',',' ','?',':'], '', $v);
+           $url[] = trim($str);
+        }
+      }
+      if($url)
+      {
+        return strpos($url[0],'http') ? $url[0] : 'http:' . $url[0];
+      }else{
+        return '';
+      }
+    }
+ 
+     /**
+     * GET 请求
+     * @param string $url
+     */
+    public function curl_Get($url = '',$time_out = 25)
+    {
+        if(!$url) return '';
+        $ch = curl_init();  
+        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // 跳过证书检查  
+        if(stripos($url,"https://")!==FALSE)
+        {
+           curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);  // 从证书中检查SSL加密算法是否存在  
+        }
+        curl_setopt($ch, CURLOPT_URL, $url);  
+        curl_setopt($ch, CURLOPT_HTTPHEADER, array('user-agent:'.$_SERVER['HTTP_USER_AGENT']));
+        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
+        curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
+        curl_setopt($ch, CURLOPT_TIMEOUT,$time_out);
+        $response = curl_exec($ch);
+        if($error=curl_error($ch)){
+            return false;
+        }
+        curl_close($ch);
+        return mb_convert_encoding($response, 'utf-8','GB2312');
+    }
+    //检测远程文件是否存在
+    public function _img_exists($url = '')
+    {
+      ini_set("max_execution_time", 0);
+      $str = @file_get_contents($url,0,null,0,1);
+      if(strlen($str) <= 0) return false;
+      if($str)
+        return true;
+      else
+        return false;
+    }
+    //TODO 下载图片
+    public function downloadImage($url = '', $name = '', $type = 0, $timeout = 30, $w = 0, $h = 0)
+    {
+        if(!strlen(trim($url))) return '';
+        if(!strlen(trim($name)))
+        {
+            //TODO 获取要下载的文件名称
+            $downloadImageInfo = $this->getImageExtname($url);
+            $name = $downloadImageInfo['file_name'];
+            if(!strlen(trim($name))) return '';
+        }
+        //TODO 获取远程文件所采用的方法
+        if($type){
+            $ch = curl_init();
+            curl_setopt($ch, CURLOPT_URL, $url);
+            curl_setopt($ch, CURLOPT_RETURNTRANSFER, false);
+            curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout);
+            curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); //TODO 跳过证书检查
+            if(stripos($url,"https://") !== FALSE) curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);  //TODO 从证书中检查SSL加密算法是否存在
+            curl_setopt($ch, CURLOPT_HTTPHEADER, array('user-agent:'.$_SERVER['HTTP_USER_AGENT']));
+            if(ini_get('open_basedir') == '' && ini_get('safe_mode' == 'Off')) curl_setopt ($ch, CURLOPT_FOLLOWLOCATION, 1);//TODO 是否采集301、302之后的页面
+            $content = curl_exec($ch);
+            curl_close($ch);
+        }else{
+            try{
+                ob_start();
+                readfile($url);
+                $content = ob_get_contents();
+                ob_end_clean();
+            }catch (\Exception $e){
+                return $e->getMessage();
+            }
+        }
+        $size = strlen(trim($content));
+        if(!$content || $size <= 2) return '图片流获取失败';
+        $date_dir = date('Y') . DS . date('m') . DS . date('d');
+        $imageInfo = UploadService::imageStream($name, $content, 'attach'  . DS . $date_dir. DS);
+        if(!is_array($imageInfo)) return $imageInfo;
+        $date['path'] = $imageInfo['dir'];
+        $date['name'] = $imageInfo['name'];
+        $date['size'] = $imageInfo['size'];
+        $date['mime'] = $imageInfo['type'];
+        $date['image_type'] = $imageInfo['image_type'];
+        $date['is_exists'] = false;
+        return $date;
+    }
+    //获取即将要下载的图片扩展名
+    public function getImageExtname($url = '', $ex = 'jpg')
+    {
+      $_empty = ['file_name' => '', 'ext_name' => $ex];
+      if(!$url) return $_empty;
+      if(strpos($url,'?'))
+      {
+        $_tarr = explode('?',$url);
+        $url = trim($_tarr[0]);
+      }
+      $arr = explode('.',$url);
+      if(!is_array($arr) || count($arr) <= 1)  return $_empty;
+      $ext_name = trim($arr[count($arr)-1]);
+      $ext_name = !$ext_name ? $ex : $ext_name; 
+      return ['file_name' => md5($url) . '.' . $ext_name, 'ext_name' => $ext_name];
+    }
+    /*
+      $filepath = 绝对路径,末尾有斜杠 /
+      $name = 图片文件名
+      $maxwidth 定义生成图片的最大宽度(单位:像素)
+      $maxheight 生成图片的最大高度(单位:像素)
+      $filetype 最终生成的图片类型(.jpg/.png/.gif)
+    */
+    public function resizeImage($filepath = '',$name = '', $maxwidth = 0,$maxheight = 0)
+    {
+      $pic_file = $filepath . $name; //图片文件
+      $img_info = getimagesize($pic_file); //索引 2 是图像类型的标记:1 = GIF,2 = JPG,3 = PNG,4 = SWF,5 = PSD,
+      if($img_info[2] == 1)
+      {
+         $im = imagecreatefromgif($pic_file); //打开图片 
+         $filetype = '.gif'; 
+      }elseif($img_info[2] == 2){
+         $im = imagecreatefromjpeg($pic_file); //打开图片
+         $filetype = '.jpg';
+      }elseif($img_info[2] == 3){
+         $im = imagecreatefrompng($pic_file); //打开图片
+         $filetype = '.png'; 
+      }else{
+         return ['path' => $filepath, 'file' => $name, 'mime' => ''];  
+      }
+      $file_name = md5('_tmp_' . microtime() . '_' .rand(0,10)) . $filetype;
+      $pic_width = imagesx($im);
+      $pic_height = imagesy($im);
+      $resizewidth_tag = false;
+      $resizeheight_tag = false;
+      if(($maxwidth && $pic_width > $maxwidth) || ($maxheight && $pic_height > $maxheight))
+      {
+        if($maxwidth && $pic_width>$maxwidth)
+        {
+            $widthratio = $maxwidth/$pic_width;
+            $resizewidth_tag = true;
+        }
+        if($maxheight && $pic_height>$maxheight)
+        {
+            $heightratio = $maxheight/$pic_height;
+            $resizeheight_tag = true;
+        }
+        if($resizewidth_tag && $resizeheight_tag)
+        {
+           if($widthratio<$heightratio)
+              $ratio = $widthratio;
+           else
+              $ratio = $heightratio;
+        }
+        if($resizewidth_tag && !$resizeheight_tag)
+                $ratio = $widthratio;
+        if($resizeheight_tag && !$resizewidth_tag)
+                $ratio = $heightratio;
+            $newwidth = $pic_width * $ratio;
+            $newheight = $pic_height * $ratio;
+            if(function_exists("imagecopyresampled"))
+            {
+               $newim = imagecreatetruecolor($newwidth,$newheight);
+               imagecopyresampled($newim,$im,0,0,0,0,$newwidth,$newheight,$pic_width,$pic_height);
+            }else{
+               $newim = imagecreate($newwidth,$newheight);
+               imagecopyresized($newim,$im,0,0,0,0,$newwidth,$newheight,$pic_width,$pic_height);
+            }
+            if($filetype == '.png')
+            {
+               imagepng($newim,$filepath . $file_name);
+            }else if($filetype == '.gif'){
+               imagegif($newim,$filepath . $file_name);   
+            }else{
+               imagejpeg($newim,$filepath . $file_name);    
+            }
+            imagedestroy($newim);
+       }else{
+            if($filetype == '.png')
+            {
+               imagepng($im,$filepath . $file_name);
+            }else if($filetype == '.gif'){
+               imagegif($im,$filepath . $file_name);
+            }else{
+               imagejpeg($im,$filepath . $file_name);   
+            }
+            imagedestroy($im);
+       }
+       @unlink($pic_file);
+       return ['path' => $filepath, 'file' => $file_name, 'mime' => $img_info['mime']];
+    }
+}

+ 10 - 11
application/admin/controller/store/StoreCategory.php

@@ -89,7 +89,7 @@ class StoreCategory extends AuthController
                 return $menus;
             })->filterable(1),
             Form::input('cate_name','分类名称'),
-            Form::frameImageOne('pic','分类图标',Url::build('admin/widget.images/index',array('fodder'=>'pic')))->icon('image'),
+            Form::formFrameImageOne('pic','分类图标'),
             Form::number('sort','排序'),
             Form::radio('is_show','状态',1)->options([['label'=>'显示','value'=>1],['label'=>'隐藏','value'=>0]])
         ];
@@ -106,17 +106,14 @@ class StoreCategory extends AuthController
     public function upload()
     {
         $res = Upload::image('file','store/category'.date('Ymd'));
-        $thumbPath = Upload::thumb($res->dir);
-        //产品图片上传记录
-        $fileInfo = $res->fileInfo->getinfo();
-        SystemAttachment::attachmentAdd($res->fileInfo->getSaveName(),$fileInfo['size'],$fileInfo['type'],$res->dir,$thumbPath,1);
-
-        if($res->status == 200)
-            return Json::successful('图片上传成功!',['name'=>$res->fileInfo->getSaveName(),'url'=>Upload::pathToUrl($thumbPath)]);
-        else
-            return Json::fail($res->error);
+        if(is_array($res)){
+            SystemAttachment::attachmentAdd($res['name'],$res['size'],$res['type'],$res['dir'],$res['thumb_path'],1,$res['image_type'],$res['time']);
+            return Json::successful('图片上传成功!',['name'=>$res['name'],'url'=>Upload::pathToUrl($res['thumb_path'])]);
+        }else
+            return Json::fail($res);
     }
 
+
     /**
      * 保存新建的资源
      *
@@ -163,7 +160,9 @@ class StoreCategory extends AuthController
                 return $menus;
             })->filterable(1),
             Form::input('cate_name','分类名称',$c->getData('cate_name')),
-            Form::frameImageOne('pic','分类图标',Url::build('admin/widget.images/index',array('fodder'=>'pic')),$c->getData('pic'))->icon('image'),
+//            Form::frameImageOne('pic','分类图标',Url::build('admin/widget.images/index',array('fodder'=>'pic')),$c->getData('pic'))->icon('image')->width('100%')->height('500px'),
+            Form::formFrameImageOne('pic','分类图标',$c->getData('pic')),
+
             Form::number('sort','排序',$c->getData('sort')),
             Form::radio('is_show','状态',$c->getData('is_show'))->options([['label'=>'显示','value'=>1],['label'=>'隐藏','value'=>0]])
         ];

+ 11 - 13
application/admin/controller/store/StoreProduct.php

@@ -145,8 +145,8 @@ class StoreProduct extends AuthController
             Form::input('store_info','产品简介')->type('textarea'),
             Form::input('keyword','产品关键字')->placeholder('多个用英文状态下的逗号隔开'),
             Form::input('unit_name','产品单位','件'),
-            Form::frameImageOne('image','产品主图片(305*305px)',Url::build('admin/widget.images/index',array('fodder'=>'image')))->icon('image')->width('100%')->height('500px'),
-            Form::frameImages('slider_image','产品轮播图(640*640px)',Url::build('admin/widget.images/index',array('fodder'=>'slider_image')))->maxLength(5)->icon('images')->width('100%')->height('500px')->spin(0),
+            Form::formFrameImageOne('image','产品主图片(305*305px)'),
+            Form::formFrameImages('slider_image','产品轮播图(640*640px)'),
             Form::number('price','产品售价')->min(0)->col(8),
             Form::number('ot_price','产品市场价')->min(0)->col(8),
             Form::number('give_integral','赠送积分')->min(0)->precision(0)->col(8),
@@ -175,16 +175,12 @@ class StoreProduct extends AuthController
     public function upload()
     {
         $res = Upload::image('file','store/product/'.date('Ymd'));
-        $thumbPath = Upload::thumb($res->dir);
-        //产品图片上传记录
-        $fileInfo = $res->fileInfo->getinfo();
-        SystemAttachment::attachmentAdd($res->fileInfo->getSaveName(),$fileInfo['size'],$fileInfo['type'],$res->dir,$thumbPath,1);
-        if($res->status == 200)
-            return Json::successful('图片上传成功!',['name'=>$res->fileInfo->getSaveName(),'url'=>Upload::pathToUrl($thumbPath)]);
+        SystemAttachment::attachmentAdd($res['name'],$res['size'],$res['type'],$res['dir'],$res['thumb_path'],1,$res['image_type'],$res['time']);
+        if(is_array($res))
+            return Json::successful('图片上传成功!',['name'=>$res['name'],'url'=>Upload::pathToUrl($res['thumb_path'])]);
         else
-            return Json::fail($res->error);
+            return Json::fail($res);
     }
-
     /**
      * 保存新建的资源
      *
@@ -275,8 +271,10 @@ class StoreProduct extends AuthController
             Form::input('store_info','产品简介',$product->getData('store_info'))->type('textarea'),
             Form::input('keyword','产品关键字',$product->getData('keyword'))->placeholder('多个用英文状态下的逗号隔开'),
             Form::input('unit_name','产品单位',$product->getData('unit_name')),
-            Form::frameImageOne('image','产品主图片(305*305px)',Url::build('admin/widget.images/index',array('fodder'=>'image')),$product->getData('image'))->icon('image')->width('100%')->height('500px'),
-            Form::frameImages('slider_image','产品轮播图(640*640px)',Url::build('admin/widget.images/index',array('fodder'=>'slider_image')),json_decode($product->getData('slider_image'),1) ? : [])->maxLength(5)->icon('images')->width('100%')->height('500px'),
+//            Form::frameImageOne('image','产品主图片(305*305px)',Url::build('admin/widget.images/index',array('fodder'=>'image')),$product->getData('image'))->icon('image')->width('80%')->height('500px'),
+            Form::formFrameImageOne('image','产品主图片(305*305px)',$product->getData('image')),
+//            Form::frameImages('slider_image','产品轮播图(640*640px)',Url::build('admin/widget.images/index',array('fodder'=>'slider_image')),json_decode($product->getData('slider_image'),1) ? : [])->maxLength(5)->icon('images')->width('945px')->height('600px'),
+            Form::formFrameImages('slider_image','产品轮播图(640*640px)',json_decode($product->getData('slider_image'),1) ? : []),
             Form::number('price','产品售价',$product->getData('price'))->min(0)->precision(2)->col(8),
             Form::number('ot_price','产品市场价',$product->getData('ot_price'))->min(0)->col(8),
             Form::number('give_integral','赠送积分',$product->getData('give_integral'))->min(0)->precision(0)->col(8),
@@ -339,7 +337,7 @@ class StoreProduct extends AuthController
         if(!$data['store_name']) return Json::fail('请输入产品名称');
         if(count($data['image'])<1) return Json::fail('请上传产品图片');
         if(count($data['slider_image'])<1) return Json::fail('请上传产品轮播图');
-        if(count($data['slider_image'])>5) return Json::fail('轮播图最多5张图');
+       // if(count($data['slider_image'])>8) return Json::fail('轮播图最多5张图');
         if($data['price'] == '' || $data['price'] < 0) return Json::fail('请输入产品售价');
         if($data['ot_price'] == '' || $data['ot_price'] < 0) return Json::fail('请输入产品市场价');
         if($data['stock'] == '' || $data['stock'] < 0) return Json::fail('请输入库存');

+ 17 - 14
application/admin/controller/system/SystemAttachment.php

@@ -4,6 +4,7 @@ namespace app\admin\controller\system;
 
 use app\admin\model\system\SystemAttachment as SystemAttachmentModel;
 use app\admin\controller\AuthController;
+use app\core\util\SystemConfigService;
 use service\UploadService as Upload;
 /**
  * 附件管理控制器
@@ -14,25 +15,27 @@ use service\UploadService as Upload;
 class SystemAttachment extends AuthController
 {
 
+
     /**
-     * 编辑器上传图片
-     * @return \think\response\Json
+     * TODO 编辑器上传图片
      */
     public function upload()
     {
         $res = Upload::image('upfile','editor/'.date('Ymd'));
-        //产品图片上传记录
-        $fileInfo = $res->fileInfo->getinfo();
-        $thumbPath = Upload::thumb($res->dir);
-        SystemAttachmentModel::attachmentAdd($res->fileInfo->getSaveName(),$fileInfo['size'],$fileInfo['type'],$res->dir,$thumbPath,0);
-        $info = array(
-            "originalName" => $fileInfo['name'],
-            "name" => $res->fileInfo->getSaveName(),
-            "url" => '.'.$res->dir,
-            "size" => $fileInfo['size'],
-            "type" => $fileInfo['type'],
-            "state" => "SUCCESS"
-        );
+        if(is_array($res)){
+            SystemAttachmentModel::attachmentAdd($res['name'],$res['size'],$res['type'],$res['dir'],$res['thumb_path'],0,$res['image_type'],$res['time']);
+            $info["originalName"] = $res['name'];
+            $info["name"] = $res['name'];
+            $info["url"] = $res['dir'];
+            $info["size"] = $res['size'];
+            $info["type"] = $res['type'];
+            $info["state"] = "SUCCESS";
+            if(strstr($info['url'],'http') === false) $info['url'] =  SystemConfigService::get('site_url').str_replace('\\','/',$res['dir']);
+        }else
+            $info = array(
+                "msg" => $res,
+                "state" => "ERROR"
+            );
         echo json_encode($info);
     }
 }

+ 2 - 0
application/admin/controller/system/SystemDatabackup.php

@@ -1,5 +1,6 @@
 <?php
 namespace app\admin\controller\system;
+
 use app\admin\controller\AuthController;
 use service\FormBuilder as Form;
 use think\Request;
@@ -18,6 +19,7 @@ class SystemDatabackup extends AuthController
     protected $DB;
     public function _initialize()
     {
+        parent::_initialize();
         $config = array(
             'path' => '.'.PUBILC_PATH.'backup/data/',
             //数据库备份路径

+ 16 - 17
application/admin/controller/ump/StoreSeckill.php

@@ -79,8 +79,8 @@ class StoreSeckill extends AuthController
         $f[] = Form::input('info','秒杀活动简介')->type('textarea');
         $f[] = Form::input('unit_name','单位')->placeholder('个、位');
         $f[] = Form::dateTimeRange('section_time','活动时间');
-        $f[] = Form::frameImageOne('image','产品主图片(305*305px)',Url::build('admin/widget.images/index',array('fodder'=>'image')))->icon('image');
-        $f[] = Form::frameImages('images','产品轮播图(640*640px)',Url::build('admin/widget.images/index',array('fodder'=>'images')))->maxLength(5)->icon('images');
+        $f[] = Form::formFrameImageOne('image','产品主图片(305*305px)');
+        $f[] = Form::formFrameImages('images','产品轮播图(640*640px)');
         $f[] = Form::number('price','秒杀价')->min(0)->col(12);
         $f[] = Form::number('ot_price','原价')->min(0)->col(12);
         $f[] = Form::number('cost','成本价')->min(0)->col(12);
@@ -141,7 +141,6 @@ class StoreSeckill extends AuthController
         if($data['ot_price'] == '' || $data['ot_price'] < 0) return Json::fail('请输入产品原售价');
         if($data['cost'] == '' || $data['cost'] < 0) return Json::fail('请输入产品成本价');
         if($data['stock'] == '' || $data['stock'] < 0) return Json::fail('请输入库存');
-        $data['add_time'] = time();
         if($data['num']<1) return Json::fail('请输入单次秒杀个数');
         if($id){
             $product = StoreSeckillModel::get($id);
@@ -149,6 +148,7 @@ class StoreSeckill extends AuthController
             StoreSeckillModel::edit($data,$id);
             return Json::successful('编辑成功!');
         }else{
+            $data['add_time'] = time();
             StoreSeckillModel::set($data);
             return Json::successful('添加成功!');
         }
@@ -168,8 +168,8 @@ class StoreSeckill extends AuthController
         $f[] = Form::input('info','秒杀活动简介',$product->getData('store_info'))->type('textarea');
         $f[] = Form::input('unit_name','单位',$product->getData('unit_name'))->placeholder('个、位');
         $f[] = Form::dateTimeRange('section_time','活动时间');
-        $f[] = Form::frameImageOne('image','产品主图片(305*305px)',Url::build('admin/widget.images/index',array('fodder'=>'image')),$product->getData('image'))->icon('image');
-        $f[] = Form::frameImages('images','产品轮播图(640*640px)',Url::build('admin/widget.images/index',array('fodder'=>'images')),json_decode($product->getData('slider_image')))->maxLength(5)->icon('images');
+        $f[] = Form::frameImageOne('image','产品主图片(305*305px)',Url::build('admin/widget.images/index',array('fodder'=>'image')),$product->getData('image'))->icon('image')->width('100%')->height('500px');
+        $f[] = Form::frameImages('images','产品轮播图(640*640px)',Url::build('admin/widget.images/index',array('fodder'=>'images')),json_decode($product->getData('slider_image')))->maxLength(5)->icon('images')->width('100%')->height('500px');
         $f[] = Form::number('price','秒杀价')->min(0)->col(12);
         $f[] = Form::number('ot_price','原价',$product->getData('price'))->min(0)->col(12);
         $f[] = Form::number('cost','成本价',$product->getData('cost'))->min(0)->col(12);
@@ -193,16 +193,12 @@ class StoreSeckill extends AuthController
      */
     public function upload()
     {
-        $res = Upload::image('file','store/seckill/'.date('Ymd'));
-        $thumbPath = Upload::thumb($res->dir);
-        //产品图片上传记录
-        $fileInfo = $res->fileInfo->getinfo();
-        SystemAttachment::attachmentAdd($res->fileInfo->getSaveName(),$fileInfo['size'],$fileInfo['type'],$res->dir,$thumbPath,4);
-
-        if($res->status == 200)
-            return Json::successful('图片上传成功!',['name'=>$res->fileInfo->getSaveName(),'url'=>Upload::pathToUrl($thumbPath)]);
-        else
-            return Json::fail($res->error);
+        $res = Upload::image('file','store/product/'.date('Ymd'));
+        if(is_array($res)){
+            SystemAttachment::attachmentAdd($res['name'],$res['size'],$res['type'],$res['dir'],$res['thumb_path'],4,$res['image_type'],$res['time']);
+            return Json::successful('图片上传成功!',['name'=>$res['name'],'url'=>Upload::pathToUrl($res['thumb_path'])]);
+        }else
+            return Json::fail($res);
     }
 
 
@@ -223,8 +219,8 @@ class StoreSeckill extends AuthController
         $f[] = Form::input('info','秒杀活动简介',$product->getData('info'))->type('textarea');
         $f[] = Form::input('unit_name','单位',$product->getData('unit_name'))->placeholder('个、位');
         $f[] = Form::dateTimeRange('section_time','活动时间',$product->getData('start_time'),$product->getData('stop_time'));
-        $f[] = Form::frameImageOne('image','产品主图片(305*305px)',Url::build('admin/widget.images/index',array('fodder'=>'image')),$product->getData('image'))->icon('image');
-        $f[] = Form::frameImages('images','产品轮播图(640*640px)',Url::build('admin/widget.images/index',array('fodder'=>'images')),json_decode($product->getData('images')))->maxLength(5)->icon('images');
+        $f[] = Form::frameImageOne('image','产品主图片(305*305px)',Url::build('admin/widget.images/index',array('fodder'=>'image')),$product->getData('image'))->icon('image')->width('100%')->height('500px');
+        $f[] = Form::frameImages('images','产品轮播图(640*640px)',Url::build('admin/widget.images/index',array('fodder'=>'images')),json_decode($product->getData('images')))->maxLength(5)->icon('images')->width('100%')->height('500px');
         $f[] = Form::number('price','秒杀价',$product->getData('price'))->min(0)->col(12);
         $f[] = Form::number('ot_price','原价',$product->getData('ot_price'))->min(0)->col(12);
         $f[] = Form::number('cost','成本价',$product->getData('cost'))->min(0)->col(12);
@@ -251,6 +247,9 @@ class StoreSeckill extends AuthController
     public function delete($id)
     {
         if(!$id) return $this->failed('数据不存在');
+        $product = StoreSeckillModel::get($id);
+        if(!$product) return Json::fail('数据不存在!');
+        if($product['is_del']) return Json::fail('已删除!');
         $data['is_del'] = 1;
         if(!StoreSeckillModel::edit($data,$id))
             return Json::fail(StoreSeckillModel::getErrorInfo('删除失败,请稍候再试!'));

+ 204 - 4
application/admin/controller/user/User.php

@@ -5,8 +5,12 @@
  * @day: 2017/11/11
  */
 namespace app\admin\controller\user;
+
 use app\admin\controller\AuthController;
+use app\admin\model\system\SystemUserLevel;
 use service\FormBuilder as Form;
+use service\JsonService;
+use think\Db;
 use traits\CurdControllerTrait;
 use service\UtilService as Util;
 use service\JsonService as Json;
@@ -16,11 +20,13 @@ use app\admin\model\user\User as UserModel;
 use app\admin\model\user\UserBill AS UserBillAdmin;
 use basic\ModelBasic;
 use service\HookService;
+use app\admin\model\user\UserLevel;
 use behavior\user\UserBehavior;
 use app\admin\model\store\StoreVisit;
 use app\admin\model\wechat\WechatMessage;
 use app\admin\model\order\StoreOrder;
 use app\admin\model\store\StoreCouponUser;
+
 /**
  * 用户管理控制器
  * Class User
@@ -36,8 +42,106 @@ class User extends AuthController
      */
     public function index(){
         $this->assign('count_user',UserModel::getcount());
+        $this->assign('level_list',SystemUserLevel::where(['is_show'=>1,'is_del'=>0])->field(['id','name'])->select());
         return $this->fetch();
     }
+
+    /*
+     * 赠送会员等级
+     * @paran int $uid
+     * */
+    public function give_level($uid=0)
+    {
+        if(!$uid) return $this->failed('缺少参数');
+        $level=\app\core\model\user\UserLevel::getUserLevel($uid);
+        //获取当前会员等级
+        if($level===false)
+            $grade=0;
+        else
+            $grade=\app\core\model\user\UserLevel::getUserLevelInfo($level,'grade');
+        //查询高于当前会员的所有会员等级
+        $systemLevelList=SystemUserLevel::where('grade','>',$grade)->where(['is_show'=>1,'is_del'=>0])->field(['name','id'])->select();
+        $field[]=Form::select('level_id','会员等级')->setOptions(function() use($systemLevelList) {
+            $menus=[];
+            foreach ($systemLevelList as $menu){
+                $menus[] = ['value'=>$menu['id'],'label'=>$menu['name']];
+            }
+            return $menus;
+        })->filterable(1);
+        $form = Form::make_post_form('赠送会员',$field,Url::build('save_give_level',['uid'=>$uid]),2);
+        $this->assign(compact('form'));
+        return $this->fetch('public/form-builder');
+    }
+
+    /*
+     * 赠送会员等级
+     * @paran int $uid
+     * @return json
+     * */
+    public function save_give_level($uid=0)
+    {
+        if(!$uid) return JsonService::fail('缺少参数');
+        list($level_id)=Util::postMore([
+            ['level_id',0],
+        ],$this->request,true);
+        //查询当前选择的会员等级
+        $systemLevel=SystemUserLevel::where(['is_show'=>1,'is_del'=>0,'id'=>$level_id])->find();
+        if(!$systemLevel) return JsonService::fail('您选择赠送的会员等级不存在!');
+        //检查是否拥有此会员等级
+        $level=UserLevel::where(['uid'=>$uid,'level_id'=>$level_id,'is_del'=>0])->field('valid_time,is_forever')->find();
+        if($level) if(!$level['is_forever'] && time() < $level['valid_time']) return JsonService::fail('此用户已有该会员等级,无法再次赠送');
+        //设置会员过期时间
+        $add_valid_time=(int)$systemLevel->valid_date*86400;
+        UserModel::commitTrans();
+        try{
+            //保存会员信息
+            $res=UserLevel::set([
+                'is_forever'=>$systemLevel->is_forever,
+                'status'=>1,
+                'is_del'=>0,
+                'grade'=>$systemLevel->grade,
+                'uid'=>$uid,
+                'add_time'=>time(),
+                'level_id'=>$level_id,
+                'discount'=>$systemLevel->discount,
+                'valid_time'=>$systemLevel->discount ? $add_valid_time : 0,
+                'mark'=>'尊敬的用户【'.UserModel::where('uid',$uid)->value('nickname').'】在'.date('Y-m-d H:i:s',time()).'赠送会员等级成为'.$systemLevel['name'].'会员',
+            ]);
+            //提取等级任务并记录完成情况
+            $levelIds=[$level_id];
+            $lowGradeLevelIds=SystemUserLevel::where('grade','<',$systemLevel->grade)->where(['is_show'=>1,'is_del'=>0])->column('id');
+            if(count($lowGradeLevelIds)) $levelIds=array_merge($levelIds,$lowGradeLevelIds);
+            $taskIds=Db::name('system_user_task')->where('level_id','in',$levelIds)->column('id');
+            $inserValue=[];
+            foreach ($taskIds as $id){
+                $inserValue[]=['uid'=>$uid,'task_id'=>$id,'status'=>1,'add_time'=>time()];
+            }
+            $res=$res && Db::name('user_task_finish')->insertAll($inserValue);
+            if($res){
+                UserModel::commitTrans();
+                return JsonService::successful('赠送成功');
+            }else{
+                UserModel::rollbackTrans();
+                return JsonService::successful('赠送失败');
+            }
+        }catch (\Exception $e){
+            UserModel::rollbackTrans();
+            return JsonService::fail('赠送失败');
+        }
+    }
+    /*
+     * 清除会员等级
+     * @param int $uid
+     * @return json
+     * */
+    public function del_level($uid=0)
+    {
+        if(!$uid) return JsonService::fail('缺少参数');
+        if(UserLevel::cleanUpLevel($uid))
+            return JsonService::successful('清除成功');
+        else
+            return JsonService::fail('清除失败');
+    }
     /**
      * 修改user表状态
      *
@@ -77,6 +181,8 @@ class User extends AuthController
             ['user_time_type',''],
             ['user_time',''],
             ['sex',''],
+            ['level_id',''],
+            ['birthday',''],
         ]);
         return Json::successlayui(UserModel::getUserList($where));
     }
@@ -92,23 +198,111 @@ class User extends AuthController
         if(!$user) return Json::fail('数据不存在!');
         $f = array();
         $f[] = Form::input('uid','用户编号',$user->getData('uid'))->disabled(1);
-        $f[] = Form::input('nickname','用户姓名',$user->getData('nickname'));
+        $f[] = Form::input('real_name','真实姓名',$user->getData('real_name'));
+        $f[] = Form::date('birthday','生日',$user->getData('birthday') ? date('Y-m-d',$user->getData('birthday')) : 0);
+        $f[] = Form::input('card_id','身份证号',$user->getData('card_id'));
+        $f[] = Form::textarea('mark','用户备注',$user->getData('mark'));
+        $f[] = Form::radio('is_promoter','推广员',$user->getData('is_promoter'))->options([['value'=>1,'label'=>'开启'],['value'=>0,'label'=>'关闭']]);
+        $f[] = Form::radio('status','状态',$user->getData('status'))->options([['value'=>1,'label'=>'开启'],['value'=>0,'label'=>'锁定']]);
+        $form = Form::make_post_form('添加用户通知',$f,Url::build('update',array('uid'=>$uid)),5);
+        $this->assign(compact('form'));
+        return $this->fetch('public/form-builder');
+    }
+
+    public function edit_other($uid)
+    {
+        if(!$uid) return $this->failed('数据不存在');
+        $user = UserModel::get($uid);
+        if(!$user) return Json::fail('数据不存在!');
+        $f = array();
         $f[] = Form::radio('money_status','修改余额',1)->options([['value'=>1,'label'=>'增加'],['value'=>2,'label'=>'减少']]);
         $f[] = Form::number('money','余额')->min(0);
         $f[] = Form::radio('integration_status','修改积分',1)->options([['value'=>1,'label'=>'增加'],['value'=>2,'label'=>'减少']]);
         $f[] = Form::number('integration','积分')->min(0);
-        $f[] = Form::radio('status','状态',$user->getData('status'))->options([['value'=>1,'label'=>'开启'],['value'=>0,'label'=>'锁定']]);
-        $f[] = Form::radio('is_promoter','推广员',$user->getData('is_promoter'))->options([['value'=>1,'label'=>'开启'],['value'=>0,'label'=>'关闭']]);
-        $form = Form::make_post_form('添加用户通知',$f,Url::build('update',array('id'=>$uid)),5);
+        $form = Form::make_post_form('修改其他',$f,Url::build('update_other',array('uid'=>$uid)),5);
         $this->assign(compact('form'));
         return $this->fetch('public/form-builder');
     }
 
+    public function update_other($uid=0)
+    {
+        $data = Util::postMore([
+            ['money_status',0],
+            ['money',0],
+            ['integration_status',0],
+            ['integration',0],
+        ],$this->request);
+        if(!$uid) return $this->failed('数据不存在');
+        $user = UserModel::get($uid);
+        if(!$user) return Json::fail('数据不存在!');
+        ModelBasic::beginTrans();
+        $res1 = false;
+        $res2 = false;
+        $edit = array();
+        if($data['money_status'] && $data['money']){//余额增加或者减少
+            if($data['money_status'] == 1){//增加
+                $edit['now_money'] = bcadd($user['now_money'],$data['money'],2);
+                $res1 = UserBillAdmin::income('系统增加余额',$user['uid'],'now_money','system_add',$data['money'],$this->adminId,$edit['now_money'],'系统增加了'.floatval($data['money']).'余额');
+                try{
+                    HookService::listen('admin_add_money',$user,$data['money'],false,UserBehavior::class);
+                }catch (\Exception $e){
+                    ModelBasic::rollbackTrans();
+                    return Json::fail($e->getMessage());
+                }
+            }else if($data['money_status'] == 2){//减少
+                $edit['now_money'] = bcsub($user['now_money'],$data['money'],2);
+                $res1 = UserBillAdmin::expend('系统减少余额',$user['uid'],'now_money','system_sub',$data['money'],$this->adminId,$edit['now_money'],'系统扣除了'.floatval($data['money']).'余额');
+                try{
+                    HookService::listen('admin_sub_money',$user,$data['money'],false,UserBehavior::class);
+                }catch (\Exception $e){
+                    ModelBasic::rollbackTrans();
+                    return Json::fail($e->getMessage());
+                }
+            }
+        }else{
+            $res1 = true;
+        }
+        if($data['integration_status'] && $data['integration']){//积分增加或者减少
+            if($data['integration_status'] == 1){//增加
+                $edit['integral'] = bcadd($user['integral'],$data['integration'],2);
+                $res2 = UserBillAdmin::income('系统增加积分',$user['uid'],'integral','system_add',$data['integration'],$this->adminId,$edit['integral'],'系统增加了'.floatval($data['integration']).'积分');
+                try{
+                    HookService::listen('admin_add_integral',$user,$data['integration'],false,UserBehavior::class);
+                }catch (\Exception $e){
+                    ModelBasic::rollbackTrans();
+                    return Json::fail($e->getMessage());
+                }
+            }else if($data['integration_status'] == 2){//减少
+                $edit['integral'] = bcsub($user['integral'],$data['integration'],2);
+                $res2 = UserBillAdmin::expend('系统减少积分',$user['uid'],'integral','system_sub',$data['integration'],$this->adminId,$edit['integral'],'系统扣除了'.floatval($data['integration']).'积分');
+                try{
+                    HookService::listen('admin_sub_integral',$user,$data['integration'],false,UserBehavior::class);
+                }catch (\Exception $e){
+                    ModelBasic::rollbackTrans();
+                    return Json::fail($e->getMessage());
+                }
+            }
+        }else{
+            $res2 = true;
+        }
+        if($edit) $res3 = UserModel::edit($edit,$uid);
+        else $res3 = true;
+        if($res1 && $res2 && $res3) $res =true;
+        else $res = false;
+        ModelBasic::checkTrans($res);
+        if($res) return Json::successful('修改成功!');
+        else return Json::fail('修改失败');
+    }
+
     public function update(Request $request, $uid)
     {
         $data = Util::postMore([
             ['money_status',0],
             ['is_promoter',1],
+            ['real_name',''],
+            ['card_id',''],
+            ['birthday',''],
+            ['mark',''],
             ['money',0],
             ['integration_status',0],
             ['integration',0],
@@ -117,6 +311,8 @@ class User extends AuthController
         if(!$uid) return $this->failed('数据不存在');
         $user = UserModel::get($uid);
         if(!$user) return Json::fail('数据不存在!');
+        $data['birthday'] = strtotime($data['birthday']);
+        if($data['card_id'] && !Util::setCard($data['card_id'])) return JsonService::successful('输入正确的身份证号码');
         ModelBasic::beginTrans();
         $res1 = false;
         $res2 = false;
@@ -168,6 +364,10 @@ class User extends AuthController
             $res2 = true;
         }
         $edit['status'] = $data['status'];
+        $edit['real_name'] = $data['real_name'];
+        $edit['card_id'] = $data['card_id'];
+        $edit['birthday'] = $data['birthday'];
+        $edit['mark'] = $data['mark'];
         $edit['is_promoter'] = $data['is_promoter'];
         if($edit) $res3 = UserModel::edit($edit,$uid);
         else $res3 = true;

+ 5 - 3
application/admin/controller/user/UserLevel.php

@@ -41,8 +41,8 @@ class UserLevel extends AuthController
         $field[]= Form::number('valid_date','有效时间(天)',isset($vipinfo) ? $vipinfo->valid_date : 0)->min(0)->col(8);
         $field[]= Form::number('grade','等级',isset($vipinfo) ? $vipinfo->grade : 0)->min(0)->col(8);
         $field[]= Form::number('discount','享受折扣',isset($vipinfo) ? $vipinfo->discount : 0)->min(0)->col(8);
-        $field[]= Form::frameImageOne('icon','图标',Url::build('admin/widget.images/index',array('fodder'=>'icon')),isset($vipinfo) ? $vipinfo->icon : '')->icon('image')->width('100%')->height('500px');
-        $field[]= Form::frameImageOne('image','会员背景',Url::build('admin/widget.images/index',array('fodder'=>'image')),isset($vipinfo) ? $vipinfo->image : '')->icon('image')->width('100%')->height('500px');
+        $field[]= Form::formFrameImageOne('icon','图标',isset($vipinfo) ? $vipinfo->icon : '');
+        $field[]= Form::formFrameImageOne('image','会员背景',isset($vipinfo) ? $vipinfo->image : '');
         $field[]= Form::radio('is_show','是否显示',isset($vipinfo) ? $vipinfo->is_show : 0)->options([['label'=>'显示','value'=>1],['label'=>'隐藏','value'=>0]])->col(8);
         $field[]= Form::textarea('explain','等级说明',isset($vipinfo) ? $vipinfo->explain : '');
         $form = Form::make_post_form('添加等级设置',$field,Url::build('save',['id'=>$id]),2);
@@ -74,9 +74,11 @@ class UserLevel extends AuthController
         if(!$data['grade']) return JsonService::fail('请输入等级');
         if(!$data['explain']) return JsonService::fail('请输入等级说明');
         if($data['is_forever']==0 && !$data['valid_date']) return JsonService::fail('请输入有效时间(天)');
+        if($data['is_pay']) return JsonService::fail('会员等级购买功能正在开发中,暂时关闭可购买功能!');
         if($data['is_pay'] && !$data['money']) return JsonService::fail('请输入购买金额');
         if(!$data['icon']) return JsonService::fail('请上传等级图标');
         if(!$data['image']) return JsonService::fail('请上传等级背景图标');
+        if(!$id && SystemUserLevel::be(['is_del'=>0,'grade'=>$data['grade']])) return JsonService::fail('已检测到您设置过的会员等级,此等级不可重复');
         SystemUserLevel::beginTrans();
         try{
             //修改
@@ -86,7 +88,7 @@ class UserLevel extends AuthController
                     return JsonService::successful('修改成功');
                 }else{
                     SystemUserLevel::rollbackTrans();
-                    return JsonService::fail('添加失败');
+                    return JsonService::fail('修改失败');
                 }
             }else{
                 //新增

+ 1 - 0
application/admin/controller/user/UserNotice.php

@@ -59,6 +59,7 @@ class UserNotice extends AuthController
      * @return \think\Response
      */
     public function save(Request $request){
+        return Json::fail('站内消息暂不可用');
         $params = $request->post();
         if(!$params["user"])return Json::fail('请输入发送人!');
         if(!$params["title"])return Json::fail('请输入通知标题!');

+ 5 - 2
application/admin/controller/wechat/Reply.php

@@ -3,6 +3,7 @@
 namespace app\admin\controller\wechat;
 
 use app\admin\controller\AuthController;
+use app\admin\model\system\SystemAttachment;
 use app\admin\model\wechat\WechatReply;
 use service\UtilService as Util;
 use service\JsonService as Json;
@@ -86,8 +87,10 @@ class Reply extends AuthController
     {
         $name = $request->post('file');
         if(!$name) return Json::fail('请上传图片');
-        $res = Upload::image($name,'wechat/image');
-        return $res->status === true ? Json::successful('上传成功',$res->filePath) : Json::fail($res->error);
+        $res = Upload::image($name,'wechat/image',true,true,null,'uniqid',1);
+        if(!is_array($res)) return Json::fail($res);
+        SystemAttachment::attachmentAdd($res['name'],$res['size'],$res['type'],$res['dir'],$res['thumb_path'],0,$res['image_type'],$res['time']);
+        return Json::successful('上传成功',$res['dir']);
     }
 
     public function upload_file(Request $request)

+ 8 - 7
application/admin/controller/wechat/StoreService.php

@@ -1,6 +1,7 @@
 <?php
 namespace app\admin\controller\wechat;
 use app\admin\controller\AuthController;
+use app\admin\model\system\SystemAttachment;
 use service\FormBuilder as Form;
 use service\UtilService as Util;
 use service\JsonService as Json;
@@ -87,7 +88,7 @@ class StoreService extends AuthController
         $service = ServiceModel::get($id);
         if(!$service) return Json::fail('数据不存在!');
         $f = array();
-        $f[] = Form::frameImageOne('avatar','客服头像',Url::build('admin/widget.images/index',array('fodder'=>'avatar')),$service['avatar'])->icon('image');
+        $f[] = Form::formFrameImageOne('avatar','客服头像',$service['avatar']);
         $f[] = Form::input('nickname','客服名称',$service["nickname"]);
         $f[] = Form::switches('notify','订单通知',$service["notify"])->trueValue(1)->falseValue(0)->openStr('开启')->closeStr('关闭');
         $f[] = Form::radio('status','客服状态',$service['status'])->options([['value'=>1,'label'=>'显示'],['value'=>0,'label'=>'隐藏']]);
@@ -135,12 +136,12 @@ class StoreService extends AuthController
      */
     public function upload()
     {
-        $res = Upload::image('file','store/service');
-        $thumbPath = Upload::thumb($res->dir);
-        if($res->status == 200)
-            return Json::successful('图片上传成功!',['name'=>$res->fileInfo->getSaveName(),'url'=>Upload::pathToUrl($thumbPath)]);
-        else
-            return Json::fail($res->error);
+        $res = Upload::image('file','store/product/'.date('Ymd'));
+        if(is_array($res)){
+            SystemAttachment::attachmentAdd($res['name'],$res['size'],$res['type'],$res['dir'],$res['thumb_path'],2,$res['image_type'],$res['time']);
+            return Json::successful('图片上传成功!',['name'=>$res['name'],'url'=>Upload::pathToUrl($res['thumb_path'])]);
+        }else
+            return Json::fail($res);
     }
 
     /**

+ 77 - 42
application/admin/controller/widget/Images.php

@@ -1,6 +1,9 @@
 <?php
 
 namespace app\admin\controller\widget;
+use Api\Storage\COS\COS;
+use Api\Storage\OSS\OSS;
+use Api\Storage\Qiniu\Qiniu;
 use think\Request;
 use think\Url;
 use app\admin\model\system\SystemAttachment as SystemAttachmentModel;
@@ -12,10 +15,9 @@ use service\UtilService as Util;
 use service\FormBuilder as Form;
 
 /**
- * 文件校验控制器
- * Class SystemFile
- * @package app\admin\controller\system
- *
+ * TODO 附件控制器
+ * Class Images
+ * @package app\admin\controller\widget
  */
 class Images extends AuthController
 {
@@ -25,22 +27,30 @@ class Images extends AuthController
      */
    public function index()
    {
-       $pid = 0;
-       if(input('pid') && is_numeric(input('pid'))){
-           $pid = input('pid');
-           session('pid',$pid);
-       }else{
-           $pid = session('pid')?session('pid'):0;
+       $pid = $this->request->param('pid');
+       if($pid === NULL)
+       {
+           $pid = session('pid') ? session('pid') : 0;
        }
+       session('pid',$pid);
        $this->assign('pid',$pid);
-       //分类标题
-       $typearray = Category::getAll();
-       $this->assign(compact('typearray'));
-//       $typearray = self::dir;
-//       $this->assign(compact('typearray'));
-       $this->assign(SystemAttachmentModel::getAll($pid));
        return $this->fetch('widget/images');
    }
+
+   public function get_image_list()
+   {
+       $where = Util::getMore([
+           ['page',1],
+           ['limit',18],
+           ['pid',0]
+       ]);
+       return Json::successful(SystemAttachmentModel::getImageList($where));
+   }
+
+   public function get_image_cate($name = '')
+   {
+       return Json::successful(Category::getAll($name));
+   }
     /**
      * 图片管理上传图片
      * @return \think\response\Json
@@ -48,26 +58,36 @@ class Images extends AuthController
     public function upload()
     {
         $pid = input('pid')!= NULL ?input('pid'):session('pid');
-        $res = Upload::image('file','attach'.DS.date('Y').DS.date('m').DS.date('d'));
-        $thumbPath = Upload::thumb($res->dir);
-        //产品图片上传记录
-        $fileInfo = $res->fileInfo->getinfo();
-        //入口是public需要替换图片路径
-        if(strpos(PUBILC_PATH,'public') == false){
-            $res->dir = str_replace('public/','',$res->dir);
+        $upload_type = $this->request->get('upload_type',0);
+        if(!$pid)  {
+            $info =['code'=>400,'msg'=>'请选择分类,再进行上传!','src'=>''];
+        }else{
+            try{
+                $res = Upload::image('file','attach'.DS.date('Y').DS.date('m').DS.date('d'),true,true,null,'uniqid',$upload_type);
+                if(is_object($res) && $res->status === false){
+                    $info = array(
+                        'code' =>400,
+                        'msg'  =>'上传失败:'.$res->error,
+                        'src'  =>''
+                    );
+                }else if(is_string($res)){
+                    $info = array(
+                        'code' =>400,
+                        'msg'  =>'上传失败:'.$res,
+                        'src'  =>''
+                    );
+                }else if(is_array($res)){
+                    SystemAttachmentModel::attachmentAdd($res['name'],$res['size'],$res['type'],$res['dir'],$res['thumb_path'],$pid,$res['image_type'],$res['time']);
+                    $info = array(
+                        'code' =>200,
+                        'msg'  =>'上传成功',
+                        'src'  =>$res['dir']
+                    );
+                }
+            }catch (\Exception $e){
+                $info = ['code'=>400,'msg'=>$e->getMessage(),'src'=>''];
+            }
         }
-        SystemAttachmentModel::attachmentAdd($res->fileInfo->getSaveName(),$fileInfo['size'],$fileInfo['type'],$res->dir,$thumbPath,$pid);
-        $info = array(
-//            "originalName" => $fileInfo['name'],
-//            "name" => $res->fileInfo->getSaveName(),
-//            "url" => '.'.$res->dir,
-//            "size" => $fileInfo['size'],
-//            "type" => $fileInfo['type'],
-//            "state" => "SUCCESS"
-            'code' =>200,
-            'msg'  =>'上传成功',
-            'src'  =>$res->dir
-        );
         echo json_encode($info);
     }
 
@@ -91,8 +111,16 @@ class Images extends AuthController
     public function deleteimganddata($att_id){
         $attinfo = SystemAttachmentModel::get($att_id)->toArray();
         if($attinfo){
-            @unlink(ROOT_PATH.ltrim($attinfo['att_dir'],'.'));
-            @unlink(ROOT_PATH.ltrim($attinfo['satt_dir'],'.'));
+            if($attinfo['image_type'] == 1){
+                @unlink(ROOT_PATH.ltrim($attinfo['att_dir'],'.'));
+                @unlink(ROOT_PATH.ltrim($attinfo['satt_dir'],'.'));
+            }else if($attinfo['image_type'] == 2){
+                Qiniu::delete($attinfo['name']);
+            }else if($attinfo['image_type'] == 3){
+                OSS::delete($attinfo['name']);
+            }else if($attinfo['image_type'] == 4){
+                COS::delete($attinfo['name']);
+            }
             SystemAttachmentModel::where(['att_id'=>$att_id])->delete();
         }
     }
@@ -137,10 +165,9 @@ class Images extends AuthController
     /**
      * ajax 添加分类
      */
-    public function addcate($id){
-        $id = $id || 0;
+    public function addcate($id=0){
         $formbuider = [];
-        $formbuider[] = Form::select('pid','上级分类','0')->setOptions(function (){
+        $formbuider[] = Form::selectOne('pid','上级分类',$id)->setOptions(function (){
             $list = Category::getCateList(0);
             $options =  [['value'=>0,'label'=>'所有分类']];
             foreach ($list as $id=>$cateName){
@@ -149,7 +176,11 @@ class Images extends AuthController
             return $options;
         })->filterable(1);
         $formbuider[] = Form::input('name','分类名称');
-        $form = Form::make_post_form('添加分类',$formbuider,Url::build('saveCate'));
+        $jsContent = <<<SCRIPT
+parent.SuccessCateg();
+parent.layer.close(parent.layer.getFrameIndex(window.name));
+SCRIPT;
+        $form = Form::make_post_form('添加分类',$formbuider,Url::build('saveCate'),$jsContent);
         $this->assign(compact('form'));
         return $this->fetch('public/form-builder');
     }
@@ -187,7 +218,11 @@ class Images extends AuthController
             return $options;
         })->filterable(1);
         $formbuider[] = Form::input('name','分类名称',$Category->getData('name'));
-        $form = Form::make_post_form('编辑分类',$formbuider,Url::build('updateCate'));
+        $jsContent = <<<SCRIPT
+parent.SuccessCateg();
+parent.layer.close(parent.layer.getFrameIndex(window.name));
+SCRIPT;
+        $form = Form::make_post_form('编辑分类',$formbuider,Url::build('updateCate'),$jsContent);
         $this->assign(compact('form'));
         return $this->fetch('public/form-builder');
     }

+ 29 - 1
application/admin/model/article/ArticleCategory.php

@@ -62,7 +62,7 @@ class ArticleCategory extends ModelBasic
     public static function getTierList($model = null)
     {
         if($model === null) $model = new self();
-        return Util::sortListTier($model->select()->toArray());
+        return Util::sortListTier($model->where('is_del',0)->where('status',1)->select()->toArray());
     }
 
     /**
@@ -82,4 +82,32 @@ class ArticleCategory extends ModelBasic
         return $new_res;
     }
 
+    /**
+     * TODO 获取文章分类
+     * @return array
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\ModelNotFoundException
+     * @throws \think\exception\DbException
+     */
+    public static function getArticleCategoryList(){
+       $list = self::where('is_del',0)->where('status',1)->select();
+       if($list) return $list->toArray();
+       return [];
+    }
+
+    /**
+     * TODO 获取文章分类信息
+     * @param $id
+     * @param string $field
+     * @return mixed
+     */
+    public static function getArticleCategoryInfo($id, $field = 'id,title')
+    {
+        $model = new self;
+        if($id) $model = $model->where('id',$id);
+        $model = $model->where('is_del',0);
+        $model = $model->where('status',1);
+        return $model->column($field);
+    }
+
 }

+ 138 - 37
application/admin/model/order/StoreOrder.php

@@ -34,22 +34,23 @@ class StoreOrder extends ModelBasic
     use ModelTrait;
 
     public static function orderCount(){
-        $data['wz']=self::statusByWhere(0,new self())->count();
-        $data['wf']=self::statusByWhere(1,new self())->count();
-        $data['ds']=self::statusByWhere(2,new self())->count();
-        $data['dp']=self::statusByWhere(3,new self())->count();
-        $data['jy']=self::statusByWhere(4,new self())->count();
-        $data['tk']=self::statusByWhere(-1,new self())->count();
-        $data['yt']=self::statusByWhere(-2,new self())->count();
-        $data['general']=self::where(['pink_id'=>0,'combination_id'=>0,'seckill_id'=>0,'bargain_id'=>0])->count();
-        $data['pink']=self::where('pink_id|combination_id','>',0)->count();
-        $data['seckill']=self::where('seckill_id','>',0)->count();
-        $data['bargain']=self::where('bargain_id','>',0)->count();
+        $data['wz']=self::statusByWhere(0,new self())->where(['is_system_del'=>0])->count();
+        $data['wf']=self::statusByWhere(1,new self())->where(['is_system_del'=>0])->count();
+        $data['ds']=self::statusByWhere(2,new self())->where(['is_system_del'=>0])->count();
+        $data['dp']=self::statusByWhere(3,new self())->where(['is_system_del'=>0])->count();
+        $data['jy']=self::statusByWhere(4,new self())->where(['is_system_del'=>0])->count();
+        $data['tk']=self::statusByWhere(-1,new self())->where(['is_system_del'=>0])->count();
+        $data['yt']=self::statusByWhere(-2,new self())->where(['is_system_del'=>0])->count();
+        $data['del']=self::statusByWhere(-4,new self())->where(['is_system_del'=>0])->count();
+        $data['general']=self::where(['pink_id'=>0,'combination_id'=>0,'seckill_id'=>0,'bargain_id'=>0,'is_system_del'=>0])->count();
+        $data['pink']=self::where('pink_id|combination_id','>',0)->where('is_system_del',0)->count();
+        $data['seckill']=self::where('seckill_id','>',0)->where('is_system_del',0)->count();
+        $data['bargain']=self::where('bargain_id','>',0)->where('is_system_del',0)->count();
         return $data;
     }
 
     public static function OrderList($where){
-        $model = self::getOrderWhere($where,self::alias('a')->join('user r','r.uid=a.uid','LEFT'),'a.','r')->field('a.*,r.nickname');
+        $model = self::getOrderWhere($where,self::alias('a')->join('user r','r.uid=a.uid','LEFT'),'a.','r')->field('a.*,r.nickname,r.phone');
         if($where['order']!=''){
             $model = $model->order(self::setOrder($where['order']));
         }else{
@@ -68,7 +69,7 @@ class StoreOrder extends ModelBasic
             }
             $item['_info'] = $_info;
             $item['add_time'] = date('Y-m-d H:i:s',$item['add_time']);
-            if($item['pink_id'] && $item['combination_id']){
+            if($item['pink_id'] || $item['combination_id']){
                 $pinkStatus = StorePink::where('order_id_key',$item['id'])->value('status');
                 switch ($pinkStatus){
                     case 1:
@@ -135,9 +136,22 @@ class StoreOrder extends ModelBasic
             }else if($item['paid']==1 && $item['status']==3 && $item['refund_status']==0){
                 $item['status_name']='已完成';
             }else if($item['paid']==1 && $item['refund_status']==1){
+                $refundReasonTime = date('Y-m-d H:i', $item['refund_reason_time']);
+                $refundReasonWapImg = json_decode($item['refund_reason_wap_img'], true);
+                $img = '';
+                if(count($refundReasonWapImg) && is_array($refundReasonWapImg)){
+                    foreach ($refundReasonWapImg as $itemImg){
+                        if(strlen(trim($itemImg)))
+                            $img .='<img style="height:50px;" src="'.$itemImg.'" />';
+                    }
+                }
+                if(!strlen(trim($img)))  $img = '无';
                 $item['status_name']=<<<HTML
 <b style="color:#f124c7">申请退款</b><br/>
-<span>退款原因:{$item['refund_reason_wap']}</span>
+<span>退款原因:{$item['refund_reason_wap']}</span><br/>
+<span>备注说明:{$item['refund_reason_wap_explain']}</span><br/>
+<span>退款时间:{$refundReasonTime}</span><br/>
+<span>退款凭证:{$img}</span>
 HTML;
             }else if($item['paid']==1 && $item['refund_status']==2){
                 $item['status_name']='已退款';
@@ -183,17 +197,32 @@ HTML;
                     ],' ');
             }
             $item['cartInfo'] = $_info;
+            $sex=Db::name('wechat_user')->where('uid',$item['uid'])->value('sex');
+            if($sex==1) $sex_name='男';
+            else if($sex==2) $sex_name='女';
+            else $sex_name='未知';
             $export[] = [
-                $item['order_id'],$item['pay_type_name'],
-                $item['total_num'],$item['total_price'],$item['total_postage'],$item['pay_price'],$item['refund_price'],
-                $item['mark'],$item['remark'],
-                [$item['real_name'],$item['user_phone'],$item['user_address']],
+                $item['order_id'],
+                $sex_name,
+                $item['phone'],
+                $item['real_name'],
+                $item['user_phone'],
+                $item['user_address'],
                 $goodsName,
-                [$item['paid'] == 1? '已支付':'未支付','支付时间: '.($item['pay_time'] > 0 ? date('Y/md H:i',$item['pay_time']) : '暂无')]
+                $item['total_price'],
+                $item['pay_price'],
+                $item['pay_postage'],
+                $item['coupon_price'],
+                $item['pay_type_name'],
+                $item['pay_time'] > 0 ? date('Y/md H:i',$item['pay_time']) : '暂无',
+                $item['status_name'],
+                $item['add_time'],
+                $item['mark']
             ];
         }
-        PHPExcelService::setExcelHeader(['订单号','支付方式','商品总数','商品总价','邮费','支付金额','退款金额','用户备注','管理员备注','收货人信息','商品信息','支付状态'])
-            ->setExcelTile('订单导出','订单信息'.time(),' 生成时间:'.date('Y-m-d H:i:s',time()))
+        PHPExcelService::setExcelHeader(['订单号','性别','电话','收货人姓名','收货人电话','收货地址','商品信息',
+            '总价格','实际支付','邮费','优惠金额','支付状态','支付时间','订单状态','下单时间','用户备注'])
+            ->setExcelTile('订单导出'.date('YmdHis',time()),'订单信息'.time(),' 生成时间:'.date('Y-m-d H:i:s',time()))
             ->setExcelContent($export)
             ->ExcelSave();
     }
@@ -313,6 +342,8 @@ HTML;
             return $model->where($alert.'paid',1)->where($alert.'refund_status',2);
         else if($status == -3)//退款
             return $model->where($alert.'paid',1)->where($alert.'refund_status','in','1,2');
+        else if($status == -4)//已删除
+            return $model->where($alert.'is_del',1);
         else
             return $model;
     }
@@ -351,7 +382,7 @@ HTML;
     public static function refundTemplate($data,$oid)
     {
         $order = self::where('id',$oid)->find();
-        WechatTemplateService::sendTemplate(WechatUser::uidToOpenid($order['uid']),WechatTemplateService::ORDER_REFUND_STATUS, [
+        WechatTemplateService::sendTemplate(WechatUser::where('uid',$order['uid'])->value('openid'),WechatTemplateService::ORDER_REFUND_STATUS, [
             'first'=>'亲,您购买的商品已退款,本次退款'.$data['refund_price'].'金额',
             'keyword1'=>$order['order_id'],
             'keyword2'=>$order['pay_price'],
@@ -388,7 +419,12 @@ HTML;
      */
     public static function getOrderWhere($where,$model,$aler='',$join=''){
 //        $model = $model->where('combination_id',0);
-        if($where['status'] != '') $model =  self::statusByWhere($where['status'],$model,$aler);
+        $model = $model->where('is_system_del',0);
+        if($where['status'] != '') {
+            $model =  self::statusByWhere($where['status'],$model,$aler);
+        }else{
+            $model = $model->where('paid',1);
+        }
         if($where['is_del'] != '' && $where['is_del'] != -1) $model = $model->where($aler.'is_del',$where['is_del']);
         if(isset($where['combination_id'])){
             if($where['combination_id'] =='普通订单'){
@@ -423,7 +459,7 @@ HTML;
         }
 
         if($where['real_name'] != ''){
-            $model = $model->where($aler.'order_id|'.$aler.'real_name|'.$aler.'user_phone'.($join ? '|'.$join.'.nickname|'.$join.'.uid':''),'LIKE',"%$where[real_name]%");
+            $model = $model->where($aler.'order_id|'.$aler.'real_name|'.$aler.'user_phone'.($join ? '|'.$join.'.nickname|'.$join.'.uid|'.$join.'.phone':''),'LIKE',"%$where[real_name]%");
         }
         if($where['data'] !== ''){
             $model = self::getModelTime($where,$model,$aler.'add_time');
@@ -436,7 +472,7 @@ HTML;
             [
                 'name'=>'订单数量',
                 'field'=>'件',
-                'count'=>$price['total_num'],
+                'count'=>$price['count_sum'],
                 'background_color'=>'layui-bg-blue',
                 'col'=>2
             ],
@@ -475,6 +511,20 @@ HTML;
                 'background_color'=>'layui-bg-blue',
                 'col'=>2
             ],
+            [
+                'name'=>'运费金额',
+                'field'=>'元',
+                'count'=>$price['pay_postage'],
+                'background_color'=>'layui-bg-blue',
+                'col'=>2
+            ],
+            [
+                'name'=>'分佣金额',
+                'field'=>'元',
+                'count'=>$price['brokerage'],
+                'background_color'=>'layui-bg-blue',
+                'col'=>2
+            ],
             [
                 'name'=>'线下支付金额',
                 'field'=>'元',
@@ -517,23 +567,38 @@ HTML;
         $price['back_integral'] = 0;//退积分总数
         $price['deduction_price'] = 0;//抵扣金额
         $price['total_num'] = 0; //商品总数
-        $sumNumber =self::getOrderWhere($where,$model)->where('is_del',0)->field([
+        $price['count_sum'] = 0; //商品总数
+        $price['brokerage'] =0;
+        $price['pay_postage'] =0;
+        $whereData=['is_del'=>0];
+        if($where['status']==''){
+            $whereData['paid']=1;
+            $whereData['refund_status']=0;
+        }
+        $ids= self::getOrderWhere($where,$model)->where($whereData)->column('id');
+        if(count($ids)){
+            $price['brokerage'] = UserBill::where(['category'=>'now_money','type'=>'brokerage'])->where('link_id','in',$ids)->sum('number');
+        }
+        $price['refund_price'] = self::getOrderWhere($where,$model)->where(['is_del'=>0,'paid'=>1,'refund_status'=>2])->sum('refund_price');
+        $sumNumber =self::getOrderWhere($where,$model)->where($whereData)->field([
             'sum(total_num) as sum_total_num',
+            'count(id) as count_sum',
             'sum(pay_price) as sum_pay_price',
-            'sum(refund_price) as sum_refund_price',
+            'sum(pay_postage) as sum_pay_postage',
             'sum(use_integral) as sum_use_integral',
             'sum(back_integral) as sum_back_integral',
             'sum(deduction_price) as sum_deduction_price'
         ])->find();
         if($sumNumber) {
+            $price['count_sum'] = $sumNumber['count_sum'];
             $price['total_num'] = $sumNumber['sum_total_num'];
             $price['pay_price'] = $sumNumber['sum_pay_price'];
-            $price['refund_price'] = $sumNumber['sum_refund_price'];
+            $price['pay_postage'] = $sumNumber['sum_pay_postage'];
             $price['use_integral'] = $sumNumber['sum_use_integral'];
             $price['back_integral'] = $sumNumber['sum_back_integral'];
             $price['deduction_price'] = $sumNumber['sum_deduction_price'];
         }
-        $list=self::getOrderWhere($where,$model)->where('is_del',0)->group('pay_type')->field(['sum(pay_price) as sum_pay_price','pay_type'])->select();
+        $list = self::getOrderWhere($where,$model)->where($whereData)->group('pay_type')->column('sum(pay_price) as sum_pay_price,pay_type','id');
         foreach ($list as $v){
             if ($v['pay_type'] == 'weixin'){
                 $price['pay_price_wx'] = $v['sum_pay_price'];
@@ -803,6 +868,26 @@ HTML;
 
     public static function getOrderBadge($where){
         return [
+            [
+                'name'=>'拼团订单数量',
+                'field'=>'个',
+                'count'=>self::setEchatWhere($where,2)->count(),
+                'content'=>'拼团总订单数量',
+                'background_color'=>'layui-bg-cyan',
+                'sum'=>self::setEchatWhere($where,2,true)->count(),
+                'class'=>'fa fa-line-chart',
+                'col'=>2
+            ],
+            [
+                'name'=>'砍价订单数量',
+                'field'=>'个',
+                'count'=>self::setEchatWhere($where,4)->count(),
+                'content'=>'砍价总订单数量',
+                'background_color'=>'layui-bg-cyan',
+                'sum'=>self::setEchatWhere($where,4,true)->count(),
+                'class'=>'fa fa-line-chart',
+                'col'=>2
+            ],
             [
                 'name'=>'秒杀订单数量',
                 'field'=>'个',
@@ -948,6 +1033,12 @@ HTML;
                 ]);
                 WechatTemplateService::sendTemplate($openid, WechatTemplateService::ORDER_POSTAGE_SUCCESS, $group, $url);
             }
+        }else if($postageData['delivery_type'] == 'fictitious'){
+            if ($order['is_channel']) {
+
+            }else{
+
+            }
         }
 
     }
@@ -974,21 +1065,31 @@ HTML;
      */
     public static function orderTakeAfter($order)
     {
+        $title = '';
+        $cartInfo = self::getDb('StoreOrderCartInfo')->where('oid', $order['id'])->column('cart_info');
+
+        if(count($cartInfo)){
+            foreach ($cartInfo as $key=>&$cart){
+                $cart = json_decode($cart,true);
+                $title .= $cart['productInfo']['store_name'].',';
+            }
+        }
+        if(strlen(trim($title)))
+            $title = substr($title,0,bcsub(strlen($title),1,0));
+        else{
+            $cartInfo = self::getDb('store_cart')->alias('a')->where('a.id','in',implode(',',json_decode($order['cart_id'],true)))->find();
+            $title = StoreProduct::where('id',$cartInfo['product_id'])->value('store_name');
+        }
+
         if($order['is_channel']){//小程序
             RoutineTemplate::sendOut('OREDER_TAKEVER',$order['uid'],[
                 'keyword1'=>$order['order_id'],
-                'keyword2'=>self::getDb('store_cart')->alias('a')->join('__STORE_PRODUCT__ P','a.product_id=p.id')->where('a.id','in',$order['cart_id'])->value('p.title'),
+                'keyword2'=>$title,
                 'keyword3'=>$order['pay_price'],
                 'keyword4'=>date('Y-m-d H:i:s',time()),
             ]);
         }else{
-             $openid = WechatUser::where('uid',$order['uid'])->value('openid');
-            $title='';
-            $cartInfo = self::getDb('StoreOrderCartInfo')->where('oid', $order['id'])->column('product_id') ?: [];
-            foreach ($cartInfo as $k => $productId) {
-                $store_name=self::getDb('store_product')->where('id',$productId)->value('store_name');
-                $title.=$store_name.',';
-            }
+            $openid = WechatUser::where('uid',$order['uid'])->value('openid');
             WechatTemplateService::sendTemplate($openid,WechatTemplateService::ORDER_TAKE_SUCCESS,[
                 'first'=>'亲,您的订单已收货',
                 'keyword1'=>$order['order_id'],

+ 76 - 13
application/admin/model/store/StoreProduct.php

@@ -7,6 +7,9 @@
 
 namespace app\admin\model\store;
 
+use app\admin\model\ump\StoreBargain;
+use app\admin\model\ump\StoreCombination;
+use app\admin\model\ump\StoreSeckill;
 use service\PHPExcelService;
 use think\Db;
 use traits\ModelTrait;
@@ -149,6 +152,7 @@ class StoreProduct extends ModelBasic
             $item['sales_attr'] = self::getSales($item['id']);//属性销量
             $item['visitor'] = Db::name('store_visit')->where('product_id',$item['id'])->where('product_type','product')->count();
         }
+        unset($item);
         if($where['excel']==1){
             $export = [];
             foreach ($data as $index=>$item){
@@ -210,28 +214,58 @@ class StoreProduct extends ModelBasic
     }
     //获取 badge 内容
     public static function getbadge($where,$type){
-        $StoreOrderModel=new StoreOrder;
         $replenishment_num = SystemConfig::getValue('replenishment_num');
         $replenishment_num = $replenishment_num > 0 ? $replenishment_num : 20;
-        $stock1=self::getModelTime($where,new self())->where('stock','<',$replenishment_num)->column('stock');
-        $sum_stock=self::where('stock','<',$replenishment_num)->column('stock');
-        $stk=[];
+        $sum = [];
+        $lack = 0;
+
+        //获取普通产品缺货
+        $stock1 = self::getModelTime($where,new self())->where('stock','<',$replenishment_num)->column('stock');
+        $sum_stock = self::where('stock','<',$replenishment_num)->column('stock');
+        $stk = [];
+        foreach ($stock1 as $item){
+            $stk[] = $replenishment_num-$item;
+        }
+        $lack = bcadd($lack,array_sum($stk),0);
+        foreach ($sum_stock as $val){
+            $sum[] = $replenishment_num-$val;
+        }
+        unset($stk,$sum_stock,$stock1);
+
+        //获取砍价缺货产品
+        $stock1 = self::getModelTime($where,new StoreBargain())->where('stock','<',$replenishment_num)->column('stock');
+        $sum_stock = StoreBargain::where('stock','<',$replenishment_num)->column('stock');
+        $stk = [];
         foreach ($stock1 as $item){
-            $stk[]=$replenishment_num-$item;
+            $stk[] = $replenishment_num-$item;
         }
-        $lack=array_sum($stk);
-        $sum=[];
+        $lack = bcadd($lack,array_sum($stk),0);
         foreach ($sum_stock as $val){
-            $sum[]=$replenishment_num-$val;
+            $sum[] = $replenishment_num-$val;
         }
+        unset($stk,$sum_stock,$stock1);
+
+        //获取拼团缺货产品
+        $stock1 = self::getModelTime($where,new StoreCombination())->where('stock','<',$replenishment_num)->column('stock');
+        $sum_stock = StoreCombination::where('stock','<',$replenishment_num)->column('stock');
+        $stk = [];
+        foreach ($stock1 as $item){
+            $stk[] = $replenishment_num - $item;
+        }
+        $lack = bcadd($lack,array_sum($stk),0);
+        foreach ($sum_stock as $val){
+            $sum[] = $replenishment_num - $val;
+        }
+        unset($stk,$sum_stock,$stock1);
+
         return [
             [
-                'name'=>'商品数量',
+                'name'=>'商品种类',
                 'field'=>'件',
-                'count'=>self::setWhereType(new self(),$type)->where('add_time','<',mktime(0,0,0,date('m'),date('d'),date('Y')))->sum('stock'),
+                'count'=>self::setWhereType(new self(),$type)->where('add_time','<',mktime(0,0,0,date('m'),date('d'),date('Y')))->count(),
                 'content'=>'商品数量总数',
                 'background_color'=>'layui-bg-blue',
-                'sum'=>self::sum('stock'),
+                'sum'=>self::count(),
                 'class'=>'fa fa fa-ioxhost',
             ],
             [
@@ -246,10 +280,10 @@ class StoreProduct extends ModelBasic
             [
                 'name'=>'活动商品',
                 'field'=>'件',
-                'count'=>self::getModelTime($where,$StoreOrderModel)->sum('total_num'),
+                'count'=>self::getActivityProductSum($where),
                 'content'=>'活动商品总数',
                 'background_color'=>'layui-bg-green',
-                'sum'=>$StoreOrderModel->sum('total_num'),
+                'sum'=>self::getActivityProductSum(),
                 'class'=>'fa fa-bar-chart',
             ],
             [
@@ -263,6 +297,25 @@ class StoreProduct extends ModelBasic
             ],
         ];
     }
+
+    /*
+     * 获取活动产品总和
+     * @param array $where 查询条件
+     * */
+    public static function getActivityProductSum($where=false)
+    {
+        if($where){
+            $bargain=self::getModelTime($where,new StoreBargain())->sum('stock');
+            $pink=self::getModelTime($where,new StoreCombination())->sum('stock');
+            $seckill=self::getModelTime($where,new StoreSeckill())->sum('stock');
+        }else{
+            $bargain=StoreBargain::sum('stock');
+            $pink=StoreCombination::sum('stock');
+            $seckill=StoreSeckill::sum('stock');
+        }
+        return bcadd(bcadd($bargain,$pink,0),$seckill,0);
+    }
+
     public static function setWhereType($model,$type){
         switch ($type){
             case 1:
@@ -590,4 +643,14 @@ class StoreProduct extends ModelBasic
             ->page((int)$where['page'],(int)$where['limit'])
             ->select();
     }
+
+    /**
+     * TODO 获取某个字段值
+     * @param $id
+     * @param string $field
+     * @return mixed
+     */
+    public static function getProductField($id,$field = 'store_name'){
+        return self::where('id',$id)->value($field);
+    }
 }

+ 6 - 1
application/admin/model/store/StoreProductAttrValue.php

@@ -33,7 +33,12 @@ class StoreProductAttrValue extends ModelBasic
      * */
     public static function incProductAttrStock($productId,$unique,$num)
     {
-        return false !== self::where('product_id',$productId)->where('unique',$unique)->inc('stock',$num)->dec('sales',$num)->update();
+        $productAttr=self::where(['product_id'=>$productId,'unique'=>$unique])->field(['stock','sales'])->find();
+        if(!$productAttr) return true;
+        if($productAttr->sales > 0) $productAttr->sales=bcsub($productAttr->sales,$num,0);
+        if($productAttr->sales < 0) $productAttr->sales=0;
+        $productAttr->stock = bcadd($productAttr->stock, $num,0);
+        return $productAttr->save();
     }
 
     public static function decProductAttrStock($productId,$unique,$num)

+ 59 - 11
application/admin/model/system/SystemAttachment.php

@@ -7,6 +7,8 @@
 
 namespace app\admin\model\system;
 
+use Api\Storage\Qiniu\Qiniu;
+use app\core\util\SystemConfigService;
 use traits\ModelTrait;
 use basic\ModelBasic;
 
@@ -18,35 +20,81 @@ use basic\ModelBasic;
 class SystemAttachment extends ModelBasic
 {
     use ModelTrait;
-    /**添加附件记录
+
+    /**
+     * TODO 添加附件记录
+     * @param $name
+     * @param $att_size
+     * @param $att_type
+     * @param $att_dir
+     * @param string $satt_dir
+     * @param int $pid
+     * @param int $imageType
+     * @param int $time
+     * @return SystemAttachment
      */
-    public static function attachmentAdd($name,$att_size,$att_type,$att_dir,$satt_dir='',$pid = 0 )
+    public static function attachmentAdd($name,$att_size,$att_type,$att_dir,$satt_dir='',$pid = 0,$imageType = 1 ,$time = 0 , $module_type=1)
     {
         $data['name'] = $name;
         $data['att_dir'] = $att_dir;
         $data['satt_dir'] = $satt_dir;
         $data['att_size'] = $att_size;
         $data['att_type'] = $att_type;
-        $data['time'] = time();
+        $data['image_type'] = $imageType;
+        $data['module_type'] = $module_type;
+        $data['time'] = $time ? $time : time();
         $data['pid'] = $pid;
         return self::create($data);
     }
+
     /**
-     * 获取分类图
-     * */
+     * TODO 获取分类图
+     * @param $id
+     * @return array
+     */
     public static function getAll($id){
         $model = new self;
         $where['pid'] = $id;
+        $where['module_type'] = 1;
         $model->where($where)->order('att_id desc');
         return $model->page($model,$where,'',24);
     }
+
+    public static function getImageList($where)
+    {
+       $list = self::where(['pid'=>$where['pid'],'module_type'=>1])->page((int)$where['page'],(int)$where['limit'])->order('att_id desc,time desc')->select();
+       $list = count($list) ? $list->toArray() : [];
+        $site_url = SystemConfig::getValue('site_url');
+        foreach ($list as &$item){
+            $item['satt_dir'] = (strpos($item['satt_dir'],$site_url) !== false || strstr($item['satt_dir'],'http') !== false) ? $item['satt_dir']:$site_url.$item['satt_dir'];
+            $item['att_dir'] = (strpos($item['att_dir'],$site_url) !== false ||  strstr($item['att_dir'],'http') !== false) ? $item['satt_dir']:$site_url.$item['att_dir'];
+        }
+       $count = self::where(['pid'=>$where['pid'],'module_type'=>1])->count();
+       return compact('list','count');
+    }
+
     /**
-     * 获取单条信息
-     * */
-    public static function getinfo($att_id){
-        $model = new self;
-        $where['att_id'] = $att_id;
-        return $model->where($where)->select()->toArray()[0];
+     * TODO 获取单条信息
+     * @param $value
+     * @param string $field
+     * @return array
+     * @throws \think\Exception
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\ModelNotFoundException
+     * @throws \think\exception\DbException
+     */
+    public static function getInfo($value,$field = 'att_id'){
+        $where[$field] = $value;
+        $count = self::where($where)->count();
+        if(!$count) return false;
+        return self::where($where)->find()->toArray();
     }
 
+    /*
+     * 清除昨日海报
+     * */
+    public static function emptyYesterDayAttachment()
+    {
+        self::whereTime('time','yesterday')->where(['module_type'=>2])->delete();
+    }
 }

+ 13 - 6
application/admin/model/system/SystemAttachmentCategory.php

@@ -31,18 +31,25 @@ class SystemAttachmentCategory extends ModelBasic
         $data['pid'] = $pid;
         return self::create($data);
     }
-    /**
-     * 获取分类图
-     * */
-    public static function getAll(){
+    public static function getAll($name){
         $model = new self;
-        return self::tidyMenuTier($model->select(),0);
+        if($name) $model = $model->where('name','LIKE',"%$name%");
+        $navList = $model->select();
+        $navList = count($navList) ? $navList->toArray() : [];
+        $navPidList = [];
+        if($name) {
+            foreach ($navList as $value) {
+                if ($value['pid']) $navPidList [] = self::where('id', $value['pid'])->find();
+            }
+        }
+        return self::tidyMenuTier(array_merge($navList,$navPidList),0);
     }
+
     public static function tidyMenuTier($menusList,$pid = 0,$navList = [])
     {
 
         foreach ($menusList as $k=>$menu){
-            $menu = $menu->getData();
+            $menu = is_object($menu) ? $menu->getData() : $menu;
             if($menu['pid'] == $pid){
                 unset($menusList[$k]);
                 $menu['child'] = self::tidyMenuTier($menusList,$menu['id']);

+ 13 - 1
application/admin/model/system/SystemConfig.php

@@ -67,6 +67,18 @@ class SystemConfig extends ModelBasic {
         if(empty($menu) || !($config_one = self::get(['menu_name'=>$menu]))) return false;
         return json_decode($config_one['value'],true);
     }
+    /**
+     * 获取单个参数配置
+     * @param $menu
+     * @return bool|mixed
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\ModelNotFoundException
+     * @throws \think\exception\DbException
+     */
+    public static function getConfigValue($menu){
+        if(empty($menu) || !($config_one = self::where('menu_name', $menu)->find())) return false;
+        return json_decode($config_one['value'],true);
+    }
 
     /**
      * 获得多个参数
@@ -157,7 +169,7 @@ class SystemConfig extends ModelBasic {
      * */
     public static function getAll($id){
         $where['config_tab_id'] = $id;
-//        $where['status'] = 1;
+        $where['status'] = 1;
         return self::where($where)->order('sort desc,id asc')->select();
     }
 

+ 1 - 0
application/admin/model/system/SystemUserLevel.php

@@ -35,6 +35,7 @@ class SystemUserLevel extends ModelBasic
         $model=$model===null ? new self() : $model;
         if($alert) $model=$model->alias($alert);
         $alert=$alert ? $alert.'.': '';
+        $model = $model->where("{$alert}is_del",0);
         if(isset($where['is_show']) && $where['is_show']!=='') $model=$model->where("{$alert}is_show",$where['is_show']);
         if(isset($where['title']) && $where['title']) $model=$model->where("{$alert}name",'LIKE',"%$where[title]%");
         return $model;

+ 17 - 7
application/admin/model/ump/StoreSeckill.php

@@ -117,12 +117,12 @@ class StoreSeckill extends ModelBasic
         }
         return [
             [
-                'name'=>'商品数量',
+                'name'=>'商品种类',
                 'field'=>'件',
-                'count'=>self::setWhereType(new self(),$type)->where('add_time','<',mktime(0,0,0,date('m'),date('d'),date('Y')))->sum('stock'),
-                'content'=>'商品数量总数',
+                'count'=>self::setWhereType(new self(),$type)->where('add_time','<',mktime(0,0,0,date('m'),date('d'),date('Y')))->count(),
+                'content'=>'商品种类总数',
                 'background_color'=>'layui-bg-blue',
-                'sum'=>self::sum('stock'),
+                'sum'=>self::count(),
                 'class'=>'fa fa fa-ioxhost',
             ],
             [
@@ -135,12 +135,12 @@ class StoreSeckill extends ModelBasic
                 'class'=>'fa fa-line-chart',
             ],
             [
-                'name'=>'活动商品',
+                'name'=>'秒杀成功商品件数',
                 'field'=>'件',
                 'count'=>self::getModelTime($where,$StoreOrderModel)->where('seckill_id','NEQ',0)->sum('total_num'),
-                'content'=>'活动商品总数',
+                'content'=>'秒杀成功商品总件数',
                 'background_color'=>'layui-bg-green',
-                'sum'=>$StoreOrderModel->sum('total_num'),
+                'sum'=>$StoreOrderModel->where('seckill_id','NEQ',0)->sum('total_num'),
                 'class'=>'fa fa-bar-chart',
             ],
             [
@@ -328,4 +328,14 @@ class StoreSeckill extends ModelBasic
     public static function getSeckillCount(){
         return self::where('is_del',0)->count();
     }
+
+    /**
+     * TODO 获取某个字段值
+     * @param $id
+     * @param string $field
+     * @return mixed
+     */
+    public static function getSeckillField($id,$field = 'title'){
+        return self::where('id',$id)->value($field);
+    }
 }

+ 77 - 23
application/admin/model/user/User.php

@@ -42,6 +42,36 @@ class User extends ModelBasic
             }
         },$where);
     }
+
+    /*
+     * 获取和提现金额
+     * @param array $uid
+     * @return float
+     * */
+    public static function getextractPrice($uid,$where=[])
+    {
+        if(is_array($uid))
+            if(!count($uid)) return 0;
+        else
+            $uid = [$uid];
+        $brokerage= UserBill::getBrokerage($uid,'now_money','brokerage',$where);//获取总佣金
+        $recharge = UserBill::getBrokerage($uid,'now_money','recharge',$where);//累计充值
+        $extractTotalPrice = UserExtract::userExtractTotalPrice($uid,1,$where);//累计提现
+        if($brokerage > $extractTotalPrice) {
+            $orderYuePrice = self::getModelTime($where,StoreOrder::where('uid','in',$uid)->where(['is_del'=>0,'paid'=>1]))->sum('pay_price');//余额累计消费
+            $systemAdd = UserBill::getBrokerage($uid,'now_money','system_add',$where);//后台添加余额
+            $yueCount = bcadd($recharge,$systemAdd,2);// 后台添加余额 + 累计充值  = 非佣金的总金额
+            $orderYuePrice = $yueCount > $orderYuePrice ? 0 : bcsub($orderYuePrice,$yueCount,2);// 余额累计消费(使用佣金消费的金额)
+            $brokerage = bcsub($brokerage,$extractTotalPrice,2);//减去已提现金额
+            $extract_price = UserExtract::userExtractTotalPrice($uid,0,$where);
+            $brokerage = $extract_price < $brokerage ? bcsub($brokerage,$extract_price,2) : 0;//减去审核中的提现金额
+            $brokerage = $brokerage > $orderYuePrice ? bcsub($brokerage,$orderYuePrice,2) : 0;//减掉余额支付
+        }else{
+            $brokerage=0;
+        }
+        $num = (float)bcsub($brokerage,$extractTotalPrice,2);
+        return $num > 0 ? $num : 0;//可提现
+    }
     /*
      * 设置搜索条件
      *
@@ -363,12 +393,16 @@ class User extends ModelBasic
     }
     //获取用户新增,头部信息
     public static function getBadgeList($where){
-        $user_count=self::setWherePage(self::getModelTime($where,new self),$where,['is_promoter','status'])->count();
-        $user_count_old=self::getOldDate($where)->count();
-        $fenxiao=self::setWherePage(self::getModelTime($where,new self),$where,['is_promoter','status'])->where('spread_uid','<>',0)->count();
-        $fenxiao_count=self::getOldDate($where)->where('spread_uid','neq',0)->count();
-        $newFemxiao_count=bcsub($fenxiao,$fenxiao_count,0);
-        $order_count=bcsub($user_count,$user_count_old,0);
+        $user_count             = self::setWherePage(self::getModelTime($where,new self),$where,['is_promoter','status'])->count();
+        $user_count_old         = self::getOldDate($where)->count();
+        $store_brokerage_statu  = SystemConfigService::get('store_brokerage_statu');
+        if($store_brokerage_statu == 1)
+            $fenxiao            = self::setWherePage(self::getModelTime($where,new self),$where,['is_promoter','status'])->where('spread_uid','<>',0)->count();
+        else
+            $fenxiao            = self::count();
+        $fenxiao_count          = self::getOldDate($where)->where('spread_uid','neq',0)->count();
+        $newFemxiao_count       = bcsub($fenxiao,$fenxiao_count,0);
+        $order_count            = bcsub($user_count,$user_count_old,0);
         return [
             [
                 'name'=>'会员人数',
@@ -394,7 +428,7 @@ class User extends ModelBasic
                 'count'=>$fenxiao,
                 'content'=>'分销总人数',
                 'background_color'=>'layui-bg-green',
-                'sum'=>self::where('spread_uid','neq',0)->count(),
+                'sum'=>$store_brokerage_statu == 1 ? self::where('spread_uid','neq',0)->count() : $fenxiao,
                 'class'=>'fa fa-bar-chart',
             ],
             [
@@ -414,28 +448,28 @@ class User extends ModelBasic
      *  $limit 显示条数,是否有滚动条
      */
     public static function getUserChartList($where,$limit=20){
-        $list=self::setWherePage(self::getModelTime($where,new self),$where,['is_promoter','status'])
+        $list = self::setWherePage(self::getModelTime($where,new self),$where,['is_promoter','status'])
             ->where('add_time','neq',0)
             ->field(['FROM_UNIXTIME(add_time,"%Y-%m-%d") as _add_time','count(uid) as num'])
             ->order('_add_time asc')
             ->group('_add_time')
             ->select();
-         count($list) && $list=$list->toArray();
-         $seriesdata=[];
-         $xdata=[];
-         $Zoom='';
+         count($list) && $list = $list->toArray();
+         $seriesdata = [];
+         $xdata = [];
+         $Zoom = '';
          foreach ($list as $item){
-             $seriesdata[]=$item['num'];
-             $xdata[]=$item['_add_time'];
+             $seriesdata[] = $item['num'];
+             $xdata[] = $item['_add_time'];
          }
-        (count($xdata) > $limit) && $Zoom=$xdata[$limit-5];
+        (count($xdata) > $limit) && $Zoom = $xdata[$limit-5];
         //多次购物会员数量饼状图
-        $count=self::setWherePage(self::getModelTime($where,new self),$where,['is_promoter'])->count();
-        $user_count=self::setWherePage(self::getModelTime($where,self::alias('a')->join('__STORE_ORDER__ r','r.uid=a.uid'),'a.add_time'),$where,['is_promoter'])
+        $count = self::setWherePage(self::getModelTime($where,new self),$where,['is_promoter'])->count();
+        $user_count = self::setWherePage(self::getModelTime($where,self::alias('a')->join('__STORE_ORDER__ r','r.uid=a.uid'),'a.add_time'),$where,['is_promoter'])
             ->where('r.paid',1)->count('a.uid');
-        $shop_xdata=['多次购买数量占比','无购买数量占比'];
-        $shop_data=[];
-        $count >0 && $shop_data=[
+        $shop_xdata = ['多次购买数量占比','无购买数量占比'];
+        $shop_data = [];
+        $count >0 && $shop_data = [
             [
                 'value'=>bcdiv($user_count,$count,2)*100,
                 'name'=>$shop_xdata[0],
@@ -522,13 +556,33 @@ class User extends ModelBasic
     }
     //获取佣金记录列表
     public static function getCommissionList($where){
-        $list=self::setCommissionWhere($where)
-            ->page((int)$where['page'],(int)$where['limit'])
-            ->select();
+        $model = self::setCommissionWhere($where);
+        if($where['excel'])
+            $list = $model->select();
+        else
+            $list = $model->page((int)$where['page'],(int)$where['limit'])->select();
         count($list) && $list=$list->toArray();
+        $export=[];
         foreach ($list as &$value){
             $value['ex_price']= Db::name('user_extract')->where(['uid'=>$value['uid']])->sum('extract_price');
             $value['extract_price']= Db::name('user_extract')->where(['uid'=>$value['uid'],'status'=>1])->sum('extract_price');
+            $cashPrice = Db::name('user_extract')->where(['uid'=>$value['uid'],'status'=>0])->sum('extract_price');
+            $value['money'] = bcsub($value['ex_price'],$value['extract_price'],2);
+            $value['money'] = bcsub($value['money'],$cashPrice,2);
+            $export[]=[
+                $value['nickname'],
+                $value['sum_number'],
+                $value['now_money'],
+                $value['money'],
+                $value['ex_price'],
+                $value['extract_price'],
+            ];
+        }
+        if($where['excel']){
+            \service\PHPExcelService::setExcelHeader(['昵称/姓名','总佣金金额','提现佣金','余额','剩余佣金','提现到账佣金'])
+                ->setExcelTile('拥金记录','拥金记录'.time(),' 生成时间:'.date('Y-m-d H:i:s',time()))
+                ->setExcelContent($export)
+                ->ExcelSave();
         }
         $count=self::setCommissionWhere($where)->count();
         return ['data'=>$list,'count'=>$count];

+ 9 - 1
application/admin/model/user/UserBill.php

@@ -22,6 +22,14 @@ class UserBill extends ModelBasic
     {
         return time();
     }
+
+    /*
+     * 获取总佣金
+     * */
+    public static function getBrokerage($uid,$category = 'now_money',$type='brokerage',$where)
+    {
+        return self::getModelTime($where,self::where('uid','in',$uid)->where(['category'=>$category,'type'=>$type,'pm'=>1,'status'=>1]))->sum('number');
+    }
     //修改积分减少积分记录
     public static function expend($title,$uid,$category,$type,$number,$link_id = 0,$balance = 0,$mark = '',$status = 1)
     {
@@ -241,7 +249,7 @@ class UserBill extends ModelBasic
     public static function getScoreBadgeList($where){
         return [
             [
-                'name'=>'总积分',
+                'name'=>'历史总积分',
                 'field'=>'个',
                 'count'=>self::getModelTime($where,new self())->where('category','integral')->where('type','in',['gain','system_sub','deduction','sign'])->sum('number'),
                 'background_color'=>'layui-bg-blue',

+ 85 - 23
application/admin/model/user/UserExtract.php

@@ -11,6 +11,7 @@ namespace app\admin\model\user;
 use app\admin\model\user\User;
 use app\admin\model\user\UserBill;
 use app\admin\model\wechat\WechatUser;
+use app\core\model\routine\RoutineTemplate;
 use think\Url;
 use traits\ModelTrait;
 use basic\ModelBasic;
@@ -23,6 +24,16 @@ use app\core\util\WechatTemplateService;
 class UserExtract extends ModelBasic
 {
     use ModelTrait;
+
+    /**
+     * 获得用户提现总金额
+     * @param $uid
+     * @return mixed
+     */
+    public static function userExtractTotalPrice($uid,$status=1,$where=[])
+    {
+        return self::getModelTime($where,self::where('uid','in',$uid)->where('status',$status))->sum('extract_price')?:0;
+    }
     /**
      * @param $where
      * @return array
@@ -51,37 +62,75 @@ class UserExtract extends ModelBasic
         $User= User::find(['uid'=>$uid])->toArray();
         UserBill::income('提现失败',$uid,'now_money','extract',$extract_number,$id,bcadd($User['now_money'],$extract_number,2),$mark);
         User::bcInc($uid,'now_money',$extract_number,'uid');
-        if($User['user_type'] == 'wechat'){
-            WechatTemplateService::sendTemplate(WechatUser::uidToOpenid($uid),WechatTemplateService::USER_BALANCE_CHANGE,[
+        $extract_type='未知方式';
+        switch ($data['extract_type']){
+            case 'alipay':
+                $extract_type='支付宝';
+                break;
+            case 'bank':
+                $extract_type='银行卡';
+                break;
+            case 'weixin':
+                $extract_type='微信';
+                break;
+        }
+        if(strtolower($User['user_type']) == 'wechat'){
+            WechatTemplateService::sendTemplate(WechatUser::where('uid',$uid)->value('openid'),WechatTemplateService::USER_BALANCE_CHANGE,[
                 'first'=> $mark,
                 'keyword1'=>'佣金提现',
                 'keyword2'=>date('Y-m-d H:i:s',time()),
                 'keyword3'=>$extract_number,
                 'remark'=>'错误原因:'.$fail_msg
             ],Url::build('wap/my/user_pro',[],true,true));
+        }else if(strtolower($User['user_type'])=='routine'){
+            RoutineTemplate::sendOut('USER_EXTRACT_FALSE',$uid,[
+                'keyword1'=>$fail_msg,
+                'keyword2'=>$extract_number,
+                'keyword3'=>$extract_type,
+                'keyword4'=>date('Y-m-d H:i:s',time()),
+            ]);
         }
-
         return self::edit(compact('fail_time','fail_msg','status'),$id);
     }
 
     public static function changeSuccess($id)
     {
-        $status = 1;
-        $data =self::get($id);
-        $extract_number=$data['extract_price'];
-        $mark='成功提现佣金'.$extract_number.'元';
-        $uid=$data['uid'];
-        $User= User::find(['uid'=>$uid])->toArray();
-        if($User['user_type'] == 'wechat') {
-            WechatTemplateService::sendTemplate(WechatUser::uidToOpenid($uid), WechatTemplateService::USER_BALANCE_CHANGE, [
-                'first' => $mark,
-                'keyword1' => '佣金提现',
-                'keyword2' => date('Y-m-d H:i:s', time()),
-                'keyword3' => $extract_number,
-                'remark' => '点击查看我的佣金明细'
-            ], Url::build('wap/my/user_pro', [], true, true));
+
+        $data = self::get($id);
+        $extractNumber = $data['extract_price'];
+        $mark = '成功提现佣金'.$extractNumber.'元';
+        $wechatUserInfo = WechatUser::where('uid',$data['uid'])->field(['openid','user_type','routine_openid'])->find();
+        $extract_type='未知方式';
+        switch ($data['extract_type']){
+            case 'alipay':
+                $extract_type='支付宝';
+                break;
+            case 'bank':
+                $extract_type='银行卡';
+                break;
+            case 'weixin':
+                $extract_type='微信';
+                break;
         }
-        return self::edit(compact('status'),$id);
+        if($wechatUserInfo){
+            if(strtolower($wechatUserInfo->user_type)=='routine'){
+                RoutineTemplate::sendOut('USER_EXTRACT_TRUE',$data['uid'],[
+                    'keyword1'=>$extractNumber.'元',
+                    'keyword2'=>'审核成功',
+                    'keyword3'=>date('Y-m-d H:i:s', time()),
+                    'keyword4'=>$extract_type,
+                ]);
+            }else if(strtolower($wechatUserInfo->user_type)=='wechat'){
+                WechatTemplateService::sendTemplate($wechatUserInfo->openid, WechatTemplateService::USER_BALANCE_CHANGE, [
+                    'first' => $mark,
+                    'keyword1' => '佣金提现',
+                    'keyword2' => date('Y-m-d H:i:s', time()),
+                    'keyword3' => $extractNumber,
+                    'remark' => '点击查看我的佣金明细'
+                ], Url::build('wap/my/user_pro', [], true, true));
+            }
+        }
+        return self::edit(['status'=>1],$id);
     }
     //测试数据
     public static function test(){
@@ -249,10 +298,16 @@ class UserExtract extends ModelBasic
      * @param int $uid
      * @return int|mixed
      */
-    public static function getUserCountPrice($uid = 0){
+    public static function getUserCountPrice($uid = 0,$where=[]){
         if(!$uid) return 0;
-        $price = self::where('uid',$uid)->where('status',1)->field('sum(extract_price) as price')->find()['price'];
-        return $price ? $price : 0;
+        $model = new self();
+        if(is_array($uid)){
+            $model = $model->where('uid','in',$uid);
+        }else{
+            $model = $model->where('uid',$uid);
+        }
+        if($where) $model = self::getModelTime($where,$model);
+        return $model->where('status',1)->sum('extract_price');
     }
 
     /**
@@ -260,8 +315,15 @@ class UserExtract extends ModelBasic
      * @param int $uid
      * @return int|string
      */
-    public static function getUserCountNum($uid = 0){
+    public static function getUserCountNum($uid = 0,$where=[]){
         if(!$uid) return 0;
-        return self::where('uid',$uid)->count();
+        $model = new self();
+        if(is_array($uid)){
+            $model = $model->where('uid','in',$uid);
+        }else{
+            $model = $model->where('uid',$uid);
+        }
+        if($where) $model = self::getModelTime($where,$model);
+        return $model->count();
     }
 }

+ 21 - 5
application/admin/model/user/UserLevel.php

@@ -1,10 +1,6 @@
 <?php
-/**
- *
- * @author: xaboy<365615158@qq.com>
- * @day: 2017/11/11
- */
 namespace app\admin\model\user;
+
 use app\admin\model\system\SystemUserLevel;
 use traits\ModelTrait;
 use basic\ModelBasic;
@@ -51,4 +47,24 @@ class UserLevel extends ModelBasic
         return compact('data','count');
     }
 
+    /*
+     * 清除会员等级
+     * @paran int $uid
+     * @paran boolean
+     * */
+    public static function cleanUpLevel($uid)
+    {
+        self::rollbackTrans();
+        $res=false !== self::where(['uid'=>$uid])->update(['is_del'=>1]);
+        $res= $res && self::getDb('user_task_finish')->where(['uid'=>$uid])->delete();
+        if($res){
+            User::where(['uid'=>$uid])->update(['clean_time'=>time()]);
+            self::commitTrans();
+            return true;
+        }else{
+            self::rollbackTrans();
+            return self::setErrorInfo('清除失败');
+        }
+    }
+
 }

+ 1 - 1
application/admin/model/user/UserRecharge.php

@@ -29,7 +29,7 @@ use basic\ModelBasic;
              $model = $model->whereOr('A.id',(int)$where['order_id']);
              $model = $model->whereOr('B.nickname','like',"%$where[order_id]%");
          }
-         $model = $model->where('A.recharge_type','weixin');
+         //$model = $model->where('A.recharge_type','weixin');
          $model = $model->where('A.paid',1);
          $model = $model->field('A.*,B.nickname');
          $model = $model->join('__USER__ B','A.uid = B.uid','RIGHT');

+ 3 - 1
application/admin/model/wechat/WechatReply.php

@@ -113,7 +113,9 @@ class WechatReply extends ModelBasic
             $res = [];
             //TODO 图片转media
             $res['src'] = $data['src'];
-            $material = (WechatService::materialService()->uploadImage(UtilService::urlToPath($data['src'])));
+            if(strstr($data['src'],'http') === false) $data['src'] = UtilService::urlToPath($data['src']);
+            $data['src'] = strstr($data['src'],'public');
+            $material = (WechatService::materialService()->uploadImage($data['src']));
             $res['media_id'] = $material->media_id;
             HookService::afterListen('wechat_material',
                 ['media_id' => $material->media_id, 'path' => $res['src'], 'url' => $material->url], 'image');

+ 465 - 79
application/admin/model/wechat/WechatUser.php

@@ -9,7 +9,9 @@ namespace app\admin\model\wechat;
 
 
 use app\admin\model\order\StoreOrder;
+use app\admin\model\order\StoreOrderStatus;
 use app\admin\model\user\User;
+use app\admin\model\user\UserBill;
 use app\admin\model\user\UserExtract;
 use service\ExportService;
 use app\core\util\QrcodeService;
@@ -154,75 +156,478 @@ use app\core\util\SystemConfigService;
         }
         return self::page($model,$where);
     }
-/**
-     * 获取分销用户
+
+    public static function setSpreadWhere($where=[],$alias='a',$model=null)
+    {
+        $model=is_null($model) ? new  self() : $model;
+        if($alias){
+            $model=$model->alias($alias)->join('user u','a.uid=u.uid')->order('u.uid desc');
+            $alias.='.';
+        }
+        $status = (int)SystemConfigService::get('store_brokerage_statu');
+        if ($status == 1) {
+            if ($uids = User::where(['is_promoter' => 1])->column('uid'))
+                $model = $model->where($alias.'uid', 'in', implode(',', $uids));
+            else
+                $model = $model->where($alias.'uid',-1);
+        }
+        if($where['nickname'] !== '') $model = $model->where("{$alias}nickname|{$alias}uid|u.phone",'LIKE',"%$where[nickname]%");
+        if((isset($where['start_time']) && isset($where['end_time'])) && $where['start_time'] !== '' && $where['end_time'] !== ''){
+            $model = $model->where("{$alias}add_time",'between',[strtotime($where['start_time']),strtotime($where['end_time'])]);
+        }
+        if(isset($where['sex']) && $where['sex'] !== '' ) $model = $model->where($alias.'sex',$where['sex']);
+        if(isset($where['subscribe']) && $where['subscribe'] !== '' ) $model = $model->where($alias.'subscribe',$where['subscribe']);
+        if(isset($where['order']) && $where['order'] != '') $model = $model->order($where['order']);
+        if(isset($where['user_type']) && $where['user_type']!='') {
+            if($where['user_type']==1){
+                $model=$model->where($alias.'unionid','neq','NULL');
+            }else if($where['user_type']==2)
+                $model=$model->where($alias.'openid','neq','NULL')->where($alias.'unionid','NULL');
+            else if($where['user_type']==3)
+                $model=$model->where($alias.'routine_openid','neq','NULL')->where($alias.'unionid','NULL');
+        }
+        if(isset($where['is_time']) && isset($where['data']) && $where['data']) $model = self::getModelTime($where,$model,$alias.'add_time');
+        return $model;
+    }
+
+    public static function setSairOrderWhere($where,$model = null,$alias='')
+    {
+        $model = $model === null ? new self() : $model;
+        if(!isset($where['uid'])) return $model;
+        if($alias){
+            $model = $model->alias($alias);
+            $alias .= '.';
+        }
+        if(isset($where['type'])){
+            switch ((int)$where['type']){
+                case 1:
+                    $uids = User::where('spread_uid',$where['uid'])->column('uid');
+                    if(count($uids))
+                        $model = $model->where("{$alias}uid",'in',$uids);
+                    else
+                        $model = $model->where("{$alias}uid",0);
+                    break;
+                case 2:
+                    $uids = User::where('spread_uid',$where['uid'])->column('uid');
+                    if(count($uids))
+                        $spread_uid_two=User::where('spread_uid','in',$uids)->column('uid');
+                    else
+                        $spread_uid_two=[0];
+                    if(count($spread_uid_two))
+                        $model = $model->where("{$alias}uid",'in',$spread_uid_two);
+                    else
+                        $model = $model->where("{$alias}uid",0);
+                    break;
+                default:
+                    $uids = User::where('spread_uid',$where['uid'])->column('uid');
+                    if(count($uids)) {
+                        if($spread_uid_two = User::where('spread_uid', 'in', $uids)->column('uid')){
+                            $uids = array_merge($uids,$spread_uid_two);
+                            $uids = array_unique($uids);
+                            $uids = array_merge($uids);
+                        }
+                        $model = $model->where("{$alias}uid",'in',$uids);
+                    }else
+                        $model = $model->where("{$alias}uid",0);
+                    break;
+            }
+        }
+        if(isset($where['data']) && $where['data']) $model = self::getModelTime($where,$model,"{$alias}add_time");
+        return $model->where("{$alias}is_del",0)->where("{$alias}is_system_del",0)->where($alias.'paid',1);
+    }
+
+    /*
+     *  推广订单统计
      * @param array $where
      * @return array
-     */
-    public static function agentSystemPage($where = array(),$isall=false){
-//        self::setWechatUserOrder();//设置 一级推荐人 二级推荐人 一级推荐人订单 二级推荐人订单 佣金
-        $model = new self;
-        if($isall==false) {
-            $status = (int)SystemConfigService::get('store_brokerage_statu');
-            if ($status == 1) {
-                if ($uids = User::where(['is_promoter' => 1])->column('uid')) {
-                    $model = $model->where('uid', 'in', implode(',', $uids));
-                }
+     * */
+    public static function getStairOrderBadge($where)
+    {
+        if(!isset($where['uid'])) return [];
+        $data['order_count'] = self::setSairOrderWhere($where,new StoreOrder())->count();
+        $data['order_price'] = self::setSairOrderWhere($where,new StoreOrder())->sum('pay_price');
+        $ids = self::setSairOrderWhere($where,new StoreOrder())->where(['paid'=>1,'is_del'=>0,'refund_status'=>0])->where('status','>',1)->column('id');
+        $data['number_price'] = 0;
+        if(count($ids)) $data['number_price'] = UserBill::where(['category'=>'now_money','type'=>'brokerage','uid'=>$where['uid']])->where('link_id','in',$ids)->sum('number');
+        $where['type'] = 1;
+        $data['one_price'] = self::setSairOrderWhere($where,new StoreOrder())->sum('pay_price');
+        $data['one_count'] = self::setSairOrderWhere($where,new StoreOrder())->count();
+        $where['type'] = 2;
+        $data['two_price'] = self::setSairOrderWhere($where,new StoreOrder())->sum('pay_price');
+        $data['two_count'] = self::setSairOrderWhere($where,new StoreOrder())->count();
+        return [
+            [
+                'name'=>'总金额',
+                'field'=>'元',
+                'count'=>$data['order_price'],
+                'background_color'=>'layui-bg-cyan',
+                'col'=>3,
+            ],
+            [
+                'name'=>'订单总数',
+                'field'=>'单',
+                'count'=>$data['order_count'],
+                'background_color'=>'layui-bg-cyan',
+                'col'=>3,
+            ],
+            [
+                'name'=>'返佣总金额',
+                'field'=>'元',
+                'count'=>$data['number_price'],
+                'background_color'=>'layui-bg-cyan',
+                'col'=>3,
+            ],
+            [
+                'name'=>'一级总金额',
+                'field'=>'元',
+                'count'=>$data['one_price'],
+                'background_color'=>'layui-bg-cyan',
+                'col'=>3,
+            ],
+            [
+                'name'=>'一级订单数',
+                'field'=>'单',
+                'count'=>$data['one_count'],
+                'background_color'=>'layui-bg-cyan',
+                'col'=>3,
+            ],
+            [
+                'name'=>'二级总金额',
+                'field'=>'元',
+                'count'=>$data['two_price'],
+                'background_color'=>'layui-bg-cyan',
+                'col'=>3,
+            ],
+            [
+                'name'=>'二级订单数',
+                'field'=>'单',
+                'count'=>$data['two_count'],
+                'background_color'=>'layui-bg-cyan',
+                'col'=>3,
+            ],
+        ];
+    }
+
+    /*
+     * 推广订单
+     * @param array $where
+     * @return array
+     * */
+    public static function getStairOrderList($where)
+    {
+        if(!isset($where['uid'])) return [];
+        $data = self::setSairOrderWhere($where,new StoreOrder())->page((int)$where['page'],(int)$where['limit'])->select();
+        $data = count($data) ? $data->toArray() : [];
+        $Info = User::where('uid',$where['uid'])->find();
+        foreach ($data as &$item){
+            $userInfo = User::where('uid',$item['uid'])->find();
+            $item['user_info']  = '';
+            $item['avatar']     = '';
+            if($userInfo){
+                $item['user_info']  = $userInfo->nickname.'|'.($userInfo->phone ? $userInfo->phone .'|' : '').$userInfo->real_name;
+                $item['avatar']     = $userInfo->avatar;
             }
+            $item['spread_info'] = $Info->nickname."|".($Info->phone ? $Info->phone."|" : '').$Info->uid;
+            $item['number_price'] = UserBill::where(['category'=>'now_money','type'=>'brokerage','link_id'=>$item['id']])->value('number');
+            $item['_pay_time'] = date('Y-m-d H:i:s',$item['pay_time']);
+            $item['_add_time'] = date('Y-m-d H:i:s',$item['add_time']);
+            $item['take_time'] = ($change_time = StoreOrderStatus::where(['change_type'=>'user_take_delivery','oid'=>$item['id']])->value('change_time')) ?
+                date('Y-m-d H:i:s',$change_time) : '暂无';
         }
-//        $model = $model->where('openid','NOT NULL');
-        if($where['nickname'] !== '') $model = $model->where('nickname','LIKE',"%$where[nickname]%");
-        if($where['data'] !== ''){
-            list($startTime,$endTime) = explode(' - ',$where['data']);
-            $model = $model->where('add_time','>',strtotime($startTime));
-            $model = $model->where('add_time','<',strtotime($endTime));
+        $count = self::setSairOrderWhere($where,new StoreOrder())->count();
+        return compact('data','count');
+    }
+    /*
+     * 设置查询条件
+     * @param array $where
+     * @param object $model
+     * @param string $alias
+     * */
+    public static function setSairWhere($where,$model = null,$alias='')
+    {
+        $model = $model === null ? new self() : $model;
+        if(!isset($where['uid'])) return $model;
+        if($alias){
+            $model = $model->alias($alias);
+            $alias .= '.';
         }
-        if(isset($where['tagid_list']) && $where['tagid_list'] !== ''){
-            $tagid_list = explode(',',$where['tagid_list']);
-            foreach ($tagid_list as $v){
-                $model = $model->where('tagid_list','LIKE',"%$v%");
+        if(isset($where['type'])){
+            switch ((int)$where['type']){
+                case 1:
+                    $uids = User::where('spread_uid',$where['uid'])->column('uid');
+                    if(count($uids))
+                        $model = $model->where("{$alias}uid",'in',$uids);
+                    else
+                        $model = $model->where("{$alias}uid",0);
+                    break;
+                case 2:
+                    $uids = User::where('spread_uid',$where['uid'])->column('uid');
+                    if(count($uids))
+                        $spread_uid_two=User::where('spread_uid','in',$uids)->column('uid');
+                    else
+                        $spread_uid_two=[0];
+                    if(count($spread_uid_two))
+                        $model = $model->where("{$alias}uid",'in',$spread_uid_two);
+                    else
+                        $model = $model->where("{$alias}uid",0);
+                    break;
+                default:
+                    $uids = User::where('spread_uid',$where['uid'])->column('uid');
+                    if(count($uids)) {
+                        if($spread_uid_two = User::where('spread_uid', 'in', $uids)->column('uid')){
+                            $uids = array_merge($uids,$spread_uid_two);
+                            $uids = array_unique($uids);
+                            $uids = array_merge($uids);
+                        }
+                        $model = $model->where("{$alias}uid",'in',$uids);
+                    }else
+                        $model = $model->where("{$alias}uid",0);
+                    break;
             }
         }
-        if(isset($where['groupid']) && $where['groupid'] !== '-1' ) $model = $model->where('groupid',"$where[groupid]");
-        if(isset($where['sex']) && $where['sex'] !== '' ) $model = $model->where('sex',"$where[sex]");
-        if(isset($where['subscribe']) && $where['subscribe'] !== '' ) $model = $model->where('subscribe',"$where[subscribe]");
-        if(isset($where['stair']) && $where['stair'] != '') $model = $model->order($where['stair']);
-        if(isset($where['second']) && $where['second'] != '') $model = $model->order($where['second']);
-        if(isset($where['order_stair']) && $where['order_stair'] != '') $model = $model->order($where['order_stair']);
-        if(isset($where['order_second']) && $where['order_second'] != '') $model = $model->order($where['order_second']);
-        if(isset($where['now_money']) && $where['now_money'] != '') $model = $model->order($where['now_money']);
-        $model = $model->order('uid desc');
-        if(isset($where['export']) && $where['export'] == 1){
-            $list = $model->select()->toArray();
+        if(isset($where['data']) && $where['data']) $model = self::getModelTime($where,$model,"{$alias}add_time");
+        if(isset($where['nickname']) && $where['nickname']) $model = $model->where("{$alias}phone|{$alias}nickname|{$alias}real_name|{$alias}uid",'LIKE',"%$where[nickname]%");
+        return $model->where($alias.'status',1);
+    }
+
+
+    public static function getStairList($where)
+    {
+        if(!isset($where['uid'])) return [];
+        $data = self::setSairWhere($where,new User())->page((int)$where['page'],(int)$where['limit'])->select();
+        $data = count($data) ? $data->toArray() : [];
+        $userInfo = User::where('uid',$where['uid'])->find();
+        foreach ($data as &$item){
+            $item['spread_count'] = User::where('spread_uid',$item['uid'])->count();
+            $item['order_count'] = StoreOrder::where('uid',$item['uid'])->where(['paid'=>1,'is_del'=>0])->count();
+            $item['promoter_name'] = $item['is_promoter'] ? '是' : '否';
+            $item['add_time'] = date("Y-m-d H:i:s",$item['add_time']);
+        }
+        $count = self::setSairWhere($where,new User())->count();
+        return compact('data','count');
+    }
+
+    public static function getSairBadge($where)
+    {
+        $data['number'] = self::setSairWhere($where,new User())->count();
+        $where['type'] = 1;
+        $data['one_number'] = self::setSairWhere($where,new User())->count();
+        $where['type'] = 2;
+        $data['two_number'] = self::setSairWhere($where,new User())->count();
+        $col = $data['two_number'] > 0 ? 4 : 6;
+        return [
+            [
+                'name'=>'总人数',
+                'field'=>'人',
+                'count'=>$data['number'],
+                'background_color'=>'layui-bg-cyan',
+                'col'=>$col,
+            ],
+            [
+                'name'=>'一级人数',
+                'field'=>'人',
+                'count'=>$data['one_number'],
+                'background_color'=>'layui-bg-cyan',
+                'col'=>$col,
+            ],
+            [
+                'name'=>'二级人数',
+                'field'=>'人',
+                'count'=>$data['two_number'],
+                'background_color'=>'layui-bg-cyan',
+                'col'=>$col,
+            ],
+        ];
+
+    }
+    /*
+     * 获取
+     * */
+    public static function getSpreadBadge($where)
+    {
+        $where['is_time']=1;
+        $uids = self::setSpreadWhere($where)->column('u.uid');
+        //分销员人数
+        $data['sum_count'] = count($uids);
+        $data['spread_sum'] = 0;
+        $data['order_count'] = 0;
+        $data['pay_price'] = 0;
+        $data['number'] = 0;
+        $data['extract_count'] = 0;
+        $data['extract_price'] = 0;
+        if($data['sum_count']){
+            //发展会员人数
+            $data['spread_sum'] = User::where('spread_uid','in',$uids)->count();
+            //订单总数
+            $data['order_count'] = StoreOrder::where('uid','in',$uids)->count();
+            //订单金额
+            $data['pay_price'] = StoreOrder::where('uid','in',$uids)->sum('pay_price');
+            //可提现金额
+            $data['number'] = UserBill::where('uid','in',$uids)->where(['category'=>'now_money','type'=>'brokerage'])->sum('number');
+            //提现次数
+            $data['extract_count'] = UserExtract::where('uid','in',$uids)->count();
+            //获取某个用户可提现金额
+            $data['extract_price'] = User::getextractPrice($uids,$where);
+        }
+        return [
+            [
+                'name'=>'分销员人数',
+                'field'=>'人',
+                'count'=>$data['sum_count'],
+                'background_color'=>'layui-bg-cyan',
+                'col'=>2,
+            ],
+            [
+                'name'=>'发展会员人数',
+                'field'=>'人',
+                'count'=>$data['spread_sum'],
+                'background_color'=>'layui-bg-cyan',
+                'col'=>2,
+            ],
+            [
+                'name'=>'分销订单数',
+                'field'=>'单',
+                'count'=>$data['order_count'],
+                'background_color'=>'layui-bg-cyan',
+                'col'=>2,
+            ],
+            [
+                'name'=>'订单金额',
+                'field'=>'元',
+                'count'=>$data['pay_price'],
+                'background_color'=>'layui-bg-cyan',
+                'col'=>2,
+            ],
+            [
+                'name'=>'提现金额',
+                'field'=>'元',
+                'count'=>$data['number'],
+                'background_color'=>'layui-bg-cyan',
+                'col'=>2,
+            ],
+            [
+                'name'=>'提现次数',
+                'field'=>'次',
+                'count'=>$data['extract_count'],
+                'background_color'=>'layui-bg-cyan',
+                'col'=>2,
+            ],
+            [
+                'name'=>'未提现金额',
+                'field'=>'元',
+                'count'=>$data['extract_price'],
+                'background_color'=>'layui-bg-cyan',
+                'col'=>2,
+            ],
+        ];
+    }
+
+    /**
+     * 获取分销用户
+     * @param array $where
+     * @return array
+     */
+    public static function agentSystemPage($where = array()){
+        $model=self::setSpreadWhere($where);
+        $status =SystemConfigService::get('store_brokerage_statu');
+        if(isset($where['excel']) && $where['excel'] == 1){
+            $list = $model->field(['a.uid','u.phone','a.nickname','a.sex','a.country','a.province','a.city','a.now_money','a.subscribe'])->select()->toArray();
             $export = [];
             foreach ($list as $index=>$item){
+                $uids = self::getModelTime($where,User::where('spread_uid',$item['uid']))->column('uid');
+                $item['spread_count'] = count($uids);
+                if(count($uids)){
+                    $uidTwo = User::where('spread_uid','in',$uids)->column('uid');
+                    $uids = array_merge($uids,$uidTwo);
+                    $uids = array_unique($uids);
+                    $uids = array_merge($uids);
+                }
+                $item['extract_sum_price'] = self::getModelTime($where,UserExtract::where('uid',$item['uid']))->sum('extract_price');
+                $item['extract_count_price'] = UserExtract::getUserCountPrice($item['uid'].$where);//累计提现金额
+                $item['extract_count_num'] = UserExtract::getUserCountNum($item['uid'],$where);//提现次数
+                $item['order_price'] = count($uids) ? StoreOrder::where('uid','in',$uids)->where(['paid'=>1,'refund_status'=>0])->sum('pay_price') : 0;//订单金额
+                $item['order_count'] = count($uids) ? StoreOrder::where('uid','in',$uids)->where(['paid'=>1,'refund_status'=>0])->count() : 0;//订单数量
+                $item['stair']              = self::getUserSpreadUidCount($item['uid'],0,$where);//一级推荐人
+                $item['second']             = self::getUserSpreadUidCount($item['uid'],1,$where);//二级推荐人
+                $item['order_stair']        = self::getUserSpreadOrderCount($item['uid'],0,$where);//一级推荐人订单
+                $item['order_second']       = self::getUserSpreadOrderCount($item['uid'],1,$where);//二级推荐人订单
+                //可提现佣金
+                $item['new_money']          = User::getextractPrice($item['uid'],$where);
+                //总共佣金
+                $item['brokerage_money']    = self::getModelTime($where,UserBill::where(['uid'=>$item['uid'],'category'=>'now_money','type'=>'brokerage','pm'=>1,'status'=>1]))->sum('number');
+                $item['spread_name']='暂无';
+                if($spread_uid=User::where('uid',$item['uid'])->value('spread_uid')) {
+                    if($user=User::where('uid',$spread_uid)->field(['uid','nickname'])->find()){
+                        $item['spread_name']=$user['nickname'].'/'.$user['uid'];
+                    }
+                }
                 $export[] = [
+                    $item['uid'],
                     $item['nickname'],
-                    $item['sex'],
-                    $item['country'].$item['province'].$item['city'],
-                    $item['stair'],
-                    $item['second'],
-                    $item['order_stair'],
-                    $item['order_second'],
-                    $item['now_money'],
-                    $item['subscribe'] == 1? '关注':'未关注',
+                    $item['phone'],
+                    $item['spread_count'],
+                    $item['order_count'],
+                    $item['order_price'],
+                    $item['brokerage_money'],
+                    $item['extract_count_price'],
+                    $item['extract_count_num'],
+                    $item['new_money'],
+                    $item['spread_name'],
                 ];
-                $list[$index] = $item;
             }
-            PHPExcelService::setExcelHeader(['名称','性别','地区','一级推荐人','二级推荐人','一级推荐订单个数','二级推荐订单个数','获得佣金','是否关注公众号'])
-                ->setExcelTile('微信用户导出','微信用户导出'.time(),' 生成时间:'.date('Y-m-d H:i:s',time()))
+            PHPExcelService::setExcelHeader(['用户编号','昵称','电话号码','推广用户数量','订单数量','推广订单金额','佣金金额','已提现金额','提现次数','未提现金额','上级推广人'])
+                ->setExcelTile('推广用户','推广用户导出'.time(),' 生成时间:'.date('Y-m-d H:i:s',time()))
                 ->setExcelContent($export)
                 ->ExcelSave();
         }
-        return self::page($model,function ($item){
-            try{
-                $item['qr_code'] = QrcodeService::getForeverQrcode('spread',$item['uid']);
-            }catch (\Exception $e){
-                $item['qr_code'] = '';
+        $data = $model->page((int)$where['page'],(int)$where['limit'])->select();
+        $data = count($data) ? $data->toArray() : [];
+        foreach ($data as &$item){
+            if((int)$status==2) $item['is_show']=false;
+            else $item['is_show']=true;
+            $uids = self::getModelTime($where,User::where('spread_uid',$item['uid']))->column('uid');
+            $item['spread_count'] = count($uids);
+            if(count($uids)){
+                $uidTwo = User::where('spread_uid','in',$uids)->column('uid');
+                $uids = array_merge($uids,$uidTwo);
+                $uids = array_unique($uids);
+                $uids = array_merge($uids);
             }
-            $item['extract_count_price'] = UserExtract::getUserCountPrice($item['uid']);//累计提现
-            $item['extract_count_num'] = UserExtract::getUserCountNum($item['uid']);//提现次数
-        },$where);
+            $item['extract_sum_price'] = self::getModelTime($where,UserExtract::where('uid',$item['uid']))->sum('extract_price');
+            $item['extract_count_price'] = UserExtract::getUserCountPrice($item['uid'],$where);//累计提现金额
+            $item['extract_count_num'] = UserExtract::getUserCountNum($item['uid'],$where);//提现次数
+            $item['order_price'] = count($uids) ? StoreOrder::where('uid','in',$uids)->where(['paid'=>1,'refund_status'=>0])->sum('pay_price') : 0;//订单金额
+            $item['order_count'] = count($uids) ? StoreOrder::where('uid','in',$uids)->where(['paid'=>1,'refund_status'=>0])->count() : 0;//订单数量
+            if($item['unionid'])
+                $item['type_name'] = '打通';
+            else if($item['openid'] && !$item['unionid'])
+                $item['type_name'] = '公众号';
+            else if($item['routine_openid'] && !$item['unionid'])
+                $item['type_name'] = '小程序';
+            $item['subscribe_name']=$item['subscribe'] ? '已关注' : ($item['routine_openid'] && !$item['unionid'] ? '暂无' : '未关注') ;
+            if($item['sex']==1)
+                $item['sex_name'] = '男';
+            else if($item['sex']==2)
+                $item['sex_name'] = '女';
+            else if($item['sex']==0)
+                $item['sex_name'] = '未知';
+            $item['spread_name']='暂无';
+            if($spread_uid=User::where('uid',$item['uid'])->value('spread_uid')) {
+                if($user=User::where('uid',$spread_uid)->field(['uid','nickname'])->find()){
+                    $item['spread_name']=$user['nickname'].'/'.$user['uid'];
+                }
+            }
+            //总共佣金
+            $item['brokerage_money']    = self::getModelTime($where,UserBill::where(['uid'=>$item['uid'],'category'=>'now_money','type'=>'brokerage','pm'=>1,'status'=>1]))->sum('number');
+            //可提现佣金
+            $item['new_money']          = User::getextractPrice($item['uid'],$where);
+            $item['stair']              = self::getUserSpreadUidCount($item['uid'],0,$where);//一级推荐人
+            $item['second']             = self::getUserSpreadUidCount($item['uid'],1,$where);//二级推荐人
+            $item['order_stair']        = self::getUserSpreadOrderCount($item['uid'],0,$where);//一级推荐人订单
+            $item['order_second']       = self::getUserSpreadOrderCount($item['uid'],1,$where);//二级推荐人订单
+        }
+        $count = self::setSpreadWhere($where)->count();
+        return compact('data','count');
     }
 
      /**
@@ -303,11 +708,11 @@ use app\core\util\SystemConfigService;
       * $spread 0 一级推广人数  1 二级推广人数
       * @return int|string
       */
-     public static function getUserSpreadUidCount($uid,$spread = 1){
-         $userStair = User::where('spread_uid',$uid)->column('uid','uid');//获取一级推家人
+     public static function getUserSpreadUidCount($uid,$spread = 1,$where=[]){
+         $userStair =self::getModelTime($where, User::where('spread_uid',$uid))->column('uid','uid');//获取一级推家人
          if($userStair){
              if(!$spread) return count($userStair);//返回一级推人人数
-             else return User::where('spread_uid','IN',implode(',',$userStair))->count();//二级推荐人数
+             else return self::getModelTime($where,User::where('spread_uid','IN',implode(',',$userStair)))->count();//二级推荐人数
          }else return 0;
      }
 
@@ -318,38 +723,19 @@ use app\core\util\SystemConfigService;
       * $spread 0 一级推广总订单  1 所有推广总订单
       * @return int|string
       */
-     public static function getUserSpreadOrderCount($uid,$spread = 1){
-         $userStair = User::where('spread_uid',$uid)->column('uid','uid');//获取一级推家人uid
+     public static function getUserSpreadOrderCount($uid,$spread = 1,$where=[]){
+         $userStair = self::getModelTime($where,User::where('spread_uid',$uid))->column('uid','uid');//获取一级推家人uid
          if($userStair){
              if(!$spread){
-                 return StoreOrder::where('uid','IN',implode(',',$userStair))->where('paid',1)->where('refund_status',0)->where('status',2)->count();//获取一级推广人订单数
+                 return self::getModelTime($where,StoreOrder::where('uid','IN',implode(',',$userStair))->where(['paid'=>1,'refund_status'=>0,'status'=>2]))->count();//获取一级推广人订单数
              }
              else{
-                 $userSecond = User::where('spread_uid','IN',implode(',',$userStair))->column('uid','uid');//二级推广人的uid
+                 $userSecond = self::getModelTime($where,User::where('spread_uid','IN',implode(',',$userStair)))->column('uid','uid');//二级推广人的uid
                  if($userSecond){
-                     return StoreOrder::where('uid','IN',implode(',',$userSecond))->where('paid',1)->where('refund_status',0)->where('status',2)->count();//获取二级推广人订单数
+                     return self::getModelTime($where,StoreOrder::where('uid','IN',implode(',',$userSecond))->where('paid',1)->where('refund_status',0)->where('status',2))->count();//获取二级推广人订单数
                  }else return 0;
              }
          }else return 0;
      }
 
-     /**
-      * 同步微信用户表内的 一级推荐人 二级推荐人 一级推荐人订单 二级推荐人订单
-      */
-     public static function setWechatUserOrder(){
-         $uidAll = self::column('uid','uid');
-         $item = [];
-         foreach ($uidAll as $k=>$v){
-             $item['stair'] = self::getUserSpreadUidCount($v,0);//一级推荐人
-             $item['second'] = self::getUserSpreadUidCount($v);//二级推荐人
-             $item['order_stair'] = self::getUserSpreadOrderCount($v,0);//一级推荐人订单
-             $item['order_second'] = self::getUserSpreadOrderCount($v);//二级推荐人订单
-             $item['now_money'] = User::where('uid',$v)->value('now_money');//佣金
-             if(!$item['stair'] && !$item['second'] && !$item['order_stair'] && !$item['order_second'] && !$item['now_money']) continue;
-             else self::edit($item,$v);
-         }
-     }
-
-
-
 }

+ 338 - 569
application/admin/view/agent/agent_manage/index.php

@@ -1,599 +1,368 @@
 {extend name="public/container"}
 {block name="head_top"}
-<link href="{__FRAME_PATH}css/plugins/iCheck/custom.css" rel="stylesheet">
-<script src="{__PLUG_PATH}moment.js"></script>
-<link rel="stylesheet" href="{__PLUG_PATH}daterangepicker/daterangepicker.css">
-<script src="{__PLUG_PATH}daterangepicker/daterangepicker.js"></script>
-<script src="{__ADMIN_PATH}frame/js/plugins/iCheck/icheck.min.js"></script>
-<link href="{__FRAME_PATH}css/plugins/footable/footable.core.css" rel="stylesheet">
-<script src="{__PLUG_PATH}sweetalert2/sweetalert2.all.min.js"></script>
-<script src="{__FRAME_PATH}js/plugins/footable/footable.all.min.js"></script>
-<script src="{__ADMIN_PATH}js/layuiList.js"></script>
 <style>
-    .on-tag{background-color: #eea91e;}
-    .height-auto{height: 300px;}
-    .tag{border: solid 1px #eee;}
+    .option{width: 200px;padding: 10px;background-color: #eeeeee;border-radius: 10px;text-align: center;display: none;}
+    .option .layui-box p{margin: 5px 0;background-color: #ffffff;color: #0092DC;padding: 8px;cursor: pointer}
+    .option .layui-box p.on{color: #eeeeee}
 </style>
 {/block}
 {block name="content"}
-<div class="row">
-    <div class="col-sm-12">
-        <div class="ibox">
-            <!--<div class="ibox-title">
-                <button type="button" class="btn btn-w-m btn-primary grant">发放优惠券</button>
-                <button type="button" class="btn btn-w-m btn-primary" onclick="$eb.createModalFrame(this.innerText,'{:Url('store.storeCoupon/grant_subscribe')}',{'w':800})">给关注的用户发放优惠券</button>
-                <button type="button" class="btn btn-w-m btn-primary" onclick="$eb.createModalFrame(this.innerText,'{:Url('store.storeCoupon/grant_all')}',{'w':800})">给所有用户发放优惠券</button>
-                <button type="button" class="btn btn-w-m btn-primary" onclick="$eb.createModalFrame(this.innerText,'{:Url('store.storeCoupon/grant_group')}',{'w':800})">给分组用户发放优惠券</button>
-                <button type="button" class="btn btn-w-m btn-primary" onclick="$eb.createModalFrame(this.innerText,'{:Url('store.storeCoupon/grant_tag')}',{'w':800})">给标签用户发放优惠券</button>
-            </div>-->
-            <div class="ibox-content">
-                <div class="row">
-                    <div class="m-b m-l">
-                        <form action="" class="form-inline" id="form" method="get">
-
-                            <div class="search-item" data-name="data">
-                                <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.data?:'no'}">自定义时间</button>
+<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">
+                    <div class="layui-carousel layadmin-carousel layadmin-shortcut" lay-anim="" lay-indicator="inside" lay-arrow="none" style="background:none">
+                        <div class="layui-card-body">
+                            <div class="layui-row layui-col-space10 layui-form-item">
+                                <div class="layui-col-lg12">
+                                    <label class="layui-form-label">时间选择:</label>
+                                    <div class="layui-input-block" data-type="data" v-cloak="">
+                                        <button class="layui-btn layui-btn-sm" type="button" v-for="item in dataList" @click="setData(item)" :class="{'layui-btn-primary':where.data!=item.value}">{{item.name}}</button>
+                                        <button class="layui-btn layui-btn-sm" type="button" ref="time" @click="setData({value:'zd',is_zd:true})" :class="{'layui-btn-primary':where.data!='zd'}">自定义</button>
+                                        <button type="button" class="layui-btn layui-btn-sm layui-btn-primary" v-show="showtime==true" ref="date_time">{$year.0} - {$year.1}</button>
+                                    </div>
+                                </div>
+                                <div class="layui-col-lg12">
+                                    <label class="layui-form-label">用户昵称:</label>
+                                    <div class="layui-input-block">
+                                        <input type="text" name="nickname" style="width: 50%" v-model="where.nickname" placeholder="请输入姓名、电话、UID" class="layui-input">
+                                    </div>
+                                </div>
+                                <div class="layui-col-lg12">
+                                    <div class="layui-input-block">
+                                        <button @click="search" type="button" class="layui-btn layui-btn-sm layui-btn-normal">
+                                            <i class="layui-icon layui-icon-search"></i>搜索</button>
+                                        <button @click="excel" type="button" class="layui-btn layui-btn-warm layui-btn-sm export" type="button">
+                                            <i class="fa fa-floppy-o" style="margin-right: 3px;"></i>导出</button>
+                                        <button @click="refresh" type="reset" class="layui-btn layui-btn-primary layui-btn-sm">
+                                            <i class="layui-icon layui-icon-refresh" ></i>刷新</button>
+                                    </div>
                                 </div>
-                                <input class="search-item-value" type="hidden" name="data" value="{$where.data}" />
-                                <input class="search-item-value" type="hidden" name="groupid" value="{$where.groupid}" />
-                                <input class="search-item-value" type="hidden" name="tagid_list" value="{$where.tagid_list}" />
-                                <input class="search-item-value" type="hidden" name="sex" value="{$where.sex}" />
-                                <input class="search-item-value" type="hidden" name="subscribe" value="{$where.subscribe}" />
-                                <input class="search-item-value" type="hidden" name="stair" value="" />
-                                <input class="search-item-value" type="hidden" name="second" value="" />
-                                <input class="search-item-value" type="hidden" name="order_stair" value="" />
-                                <input class="search-item-value" type="hidden" name="order_second" value="" />
-                                <input class="search-item-value" type="hidden" name="now_money" value="" />
-                                <input class="search-item-value" type="hidden" id="batch" name="batch" value="" />
-                            </div>
-                            <hr>
-                            <div class="btn-group">
-                                <button data-toggle="dropdown" class="btn btn-white btn-xs dropdown-toggle" style="padding: 5px 15px;"
-                                        aria-expanded="false">批量操作
-                                    <span class="caret"></span>
-                                </button>
-                                <ul class="dropdown-menu left">
-                                    <li>
-                                        <a class="save_mark grant" href="javascript:void(0);"  >
-                                            <i class="fa fa-space-shuttle"></i> 发放优惠券
-                                        </a>
-                                    </li>
-                                    <li>
-                                        <a class="save_mark news" href="javascript:void(0);"  >
-                                            <i class="fa fa-space-shuttle"></i> 发送消息
-                                        </a>
-                                    </li>
-                                </ul>
-                            </div>
-                            <div class="input-group" style="float: right">
-                                <input type="text" name="nickname" value="{$where.nickname}" placeholder="请输入会员名称" class="input-sm form-control">
-
-                                <input type="hidden" name="export" value="{$where.export}" />
-                                <span class="input-group-btn">
-                                    <button type="submit" class="btn btn-sm btn-primary" id="search"> <i class="fa fa-search"></i>搜索</button>
-                                    <button style="margin: 0 16px" type="submit" id="export" class="btn btn-sm btn-info btn-outline"> <i class="fa fa-exchange" ></i> Excel导出</button>
-                                    <script>
-                                        $('#export').on('click',function(){
-                                            $('input[name=export]').val(1);
-                                        });
-                                        $('#no_export').on('click',function(){
-                                            $('input[name=export]').val(0);
-                                        });
-                                        $('#search').on('click',function(){
-                                            $('input[name=export]').val(0);
-                                        });
-                                    </script>
-                                </span>
                             </div>
-                        </form>
+                        </div>
                     </div>
                 </div>
-                <div class="table-responsive">
-                    <table class="table table-striped  table-bordered"  data-page-size="20">
-                        <thead>
-                            <tr>
-                                <th class="text-cente">
-                                    <div class="btn-group">
-                                        <button data-toggle="dropdown" class="btn btn-white btn-xs dropdown-toggle" style="font-weight: bold;background-color: #f5f5f6;border: solid 0;"
-                                                aria-expanded="false">
-                                            选择
-                                            <span class="caret"></span>
-                                        </button>
-                                        <ul class="dropdown-menu left">
-                                            <li class="this-page">
-                                                <a class="save_mark" href="javascript:void(0);"  >
-                                                    <i class="fa fa-check-square-o"></i>本页用户
-                                                </a>
-                                            </li>
-                                            <li class="this-all">
-                                                <a class="save_mark" href="javascript:void(0);">
-                                                    <i class="fa fa-check-square"></i>全部用户
-                                                </a>
-                                            </li>
-                                            <li class="this-up">
-                                                <a class="save_mark" href="javascript:void(0);">
-                                                    <i class="fa fa-square-o"></i>取消选择
-                                                </a>
-                                            </li>
-                                        </ul>
-                                    </div>
-                                </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">
-                                    <div class="btn-group">
-                                        <button data-toggle="dropdown" class="btn btn-white btn-xs dropdown-toggle" style="font-weight: bold;background-color: #f5f5f6;border: solid 0;"
-                                                aria-expanded="false">性别
-                                            <span class="caret"></span>
-                                        </button>
-                                        <ul class="dropdown-menu search-item" data-name="sex">
-                                            <li data-value="">
-                                                <a class="save_mark" href="javascript:void(0);"  >
-                                                    <i class="fa fa-venus-mars"></i>全部
-                                                </a>
-                                            </li>
-                                            <li data-value="1">
-                                                <a class="save_mark" href="javascript:void(0);"  >
-                                                    <i class="fa fa-mars"></i>男
-                                                </a>
-                                            </li>
-                                            <li data-value="2">
-                                                <a class="save_mark" href="javascript:void(0);">
-                                                    <i class="fa fa-venus"></i>女
-                                                </a>
-                                            </li>
-                                            <li data-value="0">
-                                                <a class="save_mark" href="javascript:void(0);">
-                                                    <i class="fa fa-transgender"></i>保密
-                                                </a>
-                                            </li>
-                                        </ul>
-                                    </div>
-                                </th>
-                                <th class="text-center no-sort">地区</th>
-                                <th class="text-center">
-                                    <div class="btn-group">
-                                        <button data-toggle="dropdown" class="btn btn-white btn-xs dropdown-toggle" style="font-weight: bold;background-color: #f5f5f6;border: solid 0;"
-                                                aria-expanded="false">一级推荐人
-                                            <span class="stair caret"></span>
-                                        </button>
-                                        <ul class="dropdown-menu search-item" data-name="stair">
-                                            <li data-value="">
-                                                <a class="save_mark" href="javascript:void(0);"  >
-                                                    <i class="fa fa-arrows-v"></i>默认
-                                                </a>
-                                            </li>
-                                            <li data-value="stair desc">
-                                                <a class="save_mark" href="javascript:void(0);"  >
-                                                    <i class="fa fa-sort-numeric-desc"></i>降序
-                                                </a>
-                                            </li>
-                                            <li data-value="stair asc">
-                                                <a class="save_mark" href="javascript:void(0);">
-                                                    <i class="fa fa-sort-numeric-asc"></i>升序
-                                                </a>
-                                            </li>
-                                        </ul>
-                                    </div>
-                                </th>
-                                <th class="text-center">
-                                    <div class="btn-group">
-                                        <button data-toggle="dropdown" class="btn btn-white btn-xs dropdown-toggle" style="font-weight: bold;background-color: #f5f5f6;border: solid 0;"
-                                                aria-expanded="false">二级推荐人
-                                            <span class="second caret"></span>
-                                        </button>
-                                        <ul class="dropdown-menu search-item" data-name="second">
-                                            <li data-value="">
-                                                <a class="save_mark" href="javascript:void(0);"  >
-                                                    <i class="fa fa-arrows-v"></i>默认
-                                                </a>
-                                            </li>
-                                            <li data-value="second desc">
-                                                <a class="save_mark" href="javascript:void(0);"  >
-                                                    <i class="fa fa-sort-numeric-desc"></i>降序
-                                                </a>
-                                            </li>
-                                            <li data-value="second asc">
-                                                <a class="save_mark" href="javascript:void(0);">
-                                                    <i class="fa fa-sort-numeric-asc"></i>升序
-                                                </a>
-                                            </li>
-                                        </ul>
-                                    </div>
-                                </th>
-                                <th class="text-center">
-                                    <div class="btn-group">
-                                        <button data-toggle="dropdown" class="btn btn-white btn-xs dropdown-toggle" style="font-weight: bold;background-color: #f5f5f6;border: solid 0;"
-                                                aria-expanded="false">一级推广订单
-                                            <span class="order_stair caret"></span>
-                                        </button>
-                                        <ul class="dropdown-menu search-item" data-name="order_stair">
-                                            <li data-value="">
-                                                <a class="save_mark" href="javascript:void(0);"  >
-                                                    <i class="fa fa-arrows-v"></i>默认
-                                                </a>
-                                            </li>
-                                            <li data-value="order_stair desc">
-                                                <a class="save_mark" href="javascript:void(0);"  >
-                                                    <i class="fa fa-sort-numeric-desc"></i>降序
-                                                </a>
-                                            </li>
-                                            <li data-value="order_stair asc">
-                                                <a class="save_mark" href="javascript:void(0);">
-                                                    <i class="fa fa-sort-numeric-asc"></i>升序
-                                                </a>
-                                            </li>
-                                        </ul>
-                                    </div>
-                                </th>
-                                <th class="text-center">
-                                    <div class="btn-group">
-                                        <button data-toggle="dropdown" class="btn btn-white btn-xs dropdown-toggle" style="font-weight: bold;background-color: #f5f5f6;border: solid 0;"
-                                                aria-expanded="false">所有推广订单
-                                            <span class="caret order_second"></span>
-                                        </button>
-                                        <ul class="dropdown-menu search-item" data-name="order_second">
-                                            <li data-value="">
-                                                <a class="save_mark" href="javascript:void(0);"  >
-                                                    <i class="fa fa-arrows-v"></i>默认
-                                                </a>
-                                            </li>
-                                            <li data-value="order_second desc">
-                                                <a class="save_mark" href="javascript:void(0);"  >
-                                                    <i class="fa fa-sort-numeric-asc"></i>降序
-                                                </a>
-                                            </li>
-                                            <li data-value="order_second asc">
-                                                <a class="save_mark" href="javascript:void(0);">
-                                                    <i class="fa fa-sort-numeric-desc"></i>升序
-                                                </a>
-                                            </li>
-                                        </ul>
-                                    </div>
-                                </th>
-                                <th class="text-center">
-                                    <div class="btn-group">
-                                        <button data-toggle="dropdown" class="btn btn-white btn-xs dropdown-toggle" style="font-weight: bold;background-color: #f5f5f6;border: solid 0;"
-                                                aria-expanded="false">获得佣金
-                                            <span class="now_money caret"></span>
-                                        </button>
-                                        <ul class="dropdown-menu search-item" data-name="now_money">
-                                            <li data-value="">
-                                                <a class="save_mark" href="javascript:void(0);"  >
-                                                    <i class="fa fa-arrows-v"></i>默认
-                                                </a>
-                                            </li>
-                                            <li data-value="now_money desc">
-                                                <a class="save_mark" href="javascript:void(0);"  >
-                                                    <i class="fa fa-sort-numeric-asc"></i>降序
-                                                </a>
-                                            </li>
-                                            <li data-value="now_money asc">
-                                                <a class="save_mark" href="javascript:void(0);">
-                                                    <i class="fa fa-sort-numeric-desc"></i>升序
-                                                </a>
-                                            </li>
-                                        </ul>
-                                    </div>
-                                </th>
-                                <th class="text-center">
-                                    <div class="btn-group">
-                                        <button data-toggle="dropdown" class="btn btn-white btn-xs dropdown-toggle" style="font-weight: bold;background-color: #f5f5f6;border: solid 0;"
-                                                aria-expanded="false">是否关注公众号
-                                            <span class="caret"></span>
-                                        </button>
-                                        <ul class="dropdown-menu search-item" data-name="subscribe">
-                                            <li data-value="">
-                                                <a class="save_mark" href="javascript:void(0);"  >
-                                                    全部
-                                                </a>
-                                            </li>
-                                            <li data-value="1">
-                                                <a class="save_mark" href="javascript:void(0);"  >
-                                                    关注
-                                                </a>
-                                            </li>
-                                            <li data-value="0">
-                                                <a class="save_mark" href="javascript:void(0);">
-                                                    未关注
-                                                </a>
-                                            </li>
-                                        </ul>
-                                    </div>
-                                </th>
-                                <th class="text-center">推广二维码</th>
-                                <th class="text-center">累计提现金额</th>
-                                <th class="text-center">可提现金额</th>
-                                <th class="text-center">提现次数</th>
-                            </tr>
-                        </thead>
-                        <tbody>
-                         <?php $count = count($list); ?>
-                            {if condition="$count"}
-                                {volist name="list" id="vo"}
-                                    <tr>
-                                    <td class="text-center">
-                                        <label class="checkbox-inline i-checks">
-                                            <input type="checkbox" name="coupon[]" value="{$vo.uid}">
-                                        </label>
-                                    </td>
-                                    <td class="text-center">
-                                        {$vo.uid}
-                                    </td>
-                                    <td class="text-center">
-                                        {$vo.nickname}
-                                    </td>
-                                    <td class="text-center">
-                                        <img src="{$vo.headimgurl}" alt="{$vo.nickname}" title="{$vo.nickname}" style="width:50px;height: 50px;cursor: pointer;" class="head_image" data-image="{$vo.headimgurl}">
-                                    </td>
-                                        <td class="text-center">
-                                            {if condition="$vo['user_type'] eq 'routine'"}
-                                                小程序授权
-                                            {else/}
-                                                公众号授权
-                                            {/if}
-                                        </td>
-                                    <td class="text-center">
-                                        {if condition="$vo['sex'] eq 1"}
-                                        男
-                                        {elseif condition="$vo['sex'] eq 2"/}
-                                        女
-                                        {else/}
-                                        保密
-                                        {/if}
-                                    </td>
-                                    <td class="text-center">
-                                        {$vo.country}{$vo.province}{$vo.city}
-                                    </td>
-                                    <td class="text-center">
-                                        <button class="btn btn-white  btn-xs"  onclick="$eb.createModalFrame('推荐人列表','{:Url('stair',['uid'=>$vo['uid']])}',{'w':800})">
-                                            <i class="fa fa-street-view"></i>
-                                            {$vo.stair}
-                                        </button>
-                                    </td>
-                                    <td class="text-center">
-                                        {$vo.second}
-                                    </td>
-                                    <td class="text-center">
-                                        {$vo.order_stair}
-                                    </td>
-                                    <td class="text-center">
-                                        {$vo.order_second}
-                                    </td>
-                                    <td class="text-center">
-                                        <button class="btn btn-white  btn-xs"  onclick="$eb.createModalFrame('佣金记录','{:Url('now_money',['uid'=>$vo['uid']])}',{'w':800})">
-                                            <i class="fa fa-dollar"></i>
-                                            {$vo.now_money}
-                                        </button>
-                                    </td>
-                                    <td class="text-center">
-                                        {if condition="$vo['subscribe']"}
-                                        关注
-                                        {else/}
-                                        未关注
-                                        {/if}
-                                    </td>
-                                    <td class="text-center">
-                                        {if condition="$vo['user_type'] eq 'routine'"}
-                                           暂无
-                                        {else/}
-                                        {if isset($vo.qr_code.url)}
-                                           <img src="{$vo.qr_code.url}" alt="{$vo.nickname}" title="{$vo.nickname}" style="width:50px;height: 50px;cursor: pointer;" class="head_image" data-image="{$vo.qr_code.url}">
-                                        {else}
-                                            暂无
-                                        {/if}
-                                        {/if}
-                                    </td>
-                                    <td class="text-center">
-                                        {$vo.extract_count_price}
-                                    </td>
-                                    <td class="text-center">
-                                        {$vo.now_money}
-                                    </td>
-                                    <td class="text-center">
-                                        {$vo.extract_count_num}
-                                    </td>
-                                </tr>
-                                {/volist}
-                            {else/}
-                                <tr id="content" style="display:none;height:400px;"></tr>
-                            {/if}
-                        </tbody>
-                    </table>
+            </div>
+        </div>
+        <!--end-->
+        <!-- 中间详细信息-->
+        <div :class="item.col!=undefined ? 'layui-col-sm'+item.col+' '+'layui-col-md'+item.col:'layui-col-sm6 layui-col-md3'" v-for="item in badge" v-cloak="" v-if="item.count > 0">
+            <div class="layui-card">
+                <div class="layui-card-header">
+                    {{item.name}}
+                    <span class="layui-badge layuiadmin-badge" :class="item.background_color">{{item.field}}</span>
+                </div>
+                <div class="layui-card-body">
+                    <p class="layuiadmin-big-font">{{item.count}}</p>
+                    <p v-show="item.content!=undefined">
+                        {{item.content}}
+                        <span class="layuiadmin-span-color">{{item.sum}}<i :class="item.class"></i></span>
+                    </p>
+                </div>
+            </div>
+        </div>
+        <!--enb-->
+    </div>
+    <div class="layui-row layui-col-space15">
+        <div class="layui-col-md12">
+            <div class="layui-card">
+                <div class="layui-card-header">分销员列表</div>
+                <div class="layui-card-body">
+<!--                    <div class="layui-btn-container">-->
+<!--                        <div class="layui-btn-group conrelTable">-->
+<!--                            <button class="layui-btn layui-btn-sm layui-btn-normal" type="button" data-type="refresh"><i class="layui-icon layui-icon-refresh" ></i>刷新</button>-->
+<!--                        </div>-->
+<!--                    </div>-->
+                    <table class="layui-hide" id="userList" lay-filter="userList"></table>
+                    <script type="text/html" id="headimgurl">
+                        <img style="cursor: pointer" lay-event='open_image' src="{{d.headimgurl}}">
+                    </script>
+                    <script type="text/html" id="act">
+                        <button type="button" class="layui-btn layui-btn-xs" onclick="dropdown(this)">操作 <span class="caret"></span></button>
+                        <ul class="layui-nav-child layui-anim layui-anim-upbit">
+                            <li>
+                                <a href="javascript:void(0);" class="" onclick="$eb.createModalFrame(this.innerText,'{:Url('stair')}?uid={{d.uid}}')">
+                                    <i class="fa fa-list-alt"></i> 统计推广人列表
+                                </a>
+                            </li>
+                            <li>
+                                <a href="javascript:void(0);" class="" onclick="$eb.createModalFrame(this.innerText,'{:Url('stair_order')}?uid={{d.uid}}')">
+                                    <i class="fa fa-reorder"></i> 统计推广订单
+                                </a>
+                            </li>
+                            <li>
+                                <a href="javascript:void(0);" lay-event='look_code'>
+                                    <i class="fa fa-file-image-o"></i> 推广方式</a>
+                            </li>
+                            {{# if(d.is_show){ }}
+                            <li>
+                                <a href="javascript:void(0);" lay-event='delete_spread'>
+                                    <i class="fa fa-unlock"></i> 清除上级推广人关系
+                                </a>
+                                </a>
+                            </li>
+                            {{# } }}
+                        </ul>
+                    </script>
+                </div>
+                <!--用户信息-->
+                <script type="text/html" id="userinfo">
+                    昵称:{{d.nickname==null ? '暂无信息':d.nickname}}
+                    <br>姓名:{{d.real_name==null ? '暂无信息':d.real_name}}
+                    <br>电话:{{d.phone==null ? '暂无信息':d.phone}}
+                </script>
+                <div class="option">
+                    <div class="layui-box">
+                        <input type="hidden" name="uid" id="uid">
+                        <p data-action="routine_code" data-type="wx">小程序推广二维码</p>
+                        <p data-action="wechant_code" data-type="wx">公众号推广二维码</p>
+                    </div>
                 </div>
-                {include file="public/inner_page"}
+
             </div>
         </div>
     </div>
 </div>
+<script src="{__ADMIN_PATH}js/layuiList.js"></script>
 {/block}
 {block name="script"}
 <script>
-    window.$list = <?php echo json_encode($list);?>;
-    window.$uidAll = <?php echo json_encode($uidAll);?>;
-    window.$where = <?php echo json_encode($where);?>;
-    $('.this-page').on('click',function () {
-        $('input[name="coupon[]"]').each(function(){
-            $(this).checked = true;
-            $(this).parent().addClass('checked');
-            $('#batch').val(1);
-        });
-    })
-    $('.this-all').on('click',function () {
-        $('input[name="coupon[]"]').each(function(){
-            $(this).checked = true;
-            $(this).parent().addClass('checked');
-            $('#batch').val(2);
-        });
+    var action={
+        refresh:function () {
+            layList.reload();
+        },
+        delete_spread:function () {
+            var ids=layList.getCheckData().getIds('uid');
+            if(ids.length){
+                $eb.$swal('delete',function(){
+                    $eb.axios.post(layList.U({a:'delete_promoter'}),{uids:ids}).then(function(res){
+                        if(res.status == 200 && res.data.code == 200) {
+                            $eb.$swal('success',res.data.msg);
+                            layList.reload();
+                        }else
+                            return Promise.reject(res.data.msg || '清除失败')
+                    }).catch(function(err){
+                        $eb.$swal('error',err);
+                    });
+                },{
+                    title:'您将解除选中用户的推广权限,请谨慎操作!',
+                    text:'解除后可在会员管理里单个开启推广权限',
+                    confirm:'是的我要解除'
+                })
+            }else{
+                layList.msg('请选择要解除权限的用户');
+            }
+        },
+    };
+    layList.form.render();
+    layList.tableList('userList',"{:Url('get_spread_list')}",function () {
+        return [
+            {type:'checkbox'},
+            {field: 'uid', title: 'UID', sort: true,width:'5%'},
+            {field: 'headimgurl', title: '头像',templet:'#headimgurl'},
+            {field: 'nickname', title: '用户信息',templet:'#userinfo',width:'12%'},
+            {field: 'spread_count', title: '推广用户数量',sort:true},
+            {field: 'order_count', title: '订单数量'},
+            {field: 'order_price', title: '推广订单金额',sort:true},
+            {field: 'brokerage_money', title: '佣金金额',sort:true},
+            {field: 'extract_count_price', title: '已提现金额',sort:true},
+            {field: 'extract_count_num', title: '提现次数'},
+            {field: 'new_money', title: '未提现金额',sort:true},
+            {field: 'spread_name', title: '上级推广人',sort:true},
+            {field: 'right', title: '操作',toolbar:'#act',width:'5%'},
+        ];
+    });
+    layList.date({elem:'#start_time',theme:'#393D49',type:'datetime'});
+    layList.date({elem:'#end_time',theme:'#393D49',type:'datetime'});
+    layList.search('search',function(where){
+        if(where.start_time!='' && where.end_time=='') return layList.msg('请选择结束时间')
+        if(where.end_time!='' && where.start_time=='') return layList.msg('请选择开始时间')
+        console.log(where);
+        layList.reload(where,true);
+    });
+    layList.search('export',function(where){
+        where.excel=1;
+        location.href=layList.U({a:'get_spread_list',q:where});
     })
-    $('.this-up').on('click',function () {
-        $('input[name="coupon[]"]').each(function(){
-            $(this).checked = false;
-            $(this).parent().removeClass('checked');
-            $('#batch').val('');
-        });
+    $('.conrelTable').find('button').each(function () {
+        var type=$(this).data('type');
+        $(this).on('click',function () {
+            action[type] && action[type]();
+        })
     })
-    $(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);
+    $('.option .layui-box').find('p').each(function () {
+        $(this).on('click',function () {
+            var type = $(this).data('action'),uid = $('#uid').val();
+            layList.baseGet(layList.U({a:'look_code',q:{action:type,uid:uid}}),function (res) {
+                if($eb){
+                    $eb.openImage(res.data.code_src);
+                }else{
+                    layList.layer.open({
+                        type: 1,
+                        title: false,
+                        closeBtn: 0,
+                        shadeClose: true,
+                        content: '<img src="'+res.data.code_src+'" style="display: block;width: 100%;" />'
+                    });
                 }
-            })
-            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')
-        });
-        $('.tag-item-value').each(function () {
-            var that = $(this), name = that.attr('name'), value = that.val().split(',');
-            dom = [];
-            $.each(value,function (index,item) {
-                dom.push($('.tag-item[data-name="' + name + '"] .btn[data-value="' + item + '"]'));
-            })
-            $.each(dom,function (index,item) {
-                item.eq(0).removeClass('btn-outline btn-link tag').addClass('btn-primary btn-sm')
-            })
+            },function (res) {
+                layList.msg(res.msg);
+            });
         });
-    })
-    $('.i-checks').iCheck({
-        checkboxClass: 'icheckbox_square-green',
     });
-    $('.head_image').on('click',function (e) {
-        var image = $(this).data('image');
-        $eb.openImage(image);
+    //下拉框
+    $(document).click(function (e) {
+        $('.layui-nav-child').hide();
     })
-    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('cancel.daterangepicker', function(ev, picker) {
-        $("#data").val('');
-    });
-    dateInput.on('apply.daterangepicker', function(ev, picker) {
-        $("input[name=data]").val(picker.startDate.format('YYYY/MM/DD') + ' - ' + picker.endDate.format('YYYY/MM/DD'));
-        $('input[name=export]').val(0);
-        $('#form').submit();
-    });
-    //发优惠券
-    $('.grant').on('click',function (e) {
-        var chk_value =[];
-        var batch = $('#batch').val();
-        if(batch == 1){
-            $.each($list.data,function (index,item) {
-                chk_value.push(item.uid);
-            })
-        }else if(batch == 2){
-            chk_value = $uidAll;
-        }else{
-            $('input[name="coupon[]"]:checked').each(function(){
-                chk_value.push($(this).val());
-                str += $(this).val();
-            });
-            if(chk_value.length < 1){
-                $eb.message('请选择要发放优惠券的用户');
-                return false;
+    function dropdown(that){
+        var oEvent = arguments.callee.caller.arguments[0] || event;
+        oEvent.stopPropagation();
+        var offset = $(that).offset();
+        var top=offset.top-$(window).scrollTop();
+        var index = $(that).parents('tr').data('index');
+        $('.layui-nav-child').each(function (key) {
+            if (key != index) {
+                $(this).hide();
             }
-        }
-        var str = chk_value.join(',');
-//        var url = "http://"+window.location.host+"/admin/store.store_coupon/grant/id/"+str;
-        var url = layList.U({c:'store.store_coupon',a:'grant',p:{id:str}});
-        $eb.createModalFrame(this.innerText,url,{'w':800});
-    })
-    $('.news').on('click',function (e) {
-        var chk_value =[];
-        var batch = $('#batch').val();
-        if(batch == 1){
-            $.each($list.data,function (index,item) {
-                chk_value.push(item.uid);
-            })
-        }else if(batch == 2){
-            chk_value = $uidAll;
+        })
+        if($(document).height() < top+$(that).next('ul').height()){
+            $(that).next('ul').css({
+                'padding': 10,
+                'top': - ($(that).parent('td').height() / 2 + $(that).height() + $(that).next('ul').height()/2),
+                'min-width': 'inherit',
+                'left':-64,
+                'position': 'absolute'
+            }).toggle();
         }else{
-            $('input[name="coupon[]"]:checked').each(function(){
-                chk_value.push($(this).val());
-                str += $(this).val();
-            });
-            if(chk_value.length < 1){
-                $eb.message('请选择要发消息的用户');
-                return false;
-            }
+            $(that).next('ul').css({
+                'padding': 10,
+                'left':-64,
+                'top':$(that).parent('td').height() / 2 + $(that).height(),
+                'min-width': 'inherit',
+                'position': 'absolute'
+            }).toggle();
         }
-        var str = chk_value.join(',');
-//        var url = "http://"+window.location.host+"/admin/wechat.wechat_news_category/send_news/id/"+str;
-        var url = layList.U({c:'wechat.wechat_news_category',a:'send_news',p:{id:str}});
-        $eb.createModalFrame(this.innerText,url,{'w':800});
-    })
-    $('.synchro').on('click',function(){
-        window.t = $(this);
-        var _this = $(this),url =_this.data('url');
-        $eb.$swal('delete',function(){
-            $eb.axios.get(url).then(function(res){
-                console.log(res);
-                if(res.status == 200 && res.data.code == 200) {
-                    $eb.$swal('success',res.data.msg);
-                }else
-                    return Promise.reject(res.data.msg || '同步失败')
-            }).catch(function(err){
-                $eb.$swal('error',err);
-            });
-        },{'title':'您确定要同步该用户的标签吗?','text':'请谨慎操作!','confirm':'是的,我要同步'})
+    }
+    layList.tool(function (event,data,obj) {
+        switch (event) {
+            case 'delete_spread':
+                var url=layList.U({a:'empty_spread',q:{uid:data.uid}});
+                $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);
+                            obj.del();
+                        }else
+                            return Promise.reject(res.data.msg || '清除失败')
+                    }).catch(function(err){
+                        $eb.$swal('error',err);
+                    });
+                },{
+                    title:'您将解除【'+data.nickname+'】的推广权限,请谨慎操作!',
+                    text:'解除后可在会员管理里面开启',
+                    confirm:'是的我要解除'
+                })
+                break;
+            case 'look_code':
+                $('#uid').val(data.uid);
+                var index=layList.layer.open({
+                    type: 1,
+                    area: ['200px', 'auto'], //宽高
+                    content:$('.option'),
+                    title:false,
+                    cancel:function () {
+                        $('.option').hide();
+                        $('#uid').val('');
+                    }
+                });
+                break;
+            case 'open_image':
+                if($eb)
+                    $eb.openImage(data.headimgurl);
+                else
+                    layList.layer.open({
+                        type: 1,
+                        title: false,
+                        closeBtn: 0,
+                        shadeClose: true,
+                        content: '<img src="'+data.headimgurl+'" style="display: block;width: 100%;" />'
+                    });
+                break;
+
+        }
+    });
+    require(['vue'],function(Vue) {
+        new Vue({
+            el: "#app",
+            data: {
+                badge: [],
+                dataList: [
+                    {name: '全部', value: ''},
+                    {name: '今天', value: 'today'},
+                    {name: '昨天', value: 'yesterday'},
+                    {name: '最近7天', value: 'lately7'},
+                    {name: '最近30天', value: 'lately30'},
+                    {name: '本月', value: 'month'},
+                    {name: '本年', value: 'year'},
+                ],
+                where:{
+                    data:'',
+                    nickname: '',
+                    excel:0,
+                },
+                showtime: false,
+            },
+            watch:{
+                
+            },
+            methods:{
+                getBadge:function(){
+                    var that=this;
+                    layList.basePost(layList.Url({a:'get_badge'}),this.where,function (rem) {
+                        that.badge=rem.data;
+                    });
+                },
+                setData:function(item){
+                    var that=this;
+                    if(item.is_zd==true){
+                        that.showtime=true;
+                        this.where.data=this.$refs.date_time.innerText;
+                    }else{
+                        this.showtime=false;
+                        this.where.data=item.value;
+                    }
+                },
+                search:function () {
+                    this.where.excel=0;
+                    this.getBadge();
+                    console.log(this.where);
+                    layList.reload(this.where,true);
+                },
+                excel:function () {
+                    this.where.excel=1;
+                    location.href=layList.U({a:'get_spread_list',q:this.where});
+                },
+                refresh:function () {
+                    layList.reload();
+                    this.getBadge();
+                }
+            },
+            mounted:function () {
+                this.getBadge();
+                layList.laydate.render({
+                    elem:this.$refs.date_time,
+                    trigger:'click',
+                    eventElem:this.$refs.time,
+                    range:true,
+                    change:function (value){
+                        that.where.data=value;
+                    }
+                });
+            }
+        })
     });
 </script>
 {/block}

+ 190 - 37
application/admin/view/agent/agent_manage/stair.php

@@ -1,45 +1,198 @@
 {extend name="public/container"}
 {block name="content"}
-<div class="row">
-    <div class="col-sm-12">
-        <div class="ibox">
-            <div class="ibox-content">
-                <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>
-                        </tr>
-                        </thead>
-                        <tbody class="">
-                        {volist name="list" id="vo"}
-                            <tr>
-                                <td class="text-center">
-                                    <img src="{$vo.avatar}" alt="{$vo.nickname}" title="{$vo.nickname}" style="width:50px;height: 50px;cursor: pointer;" class="head_image" data-image="{$vo.avatar}">
-                                </td>
-                                <td class="text-center">
-                                    {$vo.nickname}
-                                </td>
-                                <td class="text-center">
-                                    {$vo.add_time|date="Y-m-d H:i:s",###}
-                                </td>
-                                <td class="text-center">
-                                    {$vo.orderCount}
-                                </td>
-                                <td class="text-center">
-                                    {$vo.now_money}
-                                </td>
-                            </tr>
-                        {/volist}
-                        </tbody>
-                    </table>
+<div class="layui-fluid">
+    <div class="layui-row layui-col-space15"  id="app" v-cloak="">
+        <!--搜索条件-->
+        <div class="layui-col-md12">
+            <div class="layui-card">
+                <div class="layui-card-header">搜索条件</div>
+                <div class="layui-card-body">
+                    <div class="layui-carousel layadmin-carousel layadmin-shortcut" lay-anim="" lay-indicator="inside" lay-arrow="none" style="background:none">
+                        <div class="layui-card-body">
+                            <div class="layui-row layui-col-space10 layui-form-item">
+                                <div class="layui-col-lg12">
+                                    <label class="layui-form-label">时间选择:</label>
+                                    <div class="layui-input-block" data-type="data" v-cloak="">
+                                        <button class="layui-btn layui-btn-sm" type="button" v-for="item in dataList" @click="setData(item)" :class="{'layui-btn-primary':where.data!=item.value}">{{item.name}}</button>
+                                        <button class="layui-btn layui-btn-sm" type="button" ref="time" @click="setData({value:'zd',is_zd:true})" :class="{'layui-btn-primary':where.data!='zd'}">自定义</button>
+                                        <button type="button" class="layui-btn layui-btn-sm layui-btn-primary" v-show="showtime==true" ref="date_time">{year.0} - {$year.1}</button>
+                                    </div>
+                                </div>
+                                <div class="layui-col-lg12">
+                                    <label class="layui-form-label">用户类型:</label>
+                                    <div class="layui-input-block" v-cloak="">
+                                        <button class="layui-btn layui-btn-sm" :class="{'layui-btn-primary':where.type!=item.value}" @click="where.type = item.value" type="button" v-for="item in spread_type">{{item.name}}
+                                            <span v-if="item.count!=undefined" class="layui-badge layui-bg-gray">{{item.count}}</span></button>
+                                    </div>
+                                </div>
+                                <div class="layui-col-lg12">
+                                    <label class="layui-form-label">用户昵称:</label>
+                                    <div class="layui-input-block">
+                                        <input type="text" name="nickname" style="width: 50%" v-model="where.nickname" placeholder="请输入姓名、电话、UID" class="layui-input">
+                                    </div>
+                                </div>
+                                <div class="layui-col-lg12">
+                                    <div class="layui-input-block">
+                                        <button @click="search" type="button" class="layui-btn layui-btn-sm layui-btn-normal">
+                                            <i class="layui-icon layui-icon-search"></i>搜索</button>
+                                        <button @click="refresh" type="reset" class="layui-btn layui-btn-primary layui-btn-sm">
+                                            <i class="layui-icon layui-icon-refresh" ></i>刷新</button>
+                                    </div>
+                                </div>
+                            </div>
+                        </div>
+                    </div>
+                </div>
+            </div>
+        </div>
+        <!--end-->
+        <!-- 中间详细信息-->
+        <div :class="item.col!=undefined ? 'layui-col-sm'+item.col+' '+'layui-col-md'+item.col +' layui-col-xs'+item.col:'layui-col-sm4 layui-col-md3'" v-for="item in badge" v-cloak="" v-if="item.count > 0">
+            <div class="layui-card">
+                <div class="layui-card-header">
+                    {{item.name}}
+                    <span class="layui-badge layuiadmin-badge" :class="item.background_color">{{item.field}}</span>
+                </div>
+                <div class="layui-card-body">
+                    <p class="layuiadmin-big-font">{{item.count}}</p>
+                    <p v-show="item.content!=undefined">
+                        {{item.content}}
+                        <span class="layuiadmin-span-color">{{item.sum}}<i :class="item.class"></i></span>
+                    </p>
+                </div>
+            </div>
+        </div>
+        <!--enb-->
+    </div>
+    <div class="layui-row layui-col-space15">
+        <div class="layui-col-md12">
+            <div class="layui-card">
+                <div class="layui-card-header">分销员列表</div>
+                <div class="layui-card-body">
+                    <div class="layui-btn-container">
+                        <!--                        <div class="layui-btn-group conrelTable">-->
+                        <!--                            <button class="layui-btn layui-btn-sm layui-btn-normal" type="button" data-type="refresh"><i class="layui-icon layui-icon-refresh" ></i>刷新</button>-->
+                        <!--                        </div>-->
+                    </div>
+                    <table class="layui-hide" id="userList" lay-filter="userList"></table>
+                    <script type="text/html" id="avatar">
+                        <img style="cursor: pointer" lay-event='open_image' src="{{d.avatar}}">
+                    </script>
+                    <!--用户信息-->
+                    <script type="text/html" id="userinfo">
+                        昵称:{{d.nickname==null ? '暂无信息':d.nickname}}
+                        <br>姓名:{{d.real_name==null ? '暂无信息':d.real_name}}
+                        <br>电话:{{d.phone==null ? '暂无信息':d.phone}}
+                    </script>
                 </div>
             </div>
         </div>
     </div>
 </div>
+<script src="{__ADMIN_PATH}js/layuiList.js"></script>
+{/block}
+{block name="script"}
+<script>
+    var action={
+        refresh:function () {
+            layList.reload();
+        }
+    },uid = {$uid};
+    layList.form.render();
+    layList.tableList('userList',"{:Url('get_stair_list',['uid'=>$uid])}",function () {
+        return [
+            {field: 'uid', title: 'UID',width:'10%'},
+            {field: 'avatar', title: '头像',templet:'#avatar'},
+            {field: 'real_name', title: '用户信息',templet:'#userinfo',width:'22%'},
+            {field: 'promoter_name', title: '是否推广员'},
+            {field: 'spread_count', title: '推广人数',sort: true},
+            {field: 'order_count', title: '订单数',sort: true},
+            {field: 'add_time', title: '关注时间',width:'10%',sort: true},
+        ];
+    });
+    layList.date({elem:'#start_time',theme:'#393D49',type:'datetime'});
+    layList.date({elem:'#end_time',theme:'#393D49',type:'datetime'});
+    layList.search('search',function(where){
+        if(where.start_time!='' && where.end_time=='') return layList.msg('请选择结束时间');
+        if(where.end_time!='' && where.start_time=='') return layList.msg('请选择开始时间');
+        layList.reload(where,true);
+    });
+    $('.conrelTable').find('button').each(function () {
+        var type=$(this).data('type');
+        $(this).on('click',function () {
+            action[type] && action[type]();
+        })
+    })
+    require(['vue'],function(Vue) {
+        new Vue({
+            el: "#app",
+            data: {
+                badge: [],
+                dataList: [
+                    {name: '全部', value: ''},
+                    {name: '昨天', value: 'yesterday'},
+                    {name: '今天', value: 'today'},
+                    {name: '最近7天', value: 'lately7'},
+                    {name: '最近30天', value: 'lately30'},
+                    {name: '本月', value: 'month'},
+                    {name: '本年', value: 'year'},
+                ],
+                spread_type:[
+                    {name:'全部',value:''},
+                    {name:'一级推广人',value:'1'},
+                    {name:'二级推广人',value:'2'},
+                ],
+                where:{
+                    data:'',
+                    nickname: '',
+                    type:'',
+                    uid:uid
+                },
+                showtime: false,
+            },
+            watch:{
+
+            },
+            methods:{
+                getBadge:function(){
+                    var that=this;
+                    layList.baseGet(layList.Url({a:'get_stair_badge',q:that.where}),function (rem) {
+                        that.badge=rem.data;
+                    });
+                },
+                setData:function(item){
+                    var that=this;
+                    if(item.is_zd==true){
+                        that.showtime=true;
+                        this.where.data=this.$refs.date_time.innerText;
+                    }else{
+                        this.showtime=false;
+                        this.where.data=item.value;
+                    }
+                },
+                search:function () {
+                    this.where.excel=0;
+                    this.getBadge();
+                    layList.reload(this.where,true);
+                },
+                refresh:function () {
+                    layList.reload();
+                    this.getBadge();
+                }
+            },
+            mounted:function () {
+                this.getBadge();
+                layList.laydate.render({
+                    elem:this.$refs.date_time,
+                    trigger:'click',
+                    eventElem:this.$refs.time,
+                    range:true,
+                    change:function (value){
+                        that.where.data=value;
+                    }
+                });
+            }
+        })
+    });
+</script>
 {/block}

+ 206 - 0
application/admin/view/agent/agent_manage/stair_order.php

@@ -0,0 +1,206 @@
+{extend name="public/container"}
+{block name="content"}
+<div class="layui-fluid">
+    <div class="layui-row layui-col-space15"  id="app" v-cloak="">
+        <!--搜索条件-->
+        <div class="layui-col-md12">
+            <div class="layui-card">
+                <div class="layui-card-header">搜索条件</div>
+                <div class="layui-card-body">
+                    <div class="layui-carousel layadmin-carousel layadmin-shortcut" lay-anim="" lay-indicator="inside" lay-arrow="none" style="background:none">
+                        <div class="layui-card-body">
+                            <div class="layui-row layui-col-space10 layui-form-item">
+                                <div class="layui-col-lg12">
+                                    <label class="layui-form-label">时间选择:</label>
+                                    <div class="layui-input-block" data-type="data" v-cloak="">
+                                        <button class="layui-btn layui-btn-sm" type="button" v-for="item in dataList" @click="setData(item)" :class="{'layui-btn-primary':where.data!=item.value}">{{item.name}}</button>
+                                        <button class="layui-btn layui-btn-sm" type="button" ref="time" @click="setData({value:'zd',is_zd:true})" :class="{'layui-btn-primary':where.data!='zd'}">自定义</button>
+                                        <button type="button" class="layui-btn layui-btn-sm layui-btn-primary" v-show="showtime==true" ref="date_time">{year.0} - {$year.1}</button>
+                                    </div>
+                                </div>
+                                <div class="layui-col-lg12">
+                                    <label class="layui-form-label">订单类型:</label>
+                                    <div class="layui-input-block" v-cloak="">
+                                        <button class="layui-btn layui-btn-sm" :class="{'layui-btn-primary':where.type!=item.value}" @click="where.type = item.value" type="button" v-for="item in spread_type">{{item.name}}
+                                            <span v-if="item.count!=undefined" class="layui-badge layui-bg-gray">{{item.count}}</span></button>
+                                    </div>
+                                </div>
+                                <div class="layui-col-lg12">
+                                    <label class="layui-form-label">订单号:</label>
+                                    <div class="layui-input-block">
+                                        <input type="text" name="order_id" style="width: 50%" v-model="where.order_id" placeholder="请输入姓名、电话、UID、订单号" class="layui-input">
+                                    </div>
+                                </div>
+                                <div class="layui-col-lg12">
+                                    <div class="layui-input-block">
+                                        <button @click="search" type="button" class="layui-btn layui-btn-sm layui-btn-normal">
+                                            <i class="layui-icon layui-icon-search"></i>搜索</button>
+                                        <button @click="refresh" type="reset" class="layui-btn layui-btn-primary layui-btn-sm">
+                                            <i class="layui-icon layui-icon-refresh" ></i>刷新</button>
+                                    </div>
+                                </div>
+                            </div>
+                        </div>
+                    </div>
+                </div>
+            </div>
+        </div>
+        <!--end-->
+        <!-- 中间详细信息-->
+        <div :class="item.col!=undefined ? 'layui-col-sm'+item.col+' '+'layui-col-md'+item.col+' layui-col-xs'+item.col:'layui-col-sm6 layui-col-md3'" v-for="item in badge" v-cloak="" v-if="item.count > 0">
+            <div class="layui-card">
+                <div class="layui-card-header">
+                    {{item.name}}
+                    <span class="layui-badge layuiadmin-badge" :class="item.background_color">{{item.field}}</span>
+                </div>
+                <div class="layui-card-body">
+                    <p class="layuiadmin-big-font">{{item.count}}</p>
+                    <p v-show="item.content!=undefined">
+                        {{item.content}}
+                        <span class="layuiadmin-span-color">{{item.sum}}<i :class="item.class"></i></span>
+                    </p>
+                </div>
+            </div>
+        </div>
+        <!--enb-->
+    </div>
+    <div class="layui-row layui-col-space15">
+        <div class="layui-col-md12">
+            <div class="layui-card">
+                <div class="layui-card-header">分销员列表</div>
+                <div class="layui-card-body">
+                    <div class="layui-btn-container">
+                        <div class="layui-btn-group conrelTable">
+                            <button class="layui-btn layui-btn-sm layui-btn-normal" type="button" data-type="refresh"><i class="layui-icon layui-icon-refresh" ></i>刷新</button>
+                        </div>
+                    </div>
+                    <table class="layui-hide" id="userList" lay-filter="userList"></table>
+                    <script type="text/html" id="time">
+                        <p>下单:{{d._add_time}}</p>
+                        <p>支付:{{d._pay_time}}</p>
+                        <p>收货:{{d.take_time}}</p>
+                    </script>
+                    <script type="text/html" id="user_info">
+                        <p>{{d.user_info}}</p>
+                    </script>
+                    <script type="text/html" id="order_id">
+                        <a href="javascript:;" lay-event="order_id">{{d.order_id}}</a>
+                    </script>
+                </div>
+            </div>
+        </div>
+    </div>
+</div>
+<script src="{__ADMIN_PATH}js/layuiList.js"></script>
+{/block}
+{block name="script"}
+<script>
+    var action={
+        refresh:function () {
+            layList.reload();
+        }
+    },uid = {$uid};
+    layList.form.render();
+    layList.tableList('userList',"{:Url('get_stair_order_list',['uid'=>$uid])}",function () {
+        return [
+            {field: 'order_id', title: '订单ID',templet:'#order_id'},
+            {field: 'user_info', title: '用户信息' ,templet:'#user_info'},
+            // {field: 'spread_info', title: '上级信息' },
+            // {field: 'order_info', title: '订单详情' },
+            {field: 'time', title: '时间',templet:'#time'},
+            {field: 'number_price', title: '返佣金额'},
+        ];
+    });
+    layList.date({elem:'#start_time',theme:'#393D49',type:'datetime'});
+    layList.date({elem:'#end_time',theme:'#393D49',type:'datetime'});
+    layList.search('search',function(where){
+        if(where.start_time!='' && where.end_time=='') return layList.msg('请选择结束时间');
+        if(where.end_time!='' && where.start_time=='') return layList.msg('请选择开始时间');
+        layList.reload(where,true);
+    });
+    $('.conrelTable').find('button').each(function () {
+        var type=$(this).data('type');
+        $(this).on('click',function () {
+            action[type] && action[type]();
+        })
+    })
+    layList.tool(function (event,data,obj) {
+        switch (event){
+            case 'order_id':
+                $eb.createModalFrame('订单列表',layList.U({c:'order.store_order',a:'index',q:{real_name:data.order_id}}),{w:1100});
+                break;
+        }
+    });
+    require(['vue'],function(Vue) {
+        new Vue({
+            el: "#app",
+            data: {
+                badge: [],
+                dataList: [
+                    {name: '全部', value: ''},
+                    {name: '今天', value: 'today'},
+                    {name: '昨天', value: 'yesterday'},
+                    {name: '最近7天', value: 'lately7'},
+                    {name: '最近30天', value: 'lately30'},
+                    {name: '本月', value: 'month'},
+                    {name: '本年', value: 'year'},
+                ],
+                spread_type:[
+                    {name:'全部',value:''},
+                    {name:'一级推广人订单',value:'1'},
+                    {name:'二级推广人订单',value:'2'},
+                ],
+                where:{
+                    data:'',
+                    order_id: '',
+                    type:'',
+                    uid:uid
+                },
+                showtime: false,
+            },
+            watch:{
+
+            },
+            methods:{
+                getBadge:function(){
+                    var that=this;
+                    layList.baseGet(layList.Url({a:'get_stair_order_badge',q:that.where}),function (rem) {
+                        that.badge=rem.data;
+                    });
+                },
+                setData:function(item){
+                    var that=this;
+                    if(item.is_zd==true){
+                        that.showtime=true;
+                        this.where.data=this.$refs.date_time.innerText;
+                    }else{
+                        this.showtime=false;
+                        this.where.data=item.value;
+                    }
+                },
+                search:function () {
+                    this.where.excel=0;
+                    this.getBadge();
+                    layList.reload(this.where,true);
+                },
+                refresh:function () {
+                    layList.reload();
+                    this.getBadge();
+                }
+            },
+            mounted:function () {
+                this.getBadge();
+                layList.laydate.render({
+                    elem:this.$refs.date_time,
+                    trigger:'click',
+                    eventElem:this.$refs.time,
+                    range:true,
+                    change:function (value){
+                        that.where.data=value;
+                    }
+                });
+            }
+        })
+    });
+</script>
+{/block}

文件差异内容过多而无法显示
+ 1 - 1
application/admin/view/article/article/create.php


+ 6 - 4
application/admin/view/finance/finance/commission_list.php

@@ -37,7 +37,7 @@
                                 <div class="layui-input-inline">
                                     <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>
-                                    <button class="layui-btn layui-btn-primary layui-btn-sm export" type="button">
+                                    <button class="layui-btn layui-btn-primary layui-btn-sm export" type="button" lay-submit="excel" lay-filter="excel">
                                         <i class="fa fa-floppy-o" style="margin-right: 3px;"></i>导出</button>
                                 </div>
                             </div>
@@ -67,15 +67,17 @@
         return [
             {field: 'nickname', title: '昵称/姓名',unresize:true},
             {field: 'sum_number', title: '总佣金金额',sort:true,unresize:true},
-            {field: 'now_money', title: '剩余佣金',unresize:true},
+            {field: 'now_money', title: '账户余额',unresize:true},
+            {field: 'money', title: '剩余佣金',unresize:true},
             {field: 'ex_price', title: '提现佣金',unresize:true},
             {field: 'extract_price', title: '提现到账佣金',unresize:true},
             {fixed: 'right', title: '操作',align:'center',unresize:true,toolbar:'#barDemo'},
         ];
     });
     layList.search('search');
-    $('.export').click(function(){
-        location.href=layList.U({a:'save_export'});
+    layList.search('excel',function (where) {
+        where.excel = 1;
+        location.href=layList.U({a:'get_commission_list',q:where});
     })
 </script>
 {/block}

+ 3 - 17
application/admin/view/index/index.php

@@ -264,6 +264,7 @@
             </div>
         </div>
     </div>
+
     <!--右侧边栏结束-->
 </div>
 <!--vue调用不能删除-->
@@ -277,24 +278,9 @@
 <script src="{__FRAME_PATH}js/contabs.min.js"></script>
 <script src="{__FRAME_PATH}js/plugins/pace/pace.min.js"></script>
 {include file="public/style"}
-<script src="{__ADMIN_PATH}js/index.js"></script>
 <script>
-    $(function() {
-        function getnotice() {
-            $.getJSON("{:Url('Jnotice')}",function(res){
-                var info = eval("("+res+")");
-                var data = info.data;
-                $('#msgcount').html(data.msgcount);
-                $('#ordernum').html(data.ordernum + '个');
-                $('#inventory').html(data.inventory + '个');
-                $('#commentnum').html(data.commentnum + '个');
-                $('#reflectnum').html(data.reflectnum + '个');
-            });
-        }
-        getnotice();
-        setInterval(getnotice, 600000);
-    });
-
+    window.newOrderAudioLink='{$new_order_audio_link}';
 </script>
+<script src="{__ADMIN_PATH}js/index.js"></script>
 </body>
 </html>

+ 11 - 9
application/admin/view/index/main.php

@@ -15,7 +15,7 @@
                 </div>
                 <div class="ibox-content">
                     <h1 class="no-margins">{$topData.orderDeliveryNum}</h1>
-                    <small><a href="{:Url('order.store_order/index')}">待发货</a> </small>
+                    <small><a href="javascript:;" class="opFrames" data-name="订单管理" data-href="{:Url('order.store_order/index',['status'=>1])}">待发货</a> </small>
                 </div>
             </div>
         </div>
@@ -27,7 +27,7 @@
                 </div>
                 <div class="ibox-content">
                     <h1 class="no-margins">{$topData.orderRefundNum}</h1>
-                    <small><a href="{:Url('order.store_order/index')}">退换货</a></small>
+                    <small><a href="javascript:;" class="opFrames" data-name="订单管理" data-href="{:Url('order.store_order/index',['status'=>-1])}">退换货</a></small>
                 </div>
             </div>
         </div>
@@ -39,7 +39,7 @@
                 </div>
                 <div class="ibox-content">
                     <h1 class="no-margins">{$topData.stockProduct}</h1>
-                    <small><a href="{:Url('store.store_product/index',array('type'=>5))}">库存预警</a></small>
+                    <small><a href="javascript:;" class="opFrames" data-name="商品管理" data-href="{:Url('store.store_product/index',array('type'=>5))}">库存预警</a></small>
                 </div>
             </div>
         </div>
@@ -51,7 +51,7 @@
                 </div>
                 <div class="ibox-content">
                     <h1 class="no-margins">{$topData.treatedExtract}</h1>
-                    <small><a href="{:Url('finance.user_extract/index')}">待提现</a></small>
+                    <small><a href="javascript:;" class="opFrames" data-name="提现盛情" data-href="{:Url('finance.user_extract/index')}">待提现</a></small>
                 </div>
             </div>
         </div>
@@ -67,7 +67,7 @@
                         {$first_line.d_num.percent}%
                         {if condition='$first_line.d_num.is_plus egt 0'}<i class="fa {if condition='$first_line.d_num.is_plus eq 1'}fa-level-up{else /}fa-level-down{/if}"></i>{/if}
                     </div>
-                    <small>昨日订单数</small>
+                    <small><a href="javascript:;" class="opFrames" data-name="订单管理" data-href="{:Url('order.store_order/index')}?data=yesterday">昨日订单数</a></small>
                 </div>
             </div>
         </div>
@@ -83,7 +83,7 @@
                         {$first_line.d_price.percent}%
                         {if condition='$first_line.d_price.is_plus egt 0'}<i class="fa {if condition='$first_line.d_price.is_plus eq 1'}fa-level-up{else /}fa-level-down{/if}"></i>{/if}
                     </div>
-                    <small>昨日交易额</small>
+                    <small><a href="javascript:;" class="opFrames" data-name="订单管理" data-href="{:Url('order.store_order/index')}?data=yesterday">昨日交易额</a></small>
                 </div>
             </div>
         </div>
@@ -99,7 +99,7 @@
                         {$first_line.day.percent}%
                         {if condition='$first_line.day.is_plus egt 0'}<i class="fa {if condition='$first_line.day.is_plus eq 1'}fa-level-up{else /}fa-level-down{/if}"></i>{/if}
                     </div>
-                    <small>今日新增粉丝</small>
+                    <small><a href="javascript:;" class="opFrames" data-name="会员管理" data-href="{:Url('user.user/index')}">今日新增粉丝</a></small>
                 </div>
             </div>
         </div>
@@ -115,7 +115,7 @@
                         {$first_line.month.percent}%
                         {if condition='$first_line.month.is_plus egt 0'}<i class="fa {if condition='$first_line.month.is_plus eq 1'}fa-level-up{else /}fa-level-down{/if}"></i>{/if}
                     </div>
-                    <small>本月新增粉丝</small>
+                    <small><a href="javascript:;" class="opFrames" data-name="会员管理" data-href="{:Url('user.user/index')}">本月新增粉丝</a></small>
                 </div>
             </div>
         </div>
@@ -439,7 +439,9 @@
                 this.setChart(self.$refs.user_echart,'user_echart');//用户图表
                 this.info();
                 this.getlist();
-
+                $('.opFrames').on('click',function () {
+                    parent.addframes($(this).data('href'),'',$(this).data('name'));
+                });
             }
         });
     });

+ 56 - 24
application/admin/view/order/store_order/index.php

@@ -79,6 +79,9 @@
             <div class="layui-card">
                 <div class="layui-card-header">订单列表</div>
                 <div class="layui-card-body">
+                    <div class="layui-btn-container" id="container-action">
+                        <button class="layui-btn layui-btn-sm" data-type="del_order">批量删除订单</button>
+                    </div>
                     <table class="layui-hide" id="List" lay-filter="List"></table>
                     <!--订单-->
                     <script type="text/html" id="order_id">
@@ -153,8 +156,8 @@
                             </li>
                         </ul>
                         {{#  }else if(d._status==2){ }}
-                        <button class="btn btn-primary btn-xs" type="button" onclick="$eb.createModalFrame('去发货','{:Url('deliver_goods')}?id={{d.id}}',{w:400,h:300})">
-                            <i class="fa fa-cart-plus"></i> 发货</button>
+                        <button class="btn btn-primary btn-xs" type="button" onclick="$eb.createModalFrame('发送货','{:Url('order_goods')}?id={{d.id}}',{w:400,h:250})">
+                            <i class="fa fa-cart-plus"></i> 发货</button>
                         <button type="button" class="layui-btn layui-btn-xs" onclick="dropdown(this)">操作 <span class="caret"></span></button>
                         <ul class="layui-nav-child layui-anim layui-anim-upbit">
                             <li>
@@ -162,11 +165,6 @@
                                     <i class="fa fa-file-text"></i> 订单详情
                                 </a>
                             </li>
-                            <li>
-                                <a  href="javascript:void(0);" onclick="$eb.createModalFrame('去送货','{:Url('delivery')}?id={{d.id}}',{w:400,h:300})">
-                                    <i class="fa fa-motorcycle"></i> 去送货
-                                </a>
-                            </li>
                             <li>
                                 <a lay-event='marke' href="javascript:void(0);" >
                                     <i class="fa fa-paste"></i> 订单备注
@@ -199,11 +197,6 @@
                                     <i class="fa fa-file-text"></i> 订单详情
                                 </a>
                             </li>
-                            <li>
-                                <a  href="javascript:void(0);" onclick="$eb.createModalFrame('去送货','{:Url('delivery')}?id={{d.id}}',{w:400,h:300})">
-                                    <i class="fa fa-motorcycle"></i> 去送货
-                                </a>
-                            </li>
                             {{#  if(d.use_integral > 0 && d.use_integral >= d.back_integral){ }}
                             <li>
                                 <a lay-event='marke' href="javascript:void(0);">
@@ -256,13 +249,13 @@
                             </li>
                             {{#  if(parseFloat(d.pay_price) > parseFloat(d.refund_price)){ }}
                             <li>
-                                <a href="javascript:void(0);" onclick="$eb.createModalFrame('退款','{:Url('refund_y')}?id={{d.id}}')">
+                                <a href="javascript:void(0);" onclick="$eb.createModalFrame('退款','{:Url('refund_y')}?id={{d.id}}',{w:400,h:300})">
                                     <i class="fa fa-history"></i> 立即退款
                                 </a>
                             </li>
                             {{# }else if(d.use_integral > 0 && d.use_integral >= d.back_integral){ }}
                             <li>
-                                <a href="javascript:void(0);" onclick="$eb.createModalFrame('退积分','{:Url('integral_back')}?id={{d.id}}')">
+                                <a href="javascript:void(0);" onclick="$eb.createModalFrame('退积分','{:Url('integral_back')}?id={{d.id}}',{w:400,h:300})">
                                     <i class="fa fa-history"></i> 退积分
                                 </a>
                             </li>
@@ -288,14 +281,14 @@
                             </li>
                             {{#  if(parseFloat(d.pay_price) > parseFloat(d.refund_price)){ }}
                             <li>
-                                <a href="javascript:void(0);" onclick="$eb.createModalFrame('退款','{:Url('refund_y')}?id={{d.id}}')">
+                                <a href="javascript:void(0);" onclick="$eb.createModalFrame('退款','{:Url('refund_y')}?id={{d.id}}',{w:400,h:300})">
                                     <i class="fa fa-history"></i> 立即退款
                                 </a>
                             </li>
                             {{# };}}
                             {{# if(d.use_integral > 0 && d.use_integral >= d.back_integral){ }}
                             <li>
-                                <a href="javascript:void(0);" onclick="$eb.createModalFrame('退积分','{:Url('integral_back')}?id={{d.id}}')">
+                                <a href="javascript:void(0);" onclick="$eb.createModalFrame('退积分','{:Url('integral_back')}?id={{d.id}}',{w:400,h:300})">
                                     <i class="fa fa-history"></i> 退积分
                                 </a>
                             </li>
@@ -321,7 +314,7 @@
                             </li>
                             {{#  if(parseFloat(d.pay_price) > parseFloat(d.refund_price)){ }}
                             <li>
-                                <a href="javascript:void(0);" onclick="$eb.createModalFrame('退款','{:Url('refund_y')}?id={{d.id}}')">
+                                <a href="javascript:void(0);" onclick="$eb.createModalFrame('退款','{:Url('refund_y')}?id={{d.id}}',{w:400,h:300})">
                                     <i class="fa fa-history"></i> 立即退款
                                 </a>
                             </li>
@@ -353,6 +346,7 @@
 <script>
     layList.tableList('List',"{:Url('order_list',['real_name'=>$real_name])}",function (){
         return [
+            {type:'checkbox'},
             {field: 'order_id', title: '订单号', sort: true,event:'order_id',width:'14%',templet:'#order_id'},
             {field: 'nickname', title: '用户信息',templet:'#userinfo',width:'10%'},
             {field: 'info', title: '商品信息',templet:"#info"},
@@ -437,8 +431,32 @@
             }).toggle();
         }
     }
+    var action={
+        del_order:function () {
+            var ids=layList.getCheckData().getIds('id');
+            if(!ids.length) return layList.msg('请选择需要删除的订单');
+            layList.layer.confirm('您确定要删除选中订单吗?', {
+                btn: ['是的,我要删除','我在想想'] //按钮
+            }, function(){
+                layList.basePost(layList.U({a:'del_order'}),{ids:ids},function (res) {
+                    layList.msg(res.msg);
+                    layList.reload();
+                },function (res) {
+                    layList.msg(res.msg);
+                });
+            });
+
+        }
+    }
+    //多选事件绑定
+    $('#container-action').find('button').each(function () {
+        var type=$(this).data('type');
+        $(this).on('click',function(){
+            action[type] && action[type]();
+        })
+    });
     var real_name='<?=$real_name?>';
-    var orderCount=<?=json_encode($orderCount)?>;
+    var orderCount=<?=json_encode($orderCount)?>,status=<?=$status ? $status : "''"?>;
     require(['vue'],function(Vue) {
         new Vue({
             el: "#app",
@@ -447,7 +465,9 @@
                 orderType: [
                     {name: '全部', value: ''},
                     {name: '普通订单', value: 1,count:orderCount.general},
-                    {name: '秒杀订单', value: 3,count:orderCount.seckill}
+                    {name: '拼团订单', value: 2,count:orderCount.pink},
+                    {name: '秒杀订单', value: 3,count:orderCount.seckill},
+                    {name: '砍价订单', value: 4,count:orderCount.bargain},
                 ],
                 orderStatus: [
                     {name: '全部', value: ''},
@@ -458,19 +478,20 @@
                     {name: '交易完成', value: 4,count:orderCount.jy},
                     {name: '退款中', value: -1,count:orderCount.tk,class:true},
                     {name: '已退款', value: -2,count:orderCount.yt},
+                    {name: '已删除', value: -4,count:orderCount.del},
                 ],
                 dataList: [
                     {name: '全部', value: ''},
-                    {name: '昨天', value: 'yesterday'},
                     {name: '今天', value: 'today'},
-                    {name: '本周', value: 'week'},
+                    {name: '昨天', value: 'yesterday'},
+                    {name: '最近7天', value: 'lately7'},
+                    {name: '最近30天', value: 'lately30'},
                     {name: '本月', value: 'month'},
-                    {name: '本季度', value: 'quarter'},
                     {name: '本年', value: 'year'},
                 ],
                 where:{
                     data:'',
-                    status:'',
+                    status:status,
                     type:'',
                     real_name:real_name || '',
                     excel:0,
@@ -478,7 +499,18 @@
                 showtime: false,
             },
             watch: {
-
+                'where.status':function () {
+                    this.getBadge();
+                    layList.reload(this.where,true);
+                },
+                'where.data':function () {
+                    this.getBadge();
+                    layList.reload(this.where,true);
+                },
+                'where.type':function () {
+                    this.getBadge();
+                    layList.reload(this.where,true);
+                }
             },
             methods: {
                 setData:function(item){

+ 93 - 0
application/admin/view/order/store_order/order_goods.php

@@ -0,0 +1,93 @@
+{extend name="public/container"}
+{block name="content"}
+<div class="layui-fluid" style="background: #fff">
+    <form class="layui-form" action="">
+        <div class="layui-form-item">
+            <label class="layui-form-label">选择类型</label>
+            <div class="layui-input-block">
+                <input type="radio" name="type" value="1" lay-filter="type" title="发货" checked>
+                <input type="radio" name="type" value="2" lay-filter="type" title="送货">
+                <input type="radio" name="type" value="3" lay-filter="type" title="虚拟">
+            </div>
+        </div>
+        <div class="type" data-type="1">
+            <div class="layui-form-item">
+                <label class="layui-form-label">快递公司</label>
+                <div class="layui-input-block">
+                    <select name="delivery_name">
+                        <option value="">请选择</option>
+                        {volist name='$list' id='item' key='k'}
+                        <option value="{$item}">{$item}</option>
+                        {/volist}
+                    </select>
+                </div>
+            </div>
+            <div class="layui-form-item">
+                <label class="layui-form-label">快递单号</label>
+                <div class="layui-input-block">
+                    <input type="text" name="delivery_id"   placeholder="请输入快递单号" autocomplete="off" class="layui-input">
+                </div>
+            </div>
+        </div>
+        <div class="type" data-type="2" style="display: none">
+            <div class="layui-form-item">
+                <label class="layui-form-label">送货人姓名</label>
+                <div class="layui-input-block">
+                    <input type="text" name="sh_delivery_name"   placeholder="请输入送货人姓名" autocomplete="off" class="layui-input">
+                </div>
+            </div>
+            <div class="layui-form-item">
+                <label class="layui-form-label">送货人电话</label>
+                <div class="layui-input-block">
+                    <input type="text" name="sh_delivery_id"   placeholder="请输入送货人电话" autocomplete="off" class="layui-input">
+                </div>
+            </div>
+        </div>
+        <div class="layui-form-item" style="margin:10px 0;padding-bottom: 10px;">
+            <div class="layui-input-block">
+                <button class="layui-btn layui-btn-sm" lay-submit="" lay-filter="delivery">立即提交</button>
+                <button type="reset" class="layui-btn layui-btn-primary layui-btn-sm">重置</button>
+            </div>
+        </div>
+    </form>
+</div>
+<script src="{__ADMIN_PATH}js/layuiList.js"></script>
+{/block}
+{block name="script"}
+<script>
+    var id={$id};
+    layList.form.render();
+    layList.form.on('radio(type)', function(data){
+       $('.type').each(function () {
+           if($(this).data('type') == data.value){
+               $(this).show();
+           }else{
+               $(this).hide();
+           }
+       })
+    });
+    layList.search('delivery',function (data) {
+        console.log(data);
+        if(data.type == '1'){
+            if(!data.delivery_name) return layList.msg('请选择快递公司');
+            if(!data.delivery_id) return layList.msg('请填写快递单号');
+        }
+        if(data.type == '2'){
+            if(!data.sh_delivery_name) return layList.msg('请填写送货人姓名');
+            if(!data.sh_delivery_id) return layList.msg('请填写送货人电话');
+        }
+        var index = layList.layer.load(1, {
+            shade: [0.1,'#fff']
+        });
+        layList.basePost(layList.U({a:'update_delivery',q:{id:id}}),data,function (res) {
+            layList.layer.close(index);
+           layList.msg(res.msg);
+            parent.layer.close(parent.layer.getFrameIndex(window.name));
+        },function (res) {
+            layList.layer.close(index);
+            layList.msg(res.msg);
+        });
+    });
+
+</script>
+{/block}

+ 90 - 2
application/admin/view/public/edit_content.php

@@ -14,6 +14,8 @@
     <script type="text/javascript" charset="utf-8" src="{__ADMIN_PATH}plug/umeditor/umeditor.config.js"></script>
     <script type="text/javascript" charset="utf-8" src="{__ADMIN_PATH}plug/umeditor/umeditor.min.js"></script>
     <script type="text/javascript" src="{__ADMIN_PATH}plug/umeditor/lang/zh-cn/zh-cn.js"></script>
+    <link href="{__PLUG_PATH}layui/css/layui.css" rel="stylesheet">
+    <script src="{__PLUG_PATH}layui/layui.all.js"></script>
     <style>
         .edui-btn-toolbar .edui-btn.edui-active .edui-icon-fullscreen.edui-icon{  display: none;}
         .edui-container{overflow: initial !important;}
@@ -35,8 +37,39 @@
 <body>
 <button class="btn btn-success  dim" data-url="{$action}" type="button"><i class="fa fa-upload"></i>
 </button>
-<script type="text/plain" id="myEditor" style="width:100%;">
-{$content ? $content : ''}
+<textarea type="text/plain" id="myEditor" style="width:100%;">{$content ? $content : ''}</textarea>
+
+<script type="text/javascript">
+    $eb = parent._mpApi;
+    $('.dim').on('click',function(){
+        $.ajax({
+            url: $(this).data('url'),
+            type: 'POST',
+            dataType: 'json',
+            data: {'{$field}':getContent()},
+            success: function (res) {
+                if(res.status == 200 && res.data.code == 200){
+                    $eb.message('success','保存成功!');
+                } else
+                return Promise.reject(res.data.msg || '保存失败!');
+            },
+            error: function () {
+                $eb.message('error',err);
+                }
+        });
+    });
+    var editor = document.getElementById('myEditor');
+    editor.style.height = document.body.scrollHeight+'px';
+    //实例化编辑器
+    var um = UM.getEditor('myEditor',{
+        fullscreen:true
+    });
+    function getContent() {
+        return (UM.getEditor('myEditor').getContent());
+    }
+    function hasContent() {
+        return (UM.getEditor('myEditor').hasContents());
+    }
 </script>
 <script type="text/javascript">
     $eb = parent._mpApi;
@@ -52,6 +85,32 @@
     });
     var editor = document.getElementById('myEditor');
     editor.style.height = document.body.scrollHeight+'px';
+    window.UMEDITOR_CONFIG.toolbar = [
+        // 加入一个 test
+        'source | undo redo | bold italic underline strikethrough | superscript subscript | forecolor backcolor | removeformat |',
+        'insertorderedlist insertunorderedlist | selectall cleardoc paragraph | fontfamily fontsize' ,
+        '| justifyleft justifycenter justifyright justifyjustify |',
+        'link unlink | emotion selectimgs video  | map',
+        '| horizontal print preview fullscreen', 'drafts', 'formula'
+    ];
+    UM.registerUI('selectimgs',function(name){
+        var me = this;
+        var $btn = $.eduibutton({
+            icon : 'image',
+            click : function(){
+                createFrame('选择图片','{:Url('widget.images/index')}?fodder=editor');
+            },
+            title: '选择图片'
+        });
+
+        this.addListener('selectionchange',function(){
+            //切换为不可编辑时,把自己变灰
+            var state = this.queryCommandState(name);
+            $btn.edui().disabled(state == -1).active(state == 1)
+        });
+        return $btn;
+
+    });
     //实例化编辑器
     var um = UM.getEditor('myEditor',{
         fullscreen:true
@@ -62,6 +121,35 @@
     function hasContent() {
         return (UM.getEditor('myEditor').hasContents());
     }
+    //弹窗
+    function createFrame(title,src,opt){
+        opt === undefined && (opt = {});
+        return layer.open({
+            type: 2,
+            title:title,
+            area: [(opt.w || 800)+'px', (opt.h || 550)+'px'],
+            fixed: false, //不固定
+            maxmin: true,
+            moveOut:false,//true  可以拖出窗外  false 只能在窗内拖
+            anim:5,//出场动画 isOutAnim bool 关闭动画
+            offset:'auto',//['100px','100px'],//'auto',//初始位置  ['100px','100px'] t[ 上 左]
+            shade:0,//遮罩
+            resize:true,//是否允许拉伸
+            content: src,//内容
+            move:'.layui-layer-title'
+        });
+    }
+    //选择图片
+    function changeIMG(index,pic){
+        $(".image_img").css('background-image',"url("+pic+")");
+        $(".active").css('background-image',"url("+pic+")");
+        $('#image_input').val(pic);
+    }
+    //选择图片插入到编辑器中
+    function insertEditor(list){
+        console.log(list);
+        um.execCommand('insertimage', list);
+    }
 </script>
 </body>
 </html>

+ 4 - 2
application/admin/view/public/form-builder.php

@@ -11,8 +11,10 @@
     <script src="{__PLUG_PATH}form-create/form-create.min.js"></script>
     <style>
         /*弹框样式修改*/
-        .ivu-modal-body{padding: 5;}
-        .ivu-modal-confirm-footer{display: none;}
+        .ivu-modal{top: 20px;}
+        .ivu-modal .ivu-modal-body{padding: 10px;}
+        .ivu-modal .ivu-modal-body .ivu-modal-confirm-head{padding:0 0 10px 0;}
+        .ivu-modal .ivu-modal-body .ivu-modal-confirm-footer{display: none;padding-bottom: 10px;}
         .ivu-date-picker {display: inline-block;line-height: normal;width: 280px;}
     </style>
 </head>

+ 2 - 2
application/admin/view/record/record/chart_order.php

@@ -84,8 +84,6 @@
                                     <div class="layui-input-block">
                                         <button @click="search" type="button" class="layui-btn layui-btn-sm layui-btn-normal">
                                             <i class="layui-icon layui-icon-search"></i>搜索</button>
-                                        <button class="layui-btn layui-btn-warm layui-btn-sm export" type="button">
-                                            <i class="fa fa-floppy-o" style="margin-right: 3px;"></i>导出</button>
                                         <button @click="refresh" type="reset" class="layui-btn layui-btn-primary layui-btn-sm">
                                             <i class="layui-icon layui-icon-refresh" ></i>刷新</button>
                                     </div>
@@ -164,6 +162,8 @@
                 typeList:[
                     {name:'全部',value:''},
                     {name:'普通',value:1},
+                    {name:'拼团',value:2},
+                    {name:'砍价',value:3},
                     {name:'秒杀',value:4},
                 ],
                 status:'',

+ 1 - 1
application/admin/view/setting/system_group/create.php

@@ -96,7 +96,7 @@
                             value: ''
                         },
                         param: {
-                            placeholder: "参数方式例如:\n1=白色\n2=红色\n3=黑色",
+                            placeholder: "参数方式例如:\n1=>白色\n2=>红色\n3=>黑色",
                             value: ''
                         }
                     })

+ 314 - 0
application/admin/view/store/copy_taobao/index.php

@@ -0,0 +1,314 @@
+{extend name="public/container"}
+{block name='head_top'}
+<style>
+    #app .layui-form-label{padding: 9px 15px;width: 80px;}
+    #app .layui-input-margin-5{margin-top: 5px}
+    #app .layui-input-image{width: 100px;height: 100px;}
+    #app .layui-box{width:100px;height:140px;display: inline-block;margin-right: 10px;margin-bottom: 10px;padding: 2px;border: 1px dashed #0d8ddb;border-radius: 3px;text-align: center;}
+    #app .layui-box img{width: 100px;height: 100px;margin: 0 auto;display: block;}
+    #app .layui-box.box-border-color{border: 1px solid #0bb20c;}
+    #app .layui-box .layui-text{background: rgba(0,0,0,.3);}
+    #app .layui-box .layui-text p{width: 50%;display: inline;text-align: center;}
+    #app .spinner {margin: 50px auto;width: 50px;height: 60px;text-align: center;font-size: 10px;}
+    #app .spinner > div {background-color: #0092DC;height: 100%;width: 6px;display: inline-block;-webkit-animation: stretchdelay 1.2s infinite ease-in-out;animation: stretchdelay 1.2s infinite ease-in-out;}
+    #app .spinner .rect2 {-webkit-animation-delay: -1.1s;animation-delay: -1.1s;}
+    #app .spinner .rect3 {-webkit-animation-delay: -1.0s;animation-delay: -1.0s;}
+    #app .spinner .rect4 {-webkit-animation-delay: -0.9s;animation-delay: -0.9s;}
+    #app .spinner .rect5 {-webkit-animation-delay: -0.8s;animation-delay: -0.8s;}
+    #app .save-button{position: fixed;width: 100%;bottom: 0;}
+    @-webkit-keyframes stretchdelay { 0%, 40%, 100% { -webkit-transform: scaleY(0.4) } 20% { -webkit-transform: scaleY(1.0) } }
+    @keyframes stretchdelay { 0%, 40%, 100% {transform: scaleY(0.4);-webkit-transform: scaleY(0.4);}  20% {transform: scaleY(1.0);-webkit-transform: scaleY(1.0);} }
+</style>
+{/block}
+{block name="content"}
+<div class="layui-fluid">
+    <div class="layui-row layui-col-space15"  id="app" v-cloak="">
+        <div class="layui-col-md12">
+            <div class="layui-card">
+                <div class="layui-card-body">
+                    <blockquote class="layui-elem-quote layui-quote-nm">
+                        链接格式说明: 输入以http或https开头的淘宝、天猫、1688、京东的商品详情页网址,网址正确且商品信息存在时才能入库成功。生成的产品默认是没有上架的,请手动上架产品!轮播图选中的颜色是绿色边框的请注意
+                    </blockquote>
+                    <div class="layui-form-item">
+                        <label class="layui-form-label">链接地址</label>
+                        <div class="layui-input-block">
+                            <input type="text" style="width: 80%;display: inline-block;vertical-align: middle" v-model="link"  autocomplete="off" placeholder="链接地址" class="layui-input">
+                            <button @click="checkUrl" class="layui-btn layui-btn-sm layui-btn-normal" lay-submit="search" lay-filter="search" style="vertical-align: middle">
+                                <i class="layui-icon layui-icon-add-1"></i>确定</button>
+                        </div>
+                    </div>
+                </div>
+            </div>
+            <div class="layui-card" v-if="isLink && link">
+                <div class="layui-card-header">商品编辑</div>
+                <div class="layui-card-body">
+                    <form class="layui-form" action="">
+                        <div class="layui-form-item">
+                            <label class="layui-form-label">选择分类</label>
+                            <div class="layui-input-block">
+                                <select name="cate_id" v-model="productInfo.cate_id" lay-verify="cate_id" lay-filter="cate_id">
+                                    <option value="">请选择</option>
+                                    <option :value="item.value" v-for="item in categoryList" :disabled="item.disabled" v-text="item.label"></option>
+                                </select>
+                            </div>
+                        </div>
+                        <div class="layui-form-item">
+                            <label class="layui-form-label">产品名称</label>
+                            <div class="layui-input-block">
+                                <input type="text" name="title"  v-model="productInfo.store_name" autocomplete="off" placeholder="请输入产品名称" class="layui-input">
+                            </div>
+                        </div>
+                        <div class="layui-form-item layui-form-text">
+                            <label class="layui-form-label">产品简介</label>
+                            <div class="layui-input-block">
+                                <textarea placeholder="请输入内容" class="layui-textarea" v-model="productInfo.store_info"></textarea>
+                            </div>
+                        </div>
+                        <div class="layui-form-item layui-input-margin-5">
+                            <div class="layui-inline">
+                                <label class="layui-form-label">产品关键字</label>
+                                <div class="layui-input-inline">
+                                    <input type="text" name="text"  autocomplete="off" class="layui-input" v-model="productInfo.keyword">
+                                </div>
+                            </div>
+                            <div class="layui-inline">
+                                <label class="layui-form-label">产品单位</label>
+                                <div class="layui-input-inline">
+                                    <input type="text" name="text"  autocomplete="off" class="layui-input" v-model="productInfo.unit_name">
+                                </div>
+                            </div>
+                            <div class="layui-inline">
+                                <label class="layui-form-label">产品售价</label>
+                                <div class="layui-input-inline">
+                                    <input type="number" name="number"  autocomplete="off" class="layui-input" v-model="productInfo.price">
+                                </div>
+                            </div>
+                        </div>
+                        <div class="layui-form-item layui-input-margin-5">
+                            <div class="layui-inline">
+                                <label class="layui-form-label">产品市场价</label>
+                                <div class="layui-input-inline">
+                                    <input type="number" name="number"  autocomplete="off" class="layui-input" v-model="productInfo.ot_price">
+                                </div>
+                            </div>
+                            <div class="layui-inline">
+                                <label class="layui-form-label">赠送积分</label>
+                                <div class="layui-input-inline">
+                                    <input type="number" name="number"  autocomplete="off" class="layui-input" v-model="productInfo.give_integral">
+                                </div>
+                            </div>
+                            <div class="layui-inline">
+                                <label class="layui-form-label">邮费</label>
+                                <div class="layui-input-inline">
+                                    <input type="number" name="number"  autocomplete="off" class="layui-input" v-model="productInfo.postage">
+                                </div>
+                            </div>
+                        </div>
+                        <div class="layui-form-item layui-input-margin-5">
+                            <div class="layui-inline">
+                                <label class="layui-form-label">虚拟销量</label>
+                                <div class="layui-input-inline">
+                                    <input type="number" name="number"  autocomplete="off" class="layui-input" v-model="productInfo.ficti">
+                                </div>
+                            </div>
+                            <div class="layui-inline">
+                                <label class="layui-form-label">库存</label>
+                                <div class="layui-input-inline">
+                                    <input type="number" name="number"  autocomplete="off" class="layui-input" v-model="productInfo.stock">
+                                </div>
+                            </div>
+                            <div class="layui-inline">
+                                <label class="layui-form-label">产品成本价</label>
+                                <div class="layui-input-inline">
+                                    <input type="number" name="number"  autocomplete="off" class="layui-input" v-model="productInfo.cost">
+                                </div>
+                            </div>
+                        </div>
+                        <div class="layui-form-item">
+                            <label class="layui-form-label">产品主图片(305*305px)</label>
+                            <div class="layui-input-block">
+                                <div class="layui-box box-border-color" style="height: 100px;">
+                                    <img :src="productInfo.image" alt="" class="layui-input-image" @click="lookImage(productInfo.image)">
+                                </div>
+                            </div>
+                        </div>
+                        <div class="layui-form-item">
+                            <label class="layui-form-label">产品轮播图(640*640px)</label>
+                            <div class="layui-input-block">
+                                <div class="layui-box" :class="item.isSelect ? 'box-border-color':'' " v-for="(item,index) in productInfo.slider_image" >
+                                    <img :src="item.pic" alt="" class="layui-input-image" @click="lookImage(item.pic)">
+                                    <div class="layui-btn-group" style="margin-top: 12px">
+                                        <button type="button" class="layui-btn layui-btn-primary layui-btn-sm" @click=" productInfo.image=item.pic ">主图</button>
+                                        <button type="button" class="layui-btn layui-btn-primary layui-btn-sm" @click="item.isSelect = !item.isSelect">{{ item.isSelect ? '移除': '选中' }}</button>
+                                    </div>
+                                </div>
+                            </div>
+                        </div>
+<!--                        <div class="layui-form-item" v-if="productInfo.description_images.length">-->
+<!--                            <label class="layui-form-label">详情图片</label>-->
+<!--                            <div class="layui-input-block">-->
+<!--                                <div class="layui-box" :class="item.isSelect ? 'box-border-color':'' " v-for="(item,index) in productInfo.description_images" >-->
+<!--                                    <img :src="item.pic" alt="" class="layui-input-image" @click="lookImage(item.pic)">-->
+<!--                                    <div class="layui-btn-group" style="margin-top: 12px">-->
+<!--                                        <button type="button" class="layui-btn layui-btn-primary layui-btn-sm" @click="item.isSelect = !item.isSelect">{{ item.isSelect ? '移除': '选中' }}</button>-->
+<!--                                    </div>-->
+<!--                                </div>-->
+<!--                            </div>-->
+<!--                        </div>-->
+                        <div class="layui-form-item layui-input-margin-5" style="margin-bottom: 40px;">
+                            <label class="layui-form-label">详情内容</label>
+                            <div class="layui-input-block">
+                                <textarea id="description" style="display: none;" class="layui-textarea" v-model="productInfo.description"></textarea>
+                            </div>
+                        </div>
+                    </form>
+                </div>
+                <button class="layui-btn save-button" type="button" @click="saveProduct">立即保存</button>
+            </div>
+            <div class="layui-card" v-if="isLink==false && link && loading">
+                <div class="spinner">
+                    <div class="rect1"></div>
+                    <div class="rect2"></div>
+                    <div class="rect3"></div>
+                    <div class="rect4"></div>
+                    <div class="rect5"></div>
+                </div>
+            </div>
+        </div>
+    </div>
+</div>
+<script src="{__ADMIN_PATH}js/layuiList.js"></script>
+{/block}
+{block name="script"}
+<script>
+    layList.form.render();
+    require(['vue'],function(Vue) {
+        new Vue({
+            el: "#app",
+            data: {
+                categoryList:<?=json_encode($menus)?>,
+                link:'',
+                linkhistory:'',
+                isLink:false,
+                loading:false,
+                productInfo:{
+                    description_images:[],
+                },
+                slider_image:[],
+                editIndex:0,
+            },
+            methods:{
+                checkUrl:function () {
+                    if(!this.link) return layList.msg('请输入链接地址');
+                    if(this.link==this.linkhistory) return false;
+                    this.linkhistory=this.link;
+                    this.loading=true;
+                    layList.basePost(layList.U({a:'get_request_contents'}),{link:this.link},function (res) {
+                        this.loading=false;
+                        this.linkhistory='';
+                        var slider_image=res.data.slider_image,slider_image_new=[],description_images=res.data.description_images,description_images_new=[];
+                        for (var i=0;i<slider_image.length;i++){
+                            slider_image_new.push({pic:slider_image[i],isSelect:true});
+                        }
+                        for(var k=0;k<description_images.length;k++){
+                            description_images_new.push({pic:description_images[k],isSelect:true});
+                        }
+                        res.data.slider_image=slider_image_new;
+                        res.data.description_images=description_images_new;
+                        this.productInfo=res.data;
+                        this.isLink=true;
+                        this.$set(this,'productInfo',this.productInfo);
+                        this.$nextTick(function () {
+                            layList.form.render('select');
+                            this.editIndex=layList.layedit.build('description',{
+                                tool: ['strong', 'italic', 'underline', 'del','|', 'left','center','right','link','unlink','face']
+                            });
+                        }.bind(this));
+                    }.bind(this),function (res) {
+                        this.loading=false;
+                        this.linkhistory='';
+                        layList.msg(res.msg);
+                    }.bind(this));
+                },
+                lookImage:function (pic) {
+                    if($eb) $eb.openImage(pic);
+                },
+                saveProduct:function () {
+                    var that=this,productInfo={
+                        cate_id:that.productInfo.cate_id,
+                        store_name:that.productInfo.store_name,
+                        store_info:that.productInfo.store_info,
+                        ficti:that.productInfo.ficti,
+                        unit_name:that.productInfo.unit_name,
+                        slider_image:that.productInfo.slider_image,
+                        price:that.productInfo.price,
+                        image:that.productInfo.image,
+                        keyword:that.productInfo.keyword,
+                        give_integral:that.productInfo.give_integral,
+                        give_integral:that.productInfo.give_integral,
+                        ot_price:that.productInfo.ot_price,
+                        stock:that.productInfo.stock,
+                        cost:that.productInfo.cost,
+                        postage:that.productInfo.postage,
+                        description:that.productInfo.description,
+                        description_images:that.productInfo.description_images,
+                        soure_link:that.link,
+                    };
+                    if(!that.productInfo.cate_id) return layList.msg('请选择分类');
+                    if(!that.productInfo.store_name) return layList.msg('请填写商品名称');
+                    if(!that.productInfo.unit_name) return layList.msg('请填写产品单位');
+                    if(!that.productInfo.price) return layList.msg('请填写产品价格');
+                    if(!that.productInfo.ot_price) return layList.msg('请填写产品市场价');
+                    if(!that.productInfo.cost) return layList.msg('请填写产品成本价');
+                    if(!that.productInfo.stock) return layList.msg('请填写产品库存');
+                    productInfo.slider_image=that.setArraySelect(productInfo.slider_image);
+                    productInfo.description_images=that.setArraySelect(productInfo.description_images);
+                    productInfo.description=layList.layedit.getContent(that.editIndex);
+                    layList.layer.confirm('保存产品生成图片可能较慢,保存中请耐心等待,请不要关闭窗口!确认生成产品和图片吗?', {
+                        btn: ['确定生成','我在想想'] //按钮
+                    }, function(){
+                        var index=layList.layer.load(1, {shade: [0.5,'#000000']});
+                        layList.basePost(layList.U({a:'save_product'}),productInfo,function (res) {
+                            layList.layer.close(index);
+                            layList.msg(res.msg,function () {
+                                var res=layList.layer.confirm('是否要继续添加?', {
+                                    btn: ['是的','不了我要关闭'] //按钮
+                                },function () {
+                                    that.productInfo={description_images:[]};
+                                    that.link='';
+                                    that.linkhistory='';
+                                    that.$set(that,'productInfo',that.productInfo);
+                                    layList.layer.close(res);
+                                },function () {
+                                    parent.layer.close(parent.layer.getFrameIndex(window.name));
+                                })
+                            })
+                        },function (res){
+                            layList.layer.close(index);
+                            layList.msg(res.msg);
+                        });
+                    });
+                },
+                setArraySelect:function (Arraylist) {
+                    var list=[];
+                    for(var i=0,len=Arraylist.length;i<len;i++) {
+                        if(Arraylist[i].isSelect) list.push(Arraylist[i].pic);
+                    }
+                    return list;
+                }
+            },
+            mounted:function () {
+                var that=this;
+                this.$nextTick(function () {
+                    layList.form.render();
+                    layList.select('cate_id',function (data) {
+                        that.productInfo.cate_id=data.value;
+                    });
+                })
+
+            }
+        })
+    })
+</script>
+{/block}
+

+ 2 - 1
application/admin/view/store/store_product/attr.php

@@ -201,10 +201,11 @@
                 },
                 createFrame:function(title,src,opt){
                     opt === undefined && (opt = {});
+                    var h = parent.document.body.clientHeight - 60;
                     return layer.open({
                         type: 2,
                         title:title,
-                        area: [(opt.w || 700)+'px', (opt.h || 650)+'px'],
+                        area: [(opt.w || 700)+'px', opt.h ? opt.h+'px': h+'px'],
                         fixed: false, //不固定
                         maxmin: true,
                         moveOut:false,//true  可以拖出窗外  false 只能在窗内拖

+ 11 - 8
application/admin/view/store/store_product/index.php

@@ -72,6 +72,7 @@
                         {switch name='type'}
                             {case value="1"}
                                 <button class="layui-btn layui-btn-sm" onclick="$eb.createModalFrame(this.innerText,'{:Url('create')}',{h:700,w:1100})">添加产品</button>
+                                <button class="layui-btn layui-btn-sm" onclick="$eb.createModalFrame(this.innerText,'{:Url('store.copy_taobao/index')}',{h:700,w:1100});">复制淘宝、天猫、1688、京东</button>
                             {/case}
                             {case value="2"}
                                 <button class="layui-btn layui-btn-sm" data-type="show">批量上架</button>
@@ -107,10 +108,10 @@
                     </script>
                     <!--操作-->
                     <script type="text/html" id="act">
-                        <button type="button" class="layui-btn layui-btn-xs btn-success" onclick="$eb.createModalFrame('{{d.store_name}}-属性','{:Url('attr')}?id={{d.id}}',{h:600,w:800})">
+                        <button type="button" class="layui-btn layui-btn-xs btn-success" lay-event='attr' >
                             属性
                         </button>
-                        <button type="button" class="layui-btn layui-btn-xs layui-btn-normal" onclick="$eb.createModalFrame('{{d.store_name}}-编辑','{:Url('edit')}?id={{d.id}}',{h:700,w:1100})">
+                        <button type="button" class="layui-btn layui-btn-xs layui-btn-normal" lay-event='edit'>
                             编辑
                         </button>
                         <button type="button" class="layui-btn layui-btn-xs" onclick="dropdown(this)">操作 <span class="caret"></span></button>
@@ -214,12 +215,8 @@
     })
     //excel下载
     layList.search('export',function(where){
-        location.href=layList.U({c:'store.store_product',a:'product_ist',q:{
-                cate_id:where.cate_id,
-                store_name:where.store_name,
-                type:where.type,
-                excel:1
-            }});
+        where.excel = 1;
+        location.href=layList.U({c:'store.store_product',a:'product_ist',q:where});
     })
     //下拉框
     $(document).click(function (e) {
@@ -304,6 +301,12 @@
             case 'open_image':
                 $eb.openImage(data.image);
                 break;
+            case 'edit':
+                $eb.createModalFrame(data.store_name+'-编辑',layList.U({a:'edit',q:{id:data.id}}),{h:720,w:1100});
+                break;
+            case 'attr':
+                $eb.createModalFrame(data.store_name+'-属性',layList.U({a:'attr',q:{id:data.id}}),{h:600,w:800})
+                break;
         }
     })
     //排序

+ 38 - 5
application/admin/view/store/store_product_reply/index.php

@@ -72,7 +72,15 @@
         <div class="message-box" id="app" v-cloak="">
             <div class="layui-col-md3" style="padding: 0 10px 0 0">
                 <div class="layui-card">
-                    <div class="layui-card-header">评论产品</div>
+                    <div class="layui-card-header" style="padding-top: 10px;">
+                        <div style="height: 30px;line-height: 30px;float:left;" >评论产品</div>
+                        <div style="height: 30px;line-height: 30px;float: right;">
+                            <input style="display: inline;width: auto;" type="text" class="layui-input layui-input-search" v-model="where.product_name" placeholder="搜索产品">
+                            <button class="layui-btn layui-btn-primary layui-btn-sm" type="button" style="height: 32px;line-height: 32px;" @click="seachs"><i class="layui-icon layui-icon-search"></i>搜索</button>
+                            <button class="layui-btn layui-btn-primary layui-btn-sm" type="button" style="height: 32px;line-height: 32px;margin-left: 0;" @click="Reset"><i class="layui-icon layui-icon-refresh-3"></i>重置</button>
+                        </div>
+                        <div class="clearfix"></div>
+                    </div>
                     <div class="layui-card-body layadmin-homepage-list-imgtxt message-content" ref="producr">
                         <div class="grid-demo">
                             <div class="layui-card homepage-bottom">
@@ -106,7 +114,7 @@
                     <div class="layui-card-body layadmin-homepage-list-imgtxt message-content">
                         <div class="media-body" v-for="(item,index) in messageList">
                             <a href="javascript:;" class="media-left" style="float: left;">
-                                <img :src="item.avatar" height="46px" width="46px">
+                                <img :src="item.avatar" height="46px" width="46px" @click="see(item.nickname,item.uid)">
                             </a>
                             <div class="pad-btm">
                                 <p class="fontColor"><a href="javascript:;" v-text="item.nickname"></a></p>
@@ -124,8 +132,8 @@
                             </div>
                             <div class="message-but">
                                 <div class="layui-btn-group">
-                                    <button class="layui-btn layui-btn-normal layui-btn-sm" @click="edit(item,index)">{{item.merchant_reply_time ? "编辑":"回复"}}</button>
-                                    <button class="layui-btn layui-btn-danger layui-btn-sm" @click="delReply(item,index)">删除</button>
+                                    <button class="layui-btn layui-btn-normal layui-btn-sm" type="button" @click="edit(item,index)">{{item.merchant_reply_time ? "编辑":"回复"}}</button>
+                                    <button class="layui-btn layui-btn-danger layui-btn-sm" type="button" @click="delReply(item,index)">删除</button>
                                 </div>
                             </div>
                             <fieldset class="layui-elem-field" style="margin-top: 10px" v-if="item.merchant_reply_time">
@@ -146,6 +154,7 @@
 {/block}
 {block name="script"}
 <script type="text/javascript">
+    var product_id=<?=$product_id?>;
     require(['vue'],function(Vue) {
         new Vue({
             el: "#app",
@@ -156,7 +165,8 @@
                     title:'',
                     is_reply:'',
                     limit:10,
-                    producr_id:0,
+                    product_name:'',
+                    producr_id:product_id,
                     message_page:1,
                 },
                 product:{
@@ -164,6 +174,7 @@
                     loadend:false,
                     loadTitle:'加载更多',
                 },
+                product_name:'',
                 messageList:[],
                 message:{
                     loading:false,
@@ -180,10 +191,32 @@
                     this.getMessageList();
                 },
                 'where.message_page':function () {
+                    this.message.loadend=false;
                     this.getMessageList(true);
                 }
             },
             methods:{
+                see:function(nickname,uid){
+                    $eb.createModalFrame(nickname+'-会员详情',layList.Url({c:'user.user',a:'see',p:{uid:uid}}));
+                },
+                Reset:function(){
+                    if(!this.where.product_name) return;
+                    this.where.page=1;
+                    this.product.loadend=false;
+                    this.product_name='';
+                    this.where.product_name='';
+                    this.$set(this,'productImaesList',[]);
+                    this.getProductImaesList();
+                },
+                seachs:function(){
+                    this.where.page=1;
+                    this.product.loadend=false;
+                    if(!this.where.product_name && !this.product_name) return layList.msg('请输入产品名称再进行查找!');
+                    if(this.where.product_name==this.product_name) return;
+                    this.product_name=this.where.product_name;
+                    this.$set(this,'productImaesList',[]);
+                    this.getProductImaesList();
+                },
                 delReply:function(item,index){
                     var url = layList.U({a:'delete',p:{id:item.id}}),that=this;
                     $eb.$swal('delete',function(){

+ 7 - 1
application/admin/view/system/system_databackup/index.php

@@ -147,7 +147,7 @@
                 if (value['name'] != undefined) tables.push(value['name']);
             });
             if(tables.length < 1 ){
-                return false;
+                return layer.msg('请选择表');
             }
             switch(obj.event){
                 case 'backup':
@@ -155,16 +155,22 @@
                         layer.msg(res.msg,{icon:1,time:1000,end:function(){
                             buckdata.reload();
                         }});
+                    },function (res) {
+                        layer.msg(res.msg);
                     });
                     break;
                 case 'optimize':
                     layList.basePost(layList.Url({a:'optimize'}),{tables:tables},function (res) {
                         layer.msg(res.msg);
+                    },function (res) {
+                        layer.msg(res.msg);
                     });
                     break;
                 case 'repair':
                     layList.basePost(layList.Url({a:'repair'}),{tables:tables},function (res) {
                         layer.msg(res.msg);
+                    },function (res) {
+                        layer.msg(res.msg);
                     });
                     break;
             };

+ 109 - 11
application/admin/view/user/user/index.php

@@ -165,6 +165,23 @@
                                 <input type="text" class="layui-input time-w" name="user_time" lay-verify="user_time"  id="user_time" placeholder=" - ">
                             </div>
                         </div>
+                        <div class="layui-inline">
+                            <label class="layui-form-label">会员等级:</label>
+                            <div class="layui-input-inline">
+                                <select name="level_id" lay-verify="level_id">
+                                    <option value="">全部</option>
+                                    {volist name='level_list' id='val'}
+                                    <option value="{$val.id}">{$val.name}</option>
+                                    {/volist}
+                                </select>
+                            </div>
+                        </div>
+                        <div class="layui-inline">
+                            <label class="layui-form-label">生日:</label>
+                            <div class="layui-input-inline">
+                                <input type="text" class="layui-input time-w" name="birthday" lay-verify="birthday"  id="birthday" placeholder=" - ">
+                            </div>
+                        </div>
                     </div>
                     <div class="layui-form-item">
                         <label class="layui-form-label">
@@ -188,7 +205,7 @@
                         <button class="layui-btn layui-btn-sm layui-btn-normal" type="button" data-type="set_grant"><i class="fa fa-check-circle-o"></i>发送优惠券</button>
                         <button class="layui-btn layui-btn-sm layui-btn-normal" type="button" data-type="set_custom"><i class="fa fa-check-circle-o"></i>发送客服图文消息</button>
 <!--                        <button class="layui-btn layui-btn-sm layui-btn-normal" type="button" data-type="set_template"><i class="fa fa-check-circle-o"></i>发送模板消息</button>-->
-                        <button class="layui-btn layui-btn-sm layui-btn-normal" type="button" data-type="set_info"><i class="fa fa-check-circle-o"></i>发送站内消息</button>
+<!--                        <button class="layui-btn layui-btn-sm layui-btn-normal" type="button" data-type="set_info"><i class="fa fa-check-circle-o"></i>发送站内消息</button>-->
                         <button class="layui-btn layui-btn-sm layui-btn-normal" type="button" data-type="refresh"><i class="layui-icon layui-icon-refresh" ></i>刷新</button>
                     </div>
                     <table class="layui-hide" id="userList" lay-filter="userList"></table>
@@ -198,12 +215,36 @@
                         <p style="color:#dab176">{{d.vip_name}}</p>
                         {{# } }}
                     </script>
+                    <script type="text/html" id="data_time">
+                        <p>首次:{{d.add_time}}</p>
+                        <p>最近:{{d.last_time}}</p>
+                    </script>
                     <script type="text/html" id="checkboxstatus">
                         <input type='checkbox' name='status' lay-skin='switch' value="{{d.uid}}" lay-filter='status' lay-text='正常|禁止'  {{ d.status == 1 ? 'checked' : '' }}>
                     </script>
                     <script type="text/html" id="barDemo">
                         <button type="button" class="layui-btn layui-btn-xs" lay-event="edit"><i class="layui-icon layui-icon-edit"></i>编辑</button>
-                        <button type="button" class="layui-btn layui-btn-xs" lay-event="see"><i class="layui-icon layui-icon-edit"></i>详情</button>
+                        <button type="button" class="layui-btn layui-btn-xs" onclick="dropdown(this)">操作 <span class="caret"></span></button>
+                        <ul class="layui-nav-child layui-anim layui-anim-upbit">
+                            <li>
+                                <a href="javascript:void(0);" lay-event="money">
+                                    <i class="layui-icon layui-icon-edit"></i> 余额积分</a>
+                            </li>
+                            <li>
+                                <a href="javascript:void(0);" lay-event="see">
+                                    <i class="layui-icon layui-icon-edit"></i> 会员详情</a>
+                            </li>
+                            <li>
+                                <a href="javascript:void(0);" lay-event="give_level">
+                                    <i class="fa fa-gift" aria-hidden="true"></i> 赠送会员</a>
+                            </li>
+                            {{# if(d.vip_name){ }}
+                            <li>
+                                <a href="javascript:void(0);" lay-event="del_level">
+                                    <i class="fa fa-eraser" aria-hidden="true"></i> 清除等级</a>
+                            </li>
+                            {{# } }}
+                        </ul>
                     </script>
                 </div>
             </div>
@@ -255,7 +296,7 @@
         return [
                 {type:'checkbox'},
                 {field: 'uid', title: '编号', width:'6%',event:'uid'},
-                {field: 'avatar', title: '头像', event:'open_image', width: '6%', templet: '<p><img class="avatar" style="cursor: pointer" class="open_image" data-image="{{d.avatar}}" src="{{d.avatar}}" alt="{{d.nickname}}"></p>'},
+                {field: 'avatar', title: '头像', event:'open_image', width: '6%', templet: '<p lay-event="open_image"><img class="avatar" style="cursor: pointer" class="open_image" data-image="{{d.avatar}}" src="{{d.avatar}}" alt="{{d.nickname}}"></p>'},
                 {field: 'nickname', title: '姓名',templet:'#nickname'},
                 {field: 'now_money', title: '余额',width:'6%',sort:true,event:'now_money'},
                 {field: 'pay_count', title: '购买次数',align:'center',width:'6%'},
@@ -263,17 +304,17 @@
                 {field: 'integral', title: '积分',width:'6%',sort:true,event:'integral'},
                 {field: 'spread_uid_nickname', title: '推荐人',width:'6%'},
                 {field: 'sex', title: '性别',width:'4%'},
-                {field: 'add_time', title: '首次访问日期',align:'center',width:'12%'},
-                {field: 'last_time', title: '最近访问日期',align:'center',width:'12%'},
+                {field: 'data_time', title: '访问日期',align:'center',width:'12%',templet:'#data_time'},
                 {field: 'status', title: '状态',templet:"#checkboxstatus",width:'6%'},
                 {field: 'user_type', title: '用户类型',width:'6%'},
                 {fixed: 'right', title: '操作', width: '10%', align: 'center', toolbar: '#barDemo'}
-            ];
+        ];
     });
     layList.date('last_time');
     layList.date('add_time');
     layList.date('user_time');
     layList.date('time');
+    layList.date({elem:'#birthday',theme:'#393D49',type:'datetime'});
     //监听并执行 uid 的排序
     layList.sort(function (obj) {
         var layEvent = obj.field;
@@ -291,7 +332,7 @@
         }
     });
     //监听并执行 uid 的排序
-    layList.tool(function (event,data) {
+    layList.tool(function (event,data,obj) {
         var layEvent = event;
         switch (layEvent){
             case 'edit':
@@ -300,9 +341,36 @@
             case 'see':
                 $eb.createModalFrame(data.nickname+'-会员详情',layList.Url({a:'see',p:{uid:data.uid}}));
                 break;
+            case 'del_level':
+                $eb.$swal('delete',function(){
+                    $eb.axios.get(layList.U({a:'del_level',q:{uid:data.uid}})).then(function(res){
+                        if(res.status == 200 && res.data.code == 200) {
+                            $eb.$swal('success',res.data.msg);
+                            obj.update({vip_name:false});
+                            layList.reload();
+                        }else
+                            return Promise.reject(res.data.msg || '删除失败')
+                    }).catch(function(err){
+                        $eb.$swal('error',err);
+                    });
+                },{
+                    title:'您确定要清除【'+data.nickname+'】的会员等级吗?',
+                    text:'清除后无法恢复请谨慎操作',
+                    confirm:'是的我要清除'
+                })
+                break;
+            case 'give_level':
+                $eb.createModalFrame(data.nickname+'-赠送会员',layList.Url({a:'give_level',p:{uid:data.uid}}),{w:500,h:200});
+                break;
+            case 'money':
+                $eb.createModalFrame(data.nickname+'-积分余额修改',layList.Url({a:'edit_other',p:{uid:data.uid}}));
+                break;
+            case 'open_image':
+                $eb.openImage(data.avatar);
+                break;
         }
     });
-//    layList.sort('uid');
+    //layList.sort('uid');
     //监听并执行 now_money 的排序
     // layList.sort('now_money');
     //监听 checkbox 的状态
@@ -391,9 +459,39 @@
             action[type] && action[type]();
         })
     })
-    $(document).on('click',".open_image",function (e) {
-        var image = $(this).data('image');
-        $eb.openImage(image);
+    //下拉框
+    $(document).click(function (e) {
+        $('.layui-nav-child').hide();
     })
+    function dropdown(that){
+        var oEvent = arguments.callee.caller.arguments[0] || event;
+        oEvent.stopPropagation();
+        var offset = $(that).offset();
+        var top=offset.top-$(window).scrollTop();
+        var index = $(that).parents('tr').data('index');
+        $('.layui-nav-child').each(function (key) {
+            if (key != index) {
+                $(this).hide();
+            }
+        })
+        if($(document).height() < top+$(that).next('ul').height()){
+            $(that).next('ul').css({
+                'padding': 10,
+                'top': - ($(that).parent('td').height() / 2 + $(that).height() + $(that).next('ul').height()/2),
+                'left':offset.left-$(that).parents('td').offset().left-20,
+                'min-width': 'inherit',
+                'position': 'absolute'
+            }).toggle();
+        }else{
+            $(that).next('ul').css({
+                'padding': 10,
+                'top':$(that).parent('td').height() / 2 + $(that).height(),
+                'left':offset.left-$(that).parents('td').offset().left-20,
+                'min-width': 'inherit',
+                'position': 'absolute'
+            }).toggle();
+        }
+    }
+
 </script>
 {/block}

+ 1 - 1
application/admin/view/user/user_level/index.php

@@ -70,7 +70,7 @@
                                 </a>
                             </li>
                             <li>
-                                <a lay-event='delect' href="javascript:void(0)" >
+                                <a lay-event='delete' href="javascript:void(0)" >
                                     <i class="fa fa-paste"></i> 删除等级
                                 </a>
                             </li>

+ 2 - 2
application/admin/view/wechat/menus/index.php

@@ -139,11 +139,11 @@
                                             </div>
                                             <div class="list">
                                                 <p>备用网页url</p>
-                                                <input class="form-control" v-model="checkedMenu.pagepath" type="text" />
+                                                <input class="form-control" v-model="checkedMenu.url" type="text" />
                                             </div>
                                             <div class="list">
                                                 <p>小程序路径</p>
-                                                <input class="form-control" v-model="checkedMenu.url" type="text" />
+                                                <input class="form-control" v-model="checkedMenu.pagepath" type="text" />
                                             </div>
                                         </div>
                                         <!-- 多客服 -->

+ 386 - 98
application/admin/view/widget/images.php

@@ -1,111 +1,399 @@
 <!DOCTYPE html>
 <!--suppress JSAnnotator -->
 <html lang="zh-CN">
-<head>
-    <link href="{__PLUG_PATH}layui/css/layui.css" rel="stylesheet">
-    <script src="{__PLUG_PATH}jquery-1.10.2.min.js"></script>
-    <script src="{__PLUG_PATH}layui/layui.js"></script>
-</head>
-<style>
-    .layui-btn + .layui-btn{margin: 0;}
-    .main{ margin: 12px 0;}
-    .main-top{ border-bottom: 1px solid #e5e5e5;  height: 12px;  width: 100%;  position: fixed;  top: 0;  background-color: #FFFFFF;  z-index: 100;  }
-    .main .left{max-width:125px; height:100%;width: 115px;border-right: 1px solid #e5e5e5;border-left: 1px solid #e5e5e5;float: left;}
-    .main .left .left-top{position: fixed;padding: 10px 10px 0;height: 35px;border-bottom: 1px solid #e5e5e5; background-color: #eee;}
-    .main .left .tabs-left{overflow-y: auto;height: 100%;width:115px;position: fixed;top:58px;border-right: 1px solid #e5e5e5;}
-    .main ::-webkit-scrollbar{width: 3px;height: auto;background-color: #ddd;}
-    .main ::-webkit-scrollbar-thumb {
-        border-radius: 1px;
-        -webkit-box-shadow: inset 0 0 6px rgba(255,255,255,.3);
-        background-color: #333;
-    }
-    .main ::-webkit-scrollbar-track {
-        -webkit-box-shadow: inset 0 0 5px rgba(0,0,0,0.2);
-        border-radius: 1px;
-        background: #e5e5e5;
-    }
-    .main .left .nav{margin:0;padding-bottom: 100px;}
-    .main .left .nav li{padding: 4px;height: 22px;}
-    .main .left .nav li.active{background-color: #293846;border-left: 2px solid #19AA8D;}
-    .main .left .nav li.active a{color: #a7b1c2;}
-    .main .left .nav li.child{padding: 2px;padding-left: 7px;}
-    .main .right{width: calc(100% - 117px);float: right;}
-    .main .right .right-top{position: fixed;background-color: #fff;  z-index: 1000;width: 100%;padding: 7px 10px 0;height: 38px;border-bottom: 1px solid #e5e5e5;border-top: 1px solid #e5e5e5;}
-    .main .right .imagesbox{position: fixed;top:58px;min-height: 200px;height: calc(100% - 88px);;overflow-y: auto;}
-    .main .right .imagesbox .image-item{position: relative;display: inline-block;  width: 112px;height: 112px;  border: 1px solid #ECECEC;background-color: #F7F6F6;  cursor: default;  margin: 10px 0 0 10px;padding: 5px;}
-    .main .right .imagesbox .image-item img{width: 112px;height: 112px;}
-    .main .right .imagesbox .on{border: 3px dashed #0092DC;padding: 3px;}
-    .main .right .foot-tool{position: fixed;bottom: 0px;width: calc(100% - 117px);background-color:#fff;height: 30px;padding: 7px 10px 0;border-top: 1px solid #e5e5e5;}
-    .main .right .foot-tool .page{padding: 0px 10px;float: right;}
-    .main .right .foot-tool .page ul{width: 100%}
-    .main .right .foot-tool .page li{float: left;margin: 0px;}
-    .main .right .foot-tool .page .disabled span{background-color: #e6e6e6!important;  color: #bbb!important;  cursor: no-drop;padding: 0px 10px;  height: 30px;  line-height: 30px;  display: block;}
-    .main .right .foot-tool .page .active span{background-color: #428bca;color: #fff;border-color: #428bca;padding: 0px 10px;  height:30px;  line-height: 30px;  display: block;}
-    .main .right .foot-tool .page li a{border: 1px solid #e5e5e5;padding: 0px 10px;  height: 28px;  line-height: 28px;  display: block;}
-</style>
-<body>
-<div class="main">
-    <div class="main-top"></div>
-    <div class="left">
-        <div class="left-top">
-            <button class="layui-btn layui-btn-primary layui-btn-xs" id="addcate" title="添加分类"><i class="layui-icon layui-icon-add-circle-fine"></i></button>
-            <button class="layui-btn layui-btn-primary layui-btn-xs" id="editcate" title="编辑当前分类"><i class="layui-icon layui-icon-edit"></i></button>
-            <button class="layui-btn layui-btn-primary layui-btn-xs" id="deletecate" title="删除当前分类"><i class="layui-icon layui-icon-delete"></i></button>
-        </div>
-        <div class="tabs-left">
-            <ul class="nav nav-tabs">
-                <li {if condition="$pid eq 0" } class="active" {/if}><a href="{:Url('index',array('pid'=>0,'fodder'=>$Request.param.fodder,'big'=>$Request.param.big))}">所有分类</a></li>
-                {volist name="$typearray" id="vo" key="k"}
-                    {if condition="$vo.id eq $pid"}
-                     <li class="active"><a href="{:Url('index',array('pid'=>$vo.id,'fodder'=>$Request.param.fodder,'big'=>$Request.param.big))}">{$vo.name}</a></li>
-                {else}
-                     <li ><a href="{:Url('index',array('pid'=>$vo.id,'fodder'=>$Request.param.fodder,'big'=>$Request.param.big))}">{$vo.name}</a></li>
-                {/if}
-                {volist name="$vo.child" id="voo" key="kk"}
-                       <li class="child {if condition="$voo.id eq $pid"} active{/if}">
-                        <a href="{:Url('index',array('pid'=>$voo.id,'fodder'=>$Request.param.fodder,'big'=>$Request.param.big))}">{if condition="$kk eq count($vo.child)"}└{else/}├{/if}{$voo.name}</a>
-                        </li>
-                    {/volist}
-                {/volist}
-            </ul>
-        </div>
-    </div>
-    <div class="right">
-        <div class="right-top">
-            <button class="layui-btn layui-btn-sm layui-btn-primary"  id="moveimg">移动分类</button>
-            <button class="layui-btn  layui-btn-sm layui-btn-primary" id="deleteimg">删除图片</button>
-        </div>
-        <div class="imagesbox">
-            {volist name="list" id="vo"}
-            <div class="image-item">
-                <div class="image-delete" data-url="{:Url('delete',array('att_id'=>$vo.att_id))}"></div>
-                {if condition="$Request.param.small eq 1"}
-                <img class="pic" src="{$vo.satt_dir|ltrim='.'}" id="{$vo.att_id}"/>
-                {else/}
-                <img class="pic" src="{$vo.att_dir|ltrim='.'}" id="{$vo.att_id}"/>
-                {/if}
+    <head>
+        <link href="{__PLUG_PATH}layui/css/layui.css" rel="stylesheet">
+        <script src="{__PLUG_PATH}jquery-1.10.2.min.js"></script>
+        <script src="{__PLUG_PATH}layui/layui.all.js"></script>
+        <script src="{__PLUG_PATH}vue/dist/vue.min.js"></script>
+    </head>
+    <style>
+        body{-moz-user-select:none;-webkit-user-select:none;-ms-user-select:none;user-select:none;}
+        .layui-fluid{margin:0;padding: 0;}
+        .layadmin-homepage-shadow{box-shadow: 0 1px 1px rgba(0,0,0,.05);background-color: #fff;border-radius: 0;border: 1px solid #e7ecf3;}
+        .layui-tree-txt{cursor: pointer;}
+        .clearfix:after{content:"";display:block;visibility:hidden;clear:both;height:0;}
+        .image-box{padding-top: 10px}
+        .image-box .image .layui-img-box{margin: 5px;border: 2px solid #ffffff;height: 100px;line-height: 100px;text-align: center;}
+        .image-box .image .layui-img-box.on{border: 2px solid #5FB878;}
+        .image-box .image .layui-img-box img{width: 90%;max-height:90%;vertical-align:middle;}
+        .page .image_page{text-align: right;}
+        .page .layui-box{text-align: left;}
+        .layui-tree-txt.on{color:#1E9FFF}
+        .line1{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;width: 90%;}
+        .layadmin-homepage-panel.left ::-webkit-scrollbar{width: 3px;height: auto;background-color: #ddd;}
+        .layadmin-homepage-panel.left ::-webkit-scrollbar-thumb {border-radius: 1px;-webkit-box-shadow: inset 0 0 6px rgba(255,255,255,.3);background-color: #333;}
+        .layadmin-homepage-panel.left ::-webkit-scrollbar-track {-webkit-box-shadow: inset 0 0 5px rgba(0,0,0,0.2);border-radius: 1px;background: #e5e5e5;}
+        #app .layui-tree-btnGroup{color: #ffffff;padding: 3px 7px;position: absolute;top: -28px;left: 30px;background-color: #1E9FFF;}
+        #app .layui-tree-btnGroup .layui-layer-TipsT{border-right-color: #1E9FFF;color: #ffffff}
+        #app .layui-tree-iconClick{margin:0 0 0 9px;}
+    </style>
+<body style="background-color: #f2f2f2">
+
+<div class="layui-fluid" id="app">
+    <div class="layui-row">
+        <div class="layui-col-md2 layui-col-xs2 layui-col-sm2">
+            <div class="layadmin-homepage-panel layadmin-homepage-shadow left">
+                <div class="layui-card text-center">
+                    <div class="layui-card-header">
+                        <div class="layui-unselect layui-form-select layui-form-selected">
+                            <div class="layui-select-title">
+                                <input type="text" name="title" v-model="searchTitle" placeholder="搜索分类" style="height: 24px;line-height:24px;padding-left:7px;font-size: 12px;display: inline;padding-right: 0;width: 100%;" autocomplete="off" class="layui-input layui-input-search" @keydown="search">
+<!--                                <i class="layui-icon layui-icon-search" @click="search"  style="cursor: pointer;margin:0 3px;"></i>-->
+                            </div>
+                        </div>
+                    </div>
+                    <div class="layui-card-body" style="padding: 0;height: 455px;overflow:auto;">
+<!--                        <div class="layadmin-homepage-pad-ver">-->
+<!--                            <button type="button" class="layui-btn layui-btn-normal layui-btn-xs" style="width: 80%" @click="addCategory">添加</button>-->
+<!--                        </div>-->
+                        <div ref="tree" class="demo-tree demo-tree-box">
+                            <div class="layui-tree layui-tree-line">
+                                <div class="layui-tree-set layui-tree-setHide">
+                                    <div class="layui-tree-entry">
+                                        <div class="layui-tree-main" @click="OpenTree({child:[],id:0})">
+                                            <span class="layui-tree-iconClick">
+                                                <i class="layui-icon">&nbsp;&nbsp;&nbsp;</i>
+                                            </span>
+                                            <span class="layui-tree-txt" :class="pid == 0 ? 'on' : '' ">全部图片</span>
+                                        </div>
+                                    </div>
+                                </div>
+                                <div class="layui-tree-set layui-tree-setHide" :class=" value.isOpen ? 'layui-tree-spread' : '' " v-for="(value,k) in categoryList">
+                                    <div class="layui-tree-entry" @mouseover.stop="changeActive(value,k)" @mouseout.stop="removeActive(value,k)">
+                                        <div class="layui-tree-main" @click="OpenTree(value,k)">
+                                            <span class="layui-tree-iconClick">
+                                                <i class="layui-icon layui-icon-triangle-d" v-if="value.child.length && value.isOpen"></i>
+                                                <i class="layui-icon layui-icon-triangle-r" v-else-if="value.child.length && !value.isOpen"></i>
+                                                <i class="layui-icon " v-else>&nbsp;&nbsp;&nbsp;</i>
+                                            </span>
+                                            <span class="layui-tree-txt line1" :class="pid == value.id ? 'on': '' " v-text="value.name"></span>
+                                        </div>
+                                        <div class="layui-btn-group layui-tree-btnGroup layui-layer layui-layer-tips" v-show="value.isShow">
+                                            <div>
+                                                <i class="layui-icon layui-icon-add-1" @click.stop ="addCategory(value)" title="添加"></i>
+                                                <i class="layui-icon layui-icon-edit" @click.stop ="updateCategory(value)" title="编辑"></i>
+                                                <i class="layui-icon layui-icon-delete" v-if="!value.child.length" title="删除" @click.stop ="delCategory(value)"></i>
+                                            </div>
+                                            <i class="layui-layer-TipsG layui-layer-TipsT"></i>
+                                        </div>
+                                    </div>
+                                    <div class="layui-tree-pack layui-tree-lineExtend layui-tree-showLine" v-show="value.isOpen" style="display: block">
+                                        <div class="layui-tree-set" v-for="(item,key) in value.child">
+                                            <div class="layui-tree-entry">
+                                                <div class="layui-tree-main" @click="OpenTree(item,key)">
+                                                    <span class="layui-tree-iconClick">
+                                                        <i class="layui-icon"></i>
+                                                    </span>
+                                                    <span class="layui-tree-txt line1" :class="pid == item.id ? 'on': '' " v-text="item.name"></span>
+                                                </div>
+                                                <div class="layui-btn-group layui-tree-btnGroup layui-layer layui-layer-tips" @mouseover.stop ="changeActive(item,k,key)" @mouseout.stop ="removeActive(item,k,key)">
+                                                    <div>
+                                                        <i class="layui-icon layui-icon-edit" @click.stop ="updateCategory(item,value.pid)" title="编辑"></i>
+                                                        <i class="layui-icon layui-icon-delete" @click.stop ="delCategory(item,value.pid)" title="删除"></i>
+                                                    </div>
+                                                    <i class="layui-layer-TipsG layui-layer-TipsT"></i>
+                                                </div>
+                                            </div>
+                                        </div>
+                                    </div>
+                                </div>
+                            </div>
+                        </div>
+                    </div>
+                </div>
             </div>
-            {/volist}
         </div>
-        <div class="foot-tool">
-            <button class="layui-btn layui-btn-sm"  id="upload">上传图片</button>
-            <button class="layui-btn layui-btn-normal layui-btn-sm" id="ConfirmChoices">使用选中的图片</button>
-<!--            <button class="layui-btn layui-btn-danger layui-btn-sm" id="close" >关闭</button>-->
-            <div class="page">{$page}</div>
+        <div class="layui-col-md10 layui-col-xs10 layui-col-sm10">
+            <div class="layadmin-homepage-panel layadmin-homepage-shadow">
+                <div class="layui-card text-center">
+                    <div class="layui-card-header">
+                        <div class="layadmin-homepage-pad-ver" style="text-align: left">
+                            <div class="layui-btn-group">
+                                <button type="button" class="layui-btn layui-btn-normal layui-btn-sm"  @click="addCategory">添加分类</button>
+                                <button type="button" class="layui-btn layui-btn-normal layui-btn-sm" ref="upload">上传图片</button>
+                                <button type="button" class="layui-btn layui-btn-warm layui-btn-sm" :class="selectImages.length ? '':'layui-btn-disabled' " @click="moveCate">移动分类</button>
+                                <button type="button" class="layui-btn layui-btn-danger layui-btn-sm" :class="selectImages.length ? '':'layui-btn-disabled' " @click="delImage">删除图片</button>
+
+                            </div>
+                        </div>
+                    </div>
+                    <div class="layui-card-body clearfix image-box" style="padding: 10px;height: 360px;">
+                        <div class="layui-col-md2 layui-col-xs2 layui-col-sm2 image" v-for="(item,index) in imageList">
+                            <div class="layui-img-box"  :class="item.isSelect ? 'on': '' ">
+                                <img :src="item.satt_dir" v-if="small == 1" @click="changImage(item,index)">
+                                <img :src="item.satt_dir" v-else @click="changImage(item,index)">
+                            </div>
+                        </div>
+                        <div class="empty-image" style="width: 100%;height: 100%;text-align: center;" v-if="!imageList.length && loading == false">
+                            <div class="layui-img-box">
+                                <img src="/public/system/images/empty.jpg" style="height: 400px;" alt="" >
+                            </div>
+                        </div>
+                    </div>
+                    <div class="layui-card-body clearfix page">
+                        <div class="layui-col-md4 layui-col-xs4 layui-col-sm4">
+                            <div class="layui-box" style="margin: 10px 0;">
+                                <button type="button" class="layui-btn layui-btn-normal layui-btn-sm" :class="selectImages.length ? '':'layui-btn-disabled' " @click="useImages">使用选中的图片</button>
+                            </div>
+                        </div>
+                        <div class="layui-col-md8 layui-col-xs8 layui-col-sm8 image_page" ref="image_page"></div>
+                    </div>
+                </div>
+            </div>
         </div>
     </div>
 </div>
 </body>
 </html>
+<script src="{__ADMIN_PATH}js/layuiList.js"></script>
 <script>
-    var pid = {$pid};//当前图片分类ID
-    var parentinputname = '{$Request.param.fodder}';//父级input name
-    var uploadurl = "{:Url('upload',array('pid'=>$pid))}"; //上传图片地址
-    var deleteurl = "{:Url('delete')}";//删除图片地址
-    var moveurl = "{:Url('moveimg')}";//移动图片地址
-    var addcate = "{:Url('addcate',array('id'=>$pid))}";//添加图片分类地址
-    var editcate = "{:Url('editcate',array('id'=>$pid))}";//编辑图片分类地址
-    var deletecate = "{:Url('deletecate')}";//删除图片分类地址
+    var pid = {$pid},small = {$Request.param.small ? : 0} ,parentinputname = '{$Request.param.fodder}';//当前图片分类ID
+
+    new Vue({
+        el: "#app",
+        data: {
+            categoryList:[],
+            searchTitle:'',
+            pid:pid,
+            imageList:[],
+            page:1,
+            limit:18,
+            loading:false,
+            small:small,
+            selectImages:[],
+            selectImagesIDS:[],
+            uploadInst:null,
+        },
+        watch:{
+            page:function () {
+                this.getImageList();
+            },
+        },
+        methods:{
+            //删除图片
+            delImage:function(){
+                var that=this;
+                if(!this.selectImages.length) return;
+                layList.layer.confirm('是否要删除选中图片?', {
+                    btn: ['是的我要删除','我想想把'] //按钮
+                }, function(){
+                    layList.basePost(that.U({a:'delete'}),{imageid:that.selectImagesIDS},function (res) {
+                        layList.msg(res.msg);
+                        that.getImageList();
+                        that.$set(that,'selectImages',[]);
+                        that.$set(that,'selectImagesIDS',[]);
+                    },function (res) {
+                        layList.msg(res.msg);
+                    })
+                })
+            },
+            //移动图片分类
+            moveCate:function(){
+                if(!this.selectImages.length) return;
+                return this.getOpenWindow('移动图片',this.U({a:'moveimg'})+'?imgaes='+this.selectImagesIDS);
+            },
+            //使用选中图片
+            useImages:function(){
+                if(!this.selectImages.length) return;
+                //判断表单限制图片个数
+                if(typeof parent.$f != 'undefined'){
+                    //已有图片个数
+                    var nowpics = parent.$f.getValue(parentinputname).length;
+                    //设置最大个数
+                    var maxlength = parent.$f.model()[parentinputname].rule.props.maxLength;
+                    //已选图片个数
+                    var selectlength = this.selectImages.length;
+                    //还可以选择多少张
+                    var surplus = maxlength-nowpics;
+                    if(nowpics+selectlength > maxlength){
+                        return layList.msg('最多只能选择 '+ surplus +' 张');
+                    }
+                }
+                //编辑器中
+                if(parentinputname == 'editor'){
+                    var list =  [];console.log(this.selectImages);
+                    for(var i = 0;i < this.selectImages.length;i++){
+                        list.push({
+                            _src: this.selectImages[i],
+                            src:this.selectImages[i]
+                        });
+                    }
+                    parent.insertEditor(list);
+                    var index = parent.layer.getFrameIndex(window.name);
+                    parent.layer.close(index);
+                }else{
+                    //form表单中
+                    if(typeof parent.$f != 'undefined'){
+                        var value = parent.$f.getValue(parentinputname);//父级input 值
+                        var list = value || [];
+                        for(var i = 0;i < this.selectImages.length;i++){
+                            if(value.indexOf(this.selectImages[i]) == -1) list.push(this.selectImages[i]);
+                        }
+                        parent.$f.changeField(parentinputname,list);
+                        parent.$f.closeModal();
+                    }else{
+                        //独立图片选择页面
+                        parent.changeIMG(parentinputname,this.selectImages[0]);
+                        var index = parent.layer.getFrameIndex(window.name);
+                        parent.layer.close(index);
+                    }
+                }
+
+            },
+            //图片选中和取消
+            changImage:function(item,index){
+                var len = this.imageList.length,selectImages=[],selectImagesIDS=[];
+
+                this.$set(this.imageList[index],'isSelect',item.isSelect == undefined ? true : !item.isSelect);
+                for (var i=0;i<len;i++){
+                    if(this.imageList[i].isSelect === true) {
+                        selectImages.push(small == 1 ? this.imageList[i]['satt_dir'] : this.imageList[i]['att_dir']);
+                        selectImagesIDS.push(this.imageList[i]['att_id']);
+                    }
+                }
+                this.$set(this,'selectImages',selectImages);
+                this.$set(this,'selectImagesIDS',selectImagesIDS);
+            },
+            //获取图片列表
+            getImageList:function(){
+                var that = this;
+                if(that.loading) return;
+                that.loading = true;
+                var index = layList.layer.load(1, {shade: [0.1,'#fff']});
+                layList.baseGet(this.U({a:'get_image_list',q:{pid:this.pid,page:this.page,limit:this.limit}}),function (res) {
+                    that.loading = false;
+                    that.$set(that,'imageList',res.data.list);
+                    layList.layer.close(index);
+                   if(that.page == 1){
+                       layList.laypage.render({
+                           elem: that.$refs.image_page
+                           ,count: res.data.count
+                           ,limit:that.limit
+                           ,theme: '#1E9FFF',
+                           jump:function (obj) {
+                               that.page=obj.curr;
+                           }
+                       });
+                   }
+                },function () {
+                    that.loading = false;
+                    layList.layer.close(index);
+                });
+            },
+            //查询分类
+            search:function(){
+//                if(!this.searchTitle) return layList.msg('请输入搜索内容!');
+                this.getCategoryList();
+            },
+            //打开和关闭树形
+            OpenTree:function(item,index){
+                this.pid = item.id;
+                if(item.child.length){
+                    item.isOpen == undefined ? false : item.isOpen;
+                    this.$set(this.categoryList[index],'isOpen',!item.isOpen);
+                }else{
+                    this.page = 1;
+                    this.$set(this,'selectImages',[]);
+                    this.$set(this,'selectImagesIDS',[]);
+                    this.getImageList();
+                }
+                this.uploadInst.reload({
+                    url:this.U({a:'upload'})+'?pid='+this.pid
+                });
+            },
+            //组装URL
+            U:function(opt){
+                opt = typeof opt == 'object' ? opt : {};
+                return layList.U({m:'admin',c:"widget.images",a:opt.a || '',q:opt.q || {},p:opt.q || {}});
+            },
+            //获取分类
+            getCategoryList:function(){
+                var that=this;
+                layList.baseGet(that.U({a:'get_image_cate',q:{name:this.searchTitle}}),function (res) {
+                    that.$set(that,'categoryList',res.data);
+                });
+            },
+            //鼠标移入显示图标
+            changeActive:function(item,indexK,index){
+                if(index)
+                    this.$set(this.categoryList[indexK]['child'],'isShow',true);
+                else
+                    this.$set(this.categoryList[indexK],'isShow',true);
+            },
+            //鼠标移出隐藏
+            removeActive:function(item,indexK,index){
+                if(index)
+                    this.$set(this.categoryList[indexK]['child'],'isShow',false);
+                else
+                    this.$set(this.categoryList[indexK],'isShow',false);
+            },
+            //添加分类
+            addCategory:function (item,pid) {
+                item = item == undefined ? {} : item;
+                var id = item.id == undefined ? 0 : item.id,
+                    pid = pid == undefined ? 0 : pid;
+                return this.getOpenWindow(item.name ? item.name+'编辑' : '新增分类',this.U({a:'addcate',q:{id:pid ==0 ? id : pid }}));
+            },
+            //修改分类
+            updateCategory:function(item,pid){
+                item = item == undefined ? {} : item ;
+                pid = pid == undefined ? 0 : pid;
+                return this.getOpenWindow(item.name+'编辑',this.U({a:'editcate',q:{id:item.id}}));
+            },
+            //删除分类
+            delCategory:function (item,pid) {
+                var that=this;
+                if(item.child.length) return layList.msg('请先删除子分类再尝试删除此分类!');
+                layList.layer.confirm('是否要删除['+item.name+']分类?', {
+                    btn: ['是的我要删除','我想想把'] //按钮
+                }, function(){
+                    layList.baseGet(that.U({a:'deletecate',q:{id:item.id}}),function (res) {
+                        layList.msg(res.msg,function () {
+                            that.getCategoryList();
+                        });
+                    });
+                });
+            },
+            //打开一个窗口
+            getOpenWindow:function(title,url,opt){
+                opt = opt == undefined ? {w:340,h:265} : opt;
+                return layList.layer.open({
+                    type: 2,
+                    title: title,
+                    shade: [0],
+                    area: [opt.w+"px" , opt.h+'px'],
+                    anim: 2,
+                    content: [url, 'no'],
+                });
+            },
+            //回调
+            SuccessCateg:function () {
+                this.getCategoryList();
+            },
+            uploal:function () {
+                var that=this;
+                this.uploadInst=layList.upload.render({
+                    elem: this.$refs.upload
+                    ,url: this.U({a:'upload'})+'?pid='+this.pid
+                    ,multiple: true
+                    ,auto:true
+                    ,size: 2097152 //限制文件大小,单位 KB
+                    ,done: function(res){
+                        layList.layer.msg(res.msg,{time:3000});
+                        that.getImageList();
+                    }
+                });
+            }
+        },
+        mounted:function () {
+            this.getCategoryList();
+            this.getImageList();
+            window.SuccessCateg = this.SuccessCateg;
+            this.uploal();
+        }
+    })
+
+
 </script>
-<script src="{__MODULE_PATH}widget/images.js"></script>
 

+ 9 - 0
application/core/behavior/UserBehavior.php

@@ -7,6 +7,7 @@
 
 namespace app\core\behavior;
 
+use app\admin\model\system\SystemAttachment;
 use app\core\model\user\UserLevel;
 use service\HookService;
 use app\core\model\user\User;
@@ -75,4 +76,12 @@ class UserBehavior
         return UserLevel::setLevelComplete($user['uid'],$number);
     }
 
+    /*
+     * 清理昨天用户产生的附件信息
+     * */
+    public static function emptyYesterDayAttachment()
+    {
+        return SystemAttachment::emptyYesterDayAttachment();
+    }
+
 }

+ 2 - 5
application/core/model/ApiMenus.php

@@ -7,16 +7,13 @@
 
 namespace app\core\model;
 
-use traits\ModelTrait;
-use basic\ModelBasic;
-
 /*
  * Api接口列表
  * class ApiMenus
  * */
-class ApiMenus extends ModelBasic
+class ApiMenus
 {
-    use ModelTrait;
+
 
     /*
      * 接口列表配置

+ 22 - 23
application/core/model/system/SystemUserTask.php

@@ -130,7 +130,7 @@ class SystemUserTask extends ModelBasic
     public static function ConsumptionAmount($task_id,$uid=0,$start_time=0,$number=0)
     {
         $isComplete=false;
-        $SumPayPrice=self::getDb('store_order')->where('paid',1)->where('refund_status',0)->where('is_del',0)->where('uid',$uid)->sum('pay_price');
+        $SumPayPrice=self::getDb('store_order')->where(['paid'=>1,'refund_status'=>0,'is_del'=>0,'uid'=>$uid])->where('add_time','>',$start_time)->sum('pay_price');
         if($SumPayPrice >= $number) $isComplete=UserTaskFinish::setFinish($uid,$task_id) ? true : false;
         return ['还需消费{$num}元',$SumPayPrice,$isComplete];
     }
@@ -146,7 +146,7 @@ class SystemUserTask extends ModelBasic
     public static function ConsumptionFrequency($task_id,$uid=0,$start_time=0,$number=0)
     {
         $isComplete=false;
-        $countPay=self::getDb('store_order')->where('paid',1)->where('refund_status',0)->where('is_del',0)->where('uid',$uid)->count();
+        $countPay=self::getDb('store_order')->where(['paid'=>1,'refund_status'=>0,'is_del'=>0,'uid'=>$uid])->where('add_time','>',$start_time)->count();
         if($countPay >= $number) $isComplete=UserTaskFinish::setFinish($uid,$task_id) ? true : false;
         return ['还需消费{$num}次',$countPay,$isComplete];
     }
@@ -194,7 +194,8 @@ class SystemUserTask extends ModelBasic
     public static function SatisfactionIntegral($task_id,$uid=0,$start_time=0,$number=0)
     {
         $isComplete=false;
-        $sumNumber=UserBill::where(['uid'=>$uid,'category'=>'integral','pm'=>1])->where('type','in',['system_add','sign'])->sum('number');
+        $sumNumber=UserBill::where(['uid'=>$uid,'category'=>'integral','pm'=>1])->where('add_time','>',$start_time)->where('type','in',['system_add','sign'])->sum('number');
+        file_put_contents('9.txt',$sumNumber.'|'.$number.'|'.$start_time);
         if($sumNumber >= $number) $isComplete=UserTaskFinish::setFinish($uid,$task_id) ? true : false;
         return ['还需要{$num}经验',$sumNumber,$isComplete];
     }
@@ -226,7 +227,7 @@ class SystemUserTask extends ModelBasic
     public static function CumulativeAttendance($task_id,$uid=0,$start_time=0,$number=0)
     {
         $isComplete=false;
-        $sumCount=UserBill::where(['uid'=>$uid,'category'=>'integral','pm'=>1])->where('type','in',['sign'])->count();
+        $sumCount=UserBill::where(['uid'=>$uid,'category'=>'integral','pm'=>1])->where('add_time','>',$start_time)->where('type','in',['sign'])->count();
         if($sumCount >= $number) $isComplete=UserTaskFinish::setFinish($uid,$task_id) ? true : false;
         return ['还需签到{$num}天',$sumCount,$isComplete];
     }
@@ -247,6 +248,7 @@ class SystemUserTask extends ModelBasic
         $task_type=$task->task_type;
         if($task_type && method_exists(self::class,$task_type)){
             try{
+                $start_time=User::getCleanTime($uid);
                 return self::$task_type($task_id,$uid,$start_time,$task->number);
             }catch (\Exception $e){
                 return self::setErrorInfo($e->getMessage());
@@ -277,23 +279,20 @@ class SystemUserTask extends ModelBasic
     public static function getTashList($level_id,$uid=0,$level=null,$expire=1400)
     {
         $level_id=is_string($level_id) ? (int)$level_id : $level_id;
-        if(Cache::has('Tash_list_common_'.$level_id))
-            $list=Cache::get('Tash_list_common_'.$level_id);
-        else{
-            $list=self::visibleWhere()->where('level_id',$level_id)->field(['name','real_name','task_type','illustrate','number','id'])->order('sort desc')->select();
-            $list=count($list) ? $list->toArray() : [];
-            Cache::set('Tash_list_common_'.$level_id,$list,$expire);
-        }
+        $list=self::visibleWhere()->where('level_id',$level_id)->field(['name','real_name','task_type','illustrate','number','id'])->order('sort desc')->select();
+        $list=count($list) ? $list->toArray() : [];
        if($uid==0) return $list;
        if($level===null) $level=SystemUserLevel::getLevelInfo($uid);
-       $add_time=self::getDb('user')->where('uid',$uid)->value('add_time');
-       if($level===false) $startTime=$add_time;
-       else $startTime=isset($level['add_time']) ? $level['add_time'] : $add_time;
+       //获取下一个vip的id
        $LeveId=SystemUserLevel::getNextLevelId($level['id']);
        $is_clear=SystemUserLevel::getClear($level['id']);
        if($is_clear==false && $LeveId==$level_id) $is_clear=true;
        $reach_count=self::getTaskComplete($level_id,$uid,true);
-       return ['reach_count'=>$reach_count,'task'=>self::tidyTask($list,$uid,$is_clear,$startTime)];
+       return [
+           'list'=>$list,
+           'reach_count'=>$reach_count,
+           'task'=>self::tidyTask($list,$uid,$is_clear,User::getCleanTime($uid)),
+       ];
     }
 
     /*
@@ -391,19 +390,19 @@ class SystemUserTask extends ModelBasic
                 $item['finish']=1;
                 $item['task_type_title']='';
             }else{
-                if($is_clear){
+//                if($is_clear){
                     list($new_number, $speed, $task_type_title, $finish) = self::set_task_type($item, $uid, $startTime);
                     $item['new_number'] = $new_number;
                     $item['speed'] = $speed;
                     $item['task_type_title'] = $task_type_title;
                     $item['finish'] = $finish;
-                }else {
-                    list($new_number, $speed, $task_type_title, $finish) = self::set_task_type($item,-1,time()+86400);
-                    $item['new_number'] = $new_number;
-                    $item['speed'] = $speed;
-                    $item['task_type_title'] = $task_type_title;
-                    $item['finish'] = $finish;
-                }
+//                }else {
+//                    list($new_number, $speed, $task_type_title, $finish) = self::set_task_type($item,-1,time()+86400);
+//                    $item['new_number'] = $new_number;
+//                    $item['speed'] = $speed;
+//                    $item['task_type_title'] = $task_type_title;
+//                    $item['finish'] = $finish;
+//                }
             }
         }
         return $task;

+ 9 - 0
application/core/model/user/User.php

@@ -16,4 +16,13 @@ class User extends ModelBasic
 {
     use ModelTrait;
 
+    /*
+     * 获取会员是否被清除过的时间
+     * */
+    public static function getCleanTime($uid)
+    {
+        $user=self::where('uid',$uid)->field(['add_time','clean_time'])->find();
+        if(!$user) return 0;
+        return $user['clean_time'] ? $user['clean_time'] : $user['add_time'];
+    }
 }

+ 11 - 2
application/core/model/user/UserBill.php

@@ -78,6 +78,15 @@ class UserBill extends ModelBasic
             ->where('status',1)->sum('number');
     }
 
+    /*
+     * 获取总佣金
+     * */
+    public static function getSystemAdd($uid)
+    {
+        return self::where('uid',$uid)->where('category','now_money')->where('type','system_add')->where('pm',1)
+            ->where('status',1)->sum('number');
+    }
+
 
     /*
      * 累计充值
@@ -238,9 +247,9 @@ class UserBill extends ModelBasic
         if(!$user) return self::setErrorInfo('用户不存在!');
         $cachename='Share_'.$uid;
         if(Cache::has($cachename)) return false;
-        $res=self::income('用户分享记录',$uid,'share',1,0,0,date('Y-m-d H:i:s',time()).':用户分享');
+        $res=self::income('用户分享记录',$uid,'share','share',1,0,0,date('Y-m-d H:i:s',time()).':用户分享');
         Cache::set($cachename,1,$cd);
-        HookService::afterListen('user_leve',$user,false,UserBehavior::class);
+        HookService::afterListen('user_level',$user,null,false,UserBehavior::class);
         return true;
     }
 

+ 11 - 7
application/core/model/user/UserLevel.php

@@ -59,6 +59,7 @@ class UserLevel extends ModelBasic
             $add_valid_time=$stay+$add_valid_time+time();
             $data['is_forever']=$vipinfo->is_forever;
             $data['valid_time']=$add_valid_time;
+            User::where('uid',$uid)->update(['level'=>$level_id]);
             return self::where(['uid'=>$uid,'level_id'=>$level_id])->update($data);
         }else{
             $data=[
@@ -74,9 +75,12 @@ class UserLevel extends ModelBasic
             if($data['is_forever'])
                 $data['valid_time']=0;
             else
-                $data['valid_time']=$add_valid_time;
+                $data['valid_time']=$add_valid_time+time();
             $data['mark']='尊敬的用户'.$userinfo['nickname'].'在'.date('Y-m-d H:i:s',time()).'成为了'.$vipinfo['name'];
-            return self::set($data);
+            $res=self::set($data);
+            if(!$res) return false;
+            User::where('uid',$uid)->update(['level'=>$level_id]);
+            return $res;
         }
     }
 
@@ -89,11 +93,11 @@ class UserLevel extends ModelBasic
     {
         $model = self::valiWhere();
         if ($grade) $model = $model->where('grade', '<', $grade);
-        $level = $model->where('uid', $uid)->order('grade desc')->field('level_id,is_forever,valid_time,id')->find();
+        $level = $model->where('uid', $uid)->order('grade desc')->field('level_id,is_forever,valid_time,id,status,grade')->find();
         if (!$level) return false;
         if ($level->is_forever) return $level->id;
         //会员已经过期
-        if (time() < $level->valid_time){
+        if (time() > $level->valid_time){
             if($level->status==1){
                 $level->status=0;
                 $level->save();
@@ -111,7 +115,7 @@ class UserLevel extends ModelBasic
      * @return array
      * */
     public static function getUserLevelInfo($id,$keyName=''){
-        $vipinfo=self::valiWhere('a')->where('a.id',$id)->field('l.id,a.add_time,a.discount,a.level_id,l.name,l.money,l.icon,l.is_pay')
+        $vipinfo=self::valiWhere('a')->where('a.id',$id)->field('l.id,a.add_time,l.discount,a.level_id,l.name,l.money,l.icon,l.is_pay,l.grade')
             ->join('__SYSTEM_USER_LEVEL__ l','l.id=a.level_id')->find();
         if($keyName) if(isset($vipinfo[$keyName])) return $vipinfo[$keyName]; else return '';
         return $vipinfo;
@@ -148,8 +152,8 @@ class UserLevel extends ModelBasic
         $res2=true;
         try{
             if($level===false){
-                //没有成为会员的从用户添加的时间开始算起
-                $add_time=$user['add_time'];
+                //没有成为会员的从用户添加的时间开始算起,如果被清理过会员从清理的时间开始算起
+                $add_time=$user['clean_time'] ? $user['clean_time'] :$user['add_time'];
             }else{
                 $add_time=self::getUserLevelInfo($level,'add_time');
             }

文件差异内容过多而无法显示
+ 34 - 1
application/core/model/user/UserTaskFinish.php


+ 2 - 0
application/core/traits/LogicTrait.php

@@ -12,6 +12,8 @@ trait LogicTrait
 
     protected $items = [];
 
+    protected static $instance = null;
+
     /*
      * 魔术方法 对不可访问或不存在的属性调用
      *

+ 12 - 14
application/core/util/MiniProgramService.php

@@ -33,21 +33,19 @@ class MiniProgramService implements ProviderInterface
         $payment = SystemConfigService::more(['pay_routine_mchid','pay_routine_key','pay_routine_client_cert','pay_routine_client_key','pay_weixin_open']);
         $config = [];
         $config['mini_program'] = [
-            'app_id'=>isset($wechat['routine_appId']) ? $wechat['routine_appId']:'',
-            'secret'=>isset($wechat['routine_appsecret']) ? $wechat['routine_appsecret']:'',
-            'token'=>isset($wechat['wechat_token']) ? $wechat['wechat_token']:'',
-            'aes_key'=> isset($wechat['wechat_encodingaeskey']) ? $wechat['wechat_encodingaeskey']:''
+            'app_id'=>isset($wechat['routine_appId']) ? trim($wechat['routine_appId']):'',
+            'secret'=>isset($wechat['routine_appsecret']) ? trim($wechat['routine_appsecret']):'',
+            'token'=>isset($wechat['wechat_token']) ? trim($wechat['wechat_token']):'',
+            'aes_key'=> isset($wechat['wechat_encodingaeskey']) ? trim($wechat['wechat_encodingaeskey']):''
+        ];
+        $config['payment'] = [
+            'app_id'=>isset($wechat['routine_appId']) ? trim($wechat['routine_appId']) :'',
+            'merchant_id'=>trim($payment['pay_routine_mchid']),
+            'key'=>trim($payment['pay_routine_key']),
+            'cert_path'=>realpath('.'.$payment['pay_routine_client_cert']),
+            'key_path'=>realpath('.'.$payment['pay_routine_client_key']),
+            'notify_url'=>$wechat['site_url'].Url::build('/ebapi/notify/notify',['notify_type'=>'routine'])
         ];
-        if(isset($payment['pay_weixin_open']) && $payment['pay_weixin_open'] == 1){
-            $config['payment'] = [
-                'app_id'=>isset($wechat['routine_appId']) ? $wechat['routine_appId']:'',
-                'merchant_id'=>$payment['pay_routine_mchid'],
-                'key'=>$payment['pay_routine_key'],
-                'cert_path'=>realpath('.'.$payment['pay_routine_client_cert']),
-                'key_path'=>realpath('.'.$payment['pay_routine_client_key']),
-                'notify_url'=>$wechat['site_url'].Url::build('/ebapi/notify/notify',['notify_type'=>'routine'])
-            ];
-        }
         return $config;
     }
     public static function application($cache = false)

+ 5 - 1
application/core/util/ProgramTemplateService.php

@@ -35,7 +35,11 @@ class ProgramTemplateService implements ProviderInterface
     //开团成功
     const OPEN_PINK_SUCCESS='AT0541';
     //确认收货通知
-    const OREDER_TAKEVER='AT0241';
+    const OREDER_TAKEVER = 'AT0241';
+    //提现成功通知
+    const USER_EXTRACT_TRUE = 'AT1330';
+    //提现失败通知
+    const USER_EXTRACT_FALSE = 'AT1242';
 
     public static function getConstants($code='')
     {

+ 1 - 1
application/ebapi/controller/ApiException.php

@@ -33,6 +33,6 @@ class ApiException extends Handle
         if($e instanceof ErrorException) return JsonService::fail($e->getMessage(),[],$e->getCode());
         //默认错误提示
         $baseExcep=new BaseException();
-        return JsonService::fail($baseExcep->msg,[],$baseExcep->code);
+        return JsonService::fail($baseExcep->msg,[$e->getMessage(),$e->getFile()],$baseExcep->code);
     }
 }

+ 2 - 2
application/ebapi/controller/AuthApi.php

@@ -139,11 +139,11 @@ class AuthApi extends AuthController
      * @param int $secKillId
      * @return \think\response\Json
      */
-    public function now_buy($productId = '', $cartNum = 1, $uniqueId = '', $combinationId = 0, $secKillId = 0, $bargainId = 0)
+    public function now_buy($productId = '', $cartNum = 1, $uniqueId = '', $combinationId = 0, $is_new = 0,$secKillId = 0, $bargainId = 0)
     {
         if (!$productId || !is_numeric($productId)) return JsonService::fail('参数错误');
         if ($bargainId && StoreBargainUserHelp::getSurplusPrice($bargainId, $this->userInfo['uid'])) return JsonService::fail('请先砍价');
-        $res = StoreCart::setCart($this->userInfo['uid'], $productId, $cartNum, $uniqueId, 'product', 1, $combinationId, $secKillId, $bargainId);
+        $res = StoreCart::setCart($this->userInfo['uid'], $productId, $cartNum, $uniqueId, 'product', $is_new, $combinationId, $secKillId, $bargainId);
         if (!$res) return JsonService::fail(StoreCart::getErrorInfo());
         else  return JsonService::successful('ok', ['cartId' => $res->id]);
     }

+ 288 - 0
application/ebapi/controller/BargainApi.php

@@ -0,0 +1,288 @@
+<?php
+namespace app\ebapi\controller;
+
+
+use app\admin\model\system\SystemAttachment;
+use app\core\model\routine\RoutineCode;
+use app\core\model\routine\RoutineTemplate;//待完善
+use app\core\util\SystemConfigService;
+use app\ebapi\model\store\StoreBargain;
+use app\ebapi\model\store\StoreBargainUser;
+use app\ebapi\model\store\StoreBargainUserHelp;
+use app\core\util\GroupDataService;
+use app\ebapi\model\store\StoreCart;
+use app\ebapi\model\store\StoreOrder;
+use service\JsonService;
+use service\UploadService;
+use service\UtilService;
+
+
+/**
+ * TODO 小程序砍价活动api接口
+ * Class BargainApi
+ * @package app\ebapi\controller
+ */
+class BargainApi extends AuthController
+{
+
+    /**
+     * TODO 获取砍价列表参数
+     */
+    public function get_bargain_config(){
+        $lovely = GroupDataService::getData('routine_lovely')?:[];//banner图
+        $info = isset($lovely[2]) ? $lovely[2] : [];
+        return JsonService::successful($info);
+    }
+
+    /**
+     * TODO 获取砍价列表
+     */
+    public function get_bargain_list()
+    {
+        $data = UtilService::postMore([['offset',0],['limit',20]]);
+        $bargainList = StoreBargain::getList($data['offset'],$data['limit']);
+        StoreBargainUser::editBargainUserStatus($this->uid);// TODO 判断过期砍价活动
+        return JsonService::successful($bargainList);
+    }
+
+    /**
+     * TODO 砍价详情和当前登录人信息
+     * @param int $bargainId  $bargainId 砍价产品
+     * @return \think\response\Json
+     */
+    public function get_bargain(){
+        list($bargainId) = UtilService::postMore([['bargainId',0]],null,true);
+        if(!$bargainId) return JsonService::fail('参数错误');
+        $bargain = StoreBargain::getBargainTerm($bargainId);
+        if(empty($bargain)) return JsonService::fail('砍价已结束');
+        $bargain['time'] = time();
+        $data['userInfo'] = $this->userInfo;
+        $data['bargain'] = $bargain;
+        $cartIds=StoreCart::where(['bargain_id'=>$bargainId,'is_del'=>0,'is_pay'=>1])->column('id');
+        foreach ($cartIds as &$cartId) $cartId="[".$cartId."]";
+        $data['bargainSumCount']=StoreOrder::where('cart_id','in',$cartIds)->where('bargain_id','neq',0)->where(['paid'=>1,'refund_status'=>0])->count();
+        return JsonService::successful($data);
+    }
+
+
+    /**
+     * TODO  开启砍价
+     * @param int $bargainId $bargainId 砍价产品编号
+     * @param int $bargainUserId  $bargainUserId 开启砍价的用户编号
+     */
+    public function set_bargain(){
+        list($bargainId) = UtilService::postMore([['bargainId',0]],null,true);
+        if(!$bargainId) return JsonService::fail('参数错误');
+        $count = StoreBargainUser::isBargainUser($bargainId,$this->uid);
+        if($count === false) return JsonService::fail('参数错误');
+        else if($count) return JsonService::successful('参与成功');
+        else $res = StoreBargainUser::setBargain($bargainId,$this->uid);
+        if(!$res) return JsonService::fail('参与失败');
+        else return JsonService::successful('参与成功');
+    }
+
+    /**
+     * TODO 帮好友砍价
+     * @param int $bargainId $bargainId  砍价产品
+     * @param int $bargainUserUid  $bargainUserUid 开启砍价用户编号
+     * @throws \think\Exception
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\ModelNotFoundException
+     * @throws \think\exception\DbException
+     */
+    public function set_bargain_help(){
+        list($bargainId,$bargainUserUid) = UtilService::postMore([['bargainId',0],['bargainUserUid',0]],null,true);
+        if(!$bargainId || !$bargainUserUid) return JsonService::fail('参数错误');
+        $res = StoreBargainUserHelp::setBargainUserHelp($bargainId,$bargainUserUid,$this->userInfo['uid']);
+        if($res) {
+            if(!StoreBargainUserHelp::getSurplusPrice($bargainId,$bargainUserUid)){
+                $bargainUserTableId = StoreBargainUser::getBargainUserTableId($bargainId,$bargainUserUid);// TODO 获取用户参与砍价表编号
+                $bargainInfo = StoreBargain::get($bargainId);//TODO 获取砍价产品信息
+                $bargainUserInfo = StoreBargainUser::get($bargainUserTableId);// TODO 获取用户参与砍价信息
+                RoutineTemplate::sendBargainSuccess($bargainInfo,$bargainUserInfo,$bargainUserUid);//TODO 砍价成功给开启砍价用户发送模板消息
+            }
+            return JsonService::successful('砍价成功');
+        }
+        else return JsonService::fail('砍价失败');
+    }
+
+    /**
+     * TODO 获取砍价帮
+     * @param int $bargainId $bargainId 砍价产品
+     * @param int $bargainUserUid $bargainUserUid 开启砍价用户编号
+     * @param int $offset
+     * @param int $limit
+     */
+    public function get_bargain_user(){
+        list($bargainId,$bargainUserUid,$offset,$limit) = UtilService::postMore([
+            ['bargainId',0],
+            ['bargainUserUid',0],
+            ['offset',0],
+            ['limit',20]
+        ],null,true);
+        if(!$bargainId) return JsonService::fail('参数错误');
+        $bargainUserTableId = StoreBargainUser::getBargainUserTableId($bargainId,$bargainUserUid); //TODO 砍价帮获取参与砍价表编号
+        $storeBargainUserHelp = StoreBargainUserHelp::getList($bargainUserTableId,$offset,$limit);
+        return JsonService::successful($storeBargainUserHelp);
+    }
+
+    /**
+     * TODO 添加砍价分享次数
+     */
+    public function add_share_bargain(){
+        list($bargainId) = UtilService::postMore([['bargainId',0]],null,true);
+        $data['lookCount'] = StoreBargain::getBargainLook();//TODO 观看人数
+        $data['shareCount'] = StoreBargain::getBargainShare();//TODO 分享人数
+        $data['userCount'] = StoreBargainUser::count();//TODO 参与人数
+        if(!$bargainId) return JsonService::successful($data);
+        StoreBargain::addBargainShare($bargainId);
+        $data['shareCount'] = StoreBargain::getBargainShare();//TODO 分享人数
+        return JsonService::successful($data);
+    }
+
+    /**
+     * TODO 添加砍价浏览次数
+     */
+    public function add_look_bargain(){
+        list($bargainId) = UtilService::postMore([['bargainId',0]],null,true);
+        $data['lookCount'] = StoreBargain::getBargainLook();//TODO 观看人数
+        $data['shareCount'] = StoreBargain::getBargainShare();//TODO 分享人数
+        $data['userCount'] = StoreBargainUser::count();//TODO 参与人数
+        if(!$bargainId) return JsonService::successful($data);
+        StoreBargain::addBargainLook($bargainId);
+        $data['lookCount'] = StoreBargain::getBargainLook();//TODO 观看人数
+        return JsonService::successful($data);
+    }
+
+    /**
+     * TODO 获取砍价帮总人数、剩余金额、进度条、已经砍掉的价格
+     * @param int $bargainId
+     * @param int $bargainUserUid
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\ModelNotFoundException
+     * @throws \think\exception\DbException
+     */
+    public function get_bargain_help_count(){
+        list($bargainId,$bargainUserUid) = UtilService::postMore([['bargainId',0],['bargainUserUid',0]],null,true);
+        if(!$bargainId || !$bargainUserUid) return JsonService::fail('参数错误');
+        $count = StoreBargainUserHelp::getBargainUserHelpPeopleCount($bargainId,$bargainUserUid);//TODO 获取砍价帮总人数
+        $price = StoreBargainUserHelp::getSurplusPrice($bargainId,$bargainUserUid);//TODO 获取砍价剩余金额
+        $bargainUserTableId = StoreBargainUser::getBargainUserTableId($bargainId,$bargainUserUid);//TODO 获取用户参与砍价表编号
+        $alreadyPrice = StoreBargainUser::getBargainUserPrice($bargainUserTableId);//TODO 用户已经砍掉的价格 好友砍价之后获取用户已经砍掉的价格
+        $pricePercent = StoreBargainUserHelp::getSurplusPricePercent($bargainId,$bargainUserUid);//TODO 获取砍价进度条
+        $data['count'] = $count;
+        $data['price'] = $price;
+        $data['alreadyPrice'] = $alreadyPrice;
+        $data['pricePercent'] = $pricePercent > 10 ? $pricePercent : 10;
+        return JsonService::successful($data);
+    }
+
+    /**
+     * TODO 获取帮忙砍价砍掉多少金额
+     * @param int $bargainId
+     * @param int $bargainUserUid
+     */
+    public function get_bargain_user_bargain_price(){
+        list($bargainId,$bargainUserUid) = UtilService::postMore([['bargainId',0],['bargainUserUid',0]],null,true);
+        if(!$bargainId || !$bargainUserUid) return JsonService::fail('参数错误');
+        $bargainUserTableId = StoreBargainUser::getBargainUserTableId($bargainId,$bargainUserUid);//TODO 获取用户参与砍价表编号
+        $price = StoreBargainUserHelp::getBargainUserBargainPrice($bargainId,$bargainUserTableId,$this->uid,'price');// TODO 获取用户砍掉的金额
+        if($price) return JsonService::successful('ok',$price);
+        else return JsonService::fail('获取失败');
+    }
+
+    /**
+     * TODO 获取砍价状态
+     * @throws \think\Exception
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\ModelNotFoundException
+     * @throws \think\exception\DbException
+     */
+    public function set_status(){
+        list($bargainId,$bargainUserUid) = UtilService::postMore([['bargainId',0],['bargainUserUid',0]],null,true);
+        if($bargainUserUid != $this->uid) $status = 1;
+        else $status = 0;
+        if(!$status && !StoreBargainUserHelp::getSurplusPrice($bargainId,$bargainUserUid)){//砍价成功
+           $statusSql = StoreBargainUser::getBargainUserStatus($bargainId,$bargainUserUid);
+           if($statusSql == 1) $status = 3;
+           else if($statusSql == 2) $status = 4;
+           else if($statusSql == 3) $status = 5;
+        }else if($status && !StoreBargainUserHelp::isBargainUserHelpCount($bargainId,$bargainUserUid,$this->userInfo['uid'])) $status = 2;
+        return JsonService::successful('ok',$status);
+    }
+
+    /**
+     * TODO 获取砍价产品  个人中心 我的砍价
+     * @throws \think\Exception
+     */
+    public function bargain_list($page = 0,$limit = 20){
+        StoreBargainUser::editBargainUserStatus($this->uid);// TODO 判断过期砍价活动
+        $list = StoreBargainUser::getBargainUserAll($this->uid,$page,$limit);
+        if(count($list)) return JsonService::successful($list);
+        else return JsonService::fail('暂无参与砍价');
+    }
+
+    /**
+     * TODO 取消砍价
+     */
+    public function cancel_bargain(){
+        list($bargainId) = UtilService::postMore([['bargainId',0]],null,true);
+        $status = StoreBargainUser::getBargainUserStatus($bargainId,$this->uid);
+        if($status != 1) return JsonService::fail('状态错误');
+        $id = StoreBargainUser::getBargainUserTableId($bargainId,$this->uid);
+        $res = StoreBargainUser::edit(['is_del'=>1],$id);
+        if($res) return JsonService::successful('取消成功');
+        else return JsonService::successful('取消失败');
+    }
+
+    /**
+     * TODO 生成海报
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\ModelNotFoundException
+     * @throws \think\exception\DbException
+     */
+    public function bargain_share_poster()
+    {
+        list($bargainId) = UtilService::postMore([['id',0]],null,true);
+        $storeBargainInfo = StoreBargain::getBargain($bargainId);
+        $price = StoreBargainUserHelp::getSurplusPrice($bargainId,$this->uid);//TODO 获取砍价剩余金额
+        $alreadyPrice = StoreBargainUser::getBargainUserPrice(StoreBargainUser::getBargainUserTableId($bargainId,$this->uid));
+        try{
+            $data['title'] = $storeBargainInfo['title'];
+            if(stripos($storeBargainInfo['image'], '/public/uploads/'))
+                $data['image'] = ROOT_PATH.substr($storeBargainInfo['image'],stripos($storeBargainInfo['image'], '/public/uploads/'),strlen($storeBargainInfo['image']));
+            else
+                $data['image'] = $storeBargainInfo['image'];
+            $data['price'] = bcsub($storeBargainInfo['price'],$alreadyPrice,2);
+            $data['label'] = '已砍至';
+            $data['msg'] = '还差'.$price.'元即可砍价成功';
+            $name = $bargainId.'_'.$this->userInfo['uid'].'_'.$this->userInfo['is_promoter'].'_bargain_share.jpg';
+            $imageInfo = SystemAttachment::getInfo($name,'name');
+            $siteUrl = SystemConfigService::get('site_url').DS;
+            if(!$imageInfo){
+                $valueData = 'id='.$bargainId.'&bargain='.$this->uid.'&pid='.$this->uid;
+//                if($this->userInfo['is_promoter'] || SystemConfigService::get('store_brokerage_statu')==2) $valueData.='&pid='.$this->uid;
+                $res = RoutineCode::getPageCode('pages/activity/goods_bargain_details/index',$valueData,280);
+                if(!$res) return JsonService::fail('二维码生成失败');
+                $imageInfo = UploadService::imageStream($name,$res,'routine/activity/bargain/code');
+                if(!is_array($imageInfo)) return JsonService::fail($imageInfo);
+                if($imageInfo['image_type'] == 1) $remoteImage = UtilService::remoteImage($siteUrl.$imageInfo['dir']);
+                else $remoteImage = UtilService::remoteImage($imageInfo['dir']);
+                if(!$remoteImage['status']) return JsonService::fail($remoteImage['msg']);
+                SystemAttachment::attachmentAdd($imageInfo['name'],$imageInfo['size'],$imageInfo['type'],$imageInfo['dir'],$imageInfo['thumb_path'],1,$imageInfo['image_type'],$imageInfo['time'],2);
+                $url = $imageInfo['dir'];
+            }else $url = $imageInfo['att_dir'];
+            if($imageInfo['image_type'] == 1)
+                $data['url'] = str_replace('//','/',ROOT_PATH.$url);
+            else
+                $data['url'] = $url;
+            $posterImage = UtilService::setShareMarketingPoster($data,'routine/activity/bargain/poster');
+            if(!is_array($posterImage)) return JsonService::fail('海报生成失败');
+            SystemAttachment::attachmentAdd($posterImage['name'],$posterImage['size'],$posterImage['type'],$posterImage['dir'],$posterImage['thumb_path'],1,$posterImage['image_type'],$posterImage['time'],2);
+            if($posterImage['image_type'] == 1) $posterImage['dir'] = $siteUrl.$posterImage['dir'];
+            return JsonService::successful('ok',$posterImage['dir']);
+        }catch (\Exception $e){
+            return JsonService::fail('生成海报失败',['line'=>$e->getLine(),'message'=>$e->getMessage()]);
+        }
+    }
+}

+ 10 - 4
application/ebapi/controller/Basic.php

@@ -18,13 +18,19 @@ class Basic extends Controller
     protected $Debug=true;
     //未使用路由前置执行的行为
     protected $ApimiddlewareGroups=[
-
+        //取消未支付订单
+        'order_unpaid_cancel'=>\app\core\behavior\OrderBehavior::class,
+        //清除昨日用户生成的附件
+        'empty_yester_day_attachment'=>\app\core\behavior\UserBehavior::class,
     ];
 
     protected function _initialize()
     {
         parent::_initialize(); // TODO: Change the autogenerated stub
         $this->Debug=Config::get('app_debug');
+        header("Access-Control-Allow-Origin:*");
+        header("Access-Control-Allow-Methods:POST,GET");
+        header("Access-Control-Allow-Headers:*");
         $this->runApimiddlewareGroups();
     }
 
@@ -65,8 +71,8 @@ class Basic extends Controller
         $hash=$this->request->routeInfo();
         if(!Config::get('url_route_on') || !isset($hash['rule'][1]))
         {
-            foreach ((array)$this->ApimiddlewareGroups as $behavior){
-                $result=Hook::exec($behavior);
+            foreach ((array)$this->ApimiddlewareGroups as $action=>$behavior){
+                $result=Hook::exec($behavior,is_string($action) ? $action : '');
                 if(!is_null($result)) return $this->fail($result);
             }
         }
@@ -155,7 +161,7 @@ class Basic extends Controller
         if(method_exists($className,'whiteList')){
             try{
                 //执行白名单方法获取白名单
-                $white=$className::whiteList();
+                $white = $className::whiteList();
                 if(!is_array($white)) return false;
                 foreach ($white as $actionWhite){
                     //比较白名单和当前访问方法

+ 204 - 0
application/ebapi/controller/PinkApi.php

@@ -0,0 +1,204 @@
+<?php
+namespace app\ebapi\controller;
+
+use app\admin\model\system\SystemAttachment;
+use app\core\model\routine\RoutineCode;
+use app\core\util\SystemConfigService;
+use app\ebapi\model\store\StoreCombination;
+use app\ebapi\model\store\StoreOrder;
+use app\ebapi\model\store\StorePink;
+use app\ebapi\model\store\StoreProductRelation;
+use app\ebapi\model\store\StoreProductReply;
+use app\ebapi\model\user\WechatUser;
+use app\core\util\GroupDataService;
+use service\JsonService;
+use service\UploadService;
+use service\UtilService;
+
+
+/**
+ * TODO 小程序拼团产品和拼团其他api接口
+ * Class PinkApi
+ * @package app\ebapi\controller
+ */
+class PinkApi extends AuthController
+{
+    /**
+     * TODO 获取拼团列表
+     */
+    public function get_combination_list(){
+        $data = UtilService::postMore([['offset',0],['limit',20]]);
+        $store_combination = StoreCombination::getAll($data['offset'],$data['limit']);
+        return JsonService::successful($store_combination);
+    }
+
+    /**
+     * TODO 获取拼团列表顶部图
+     */
+    public function get_combination_list_banner(){
+        return JsonService::successful();
+    }
+
+    /**
+     * TODO 获取拼团产品详情
+     * @throws \think\Exception
+     * @throws \think\exception\DbException
+     */
+    public function combination_detail(){
+        list($id) = UtilService::postMore([['id',0]],null,true);
+        if(!$id) return JsonService::fail('拼团不存在或已下架');
+        $combinationOne = StoreCombination::getCombinationOne($id);
+        if(!$combinationOne) return JsonService::fail('拼团不存在或已下架');
+        $combinationOne['images'] = json_decode($combinationOne['images'],true);
+        $combinationOne['userCollect'] = StoreProductRelation::isProductRelation($id,$this->userInfo['uid'],'collect','pink_product');
+        list($pink ,$pindAll)= StorePink::getPinkAll($id,true);//拼团列表
+        $data['pink'] = $pink;
+        $data['user'] = $this->userInfo;//用户信息
+        $data['pindAll'] = $pindAll;
+        $data['storeInfo'] = $combinationOne;
+        $data['pink_ok_list']=StorePink::getPinkOkList($this->uid);
+        $data['pink_ok_sum']=StorePink::getPinkOkSumTotalNum($id);
+        $data['reply'] = StoreProductReply::getRecProductReply($combinationOne['product_id']);
+        $data['replyCount'] = StoreProductReply::productValidWhere()->where('product_id',$combinationOne['product_id'])->count();
+        if($data['replyCount']){
+            $goodReply=StoreProductReply::productValidWhere()->where('product_id',$combinationOne['product_id'])->where('product_score',5)->count();
+            $data['replyChance']=bcdiv($goodReply,$data['replyCount'],2);
+            $data['replyChance']=bcmul($data['replyChance'],100,3);
+        }else $data['replyChance']=0;
+        return JsonService::successful($data);
+    }
+
+    /**
+     * 开团页面
+     * @param int $id
+     * @return mixed
+     */
+    public function get_pink($id = 0){
+        $is_ok = 0;//判断拼团是否完成
+        $userBool = 0;//判断当前用户是否在团内  0未在 1在
+        $pinkBool = 0;//判断当前用户是否在团内  0未在 1在
+        if(!$id) return JsonService::fail('参数错误');
+        $pink = StorePink::getPinkUserOne($id);
+        if(isset($pink['is_refund']) && $pink['is_refund']) {
+            if($pink['is_refund'] != $pink['id']){
+                $id = $pink['is_refund'];
+                return $this->get_pink($id);
+            }else{
+                return JsonService::fail('订单已退款');
+            }
+        }
+        if(!$pink) return JsonService::fail('参数错误');
+        list($pinkAll,$pinkT,$count,$idAll,$uidAll)=StorePink::getPinkMemberAndPinkK($pink);
+        if($pinkT['status'] == 2){
+            $pinkBool = 1;
+            $is_ok = 1;
+        }else{
+            if(!$count){//组团完成
+                $is_ok = 1;
+                $pinkBool=StorePink::PinkComplete($uidAll,$idAll,$this->userInfo['uid'],$pinkT);
+            }else{
+                $pinkBool=StorePink::PinkFail($pinkAll,$pinkT,$pinkBool);
+            }
+        }
+        if(!empty($pinkAll)){
+            foreach ($pinkAll as $v){
+                if($v['uid'] == $this->userInfo['uid']) $userBool = 1;
+            }
+        }
+        if($pinkT['uid'] == $this->userInfo['uid']) $userBool = 1;
+        $combinationOne = StoreCombination::getCombinationOne($pink['cid']);
+        if(!$combinationOne) return JsonService::fail('拼团不存在或已下架');
+        $data['userInfo'] = $this->userInfo;
+        $data['pinkBool'] = $pinkBool;
+        $data['is_ok'] = $is_ok;
+        $data['userBool'] = $userBool;
+        $data['store_combination'] =$combinationOne;
+        $data['pinkT'] = $pinkT;
+        $data['pinkAll'] = $pinkAll;
+        $data['count'] = $count;
+        $data['store_combination_host'] = StoreCombination::getCombinationHost();
+        $data['current_pink_order'] = StorePink::getCurrentPink($id,$this->uid);
+        return JsonService::successful($data);
+    }
+
+    /**
+     * 获取今天正在拼团的人的头像和名称
+     * @return \think\response\Json
+     */
+    public function get_pink_second_one()
+    {
+        return JsonService::successful(StorePink::getPinkSecondOne());
+    }
+
+    /*
+     * 取消开团
+     * @param int $pink_id 团长id
+     * */
+    public function remove_pink($pink_id=0,$cid=0,$formId='')
+    {
+        if(!$pink_id || !$cid) return JsonService::fail('缺少参数');
+        $res=StorePink::removePink($this->uid,$cid,$pink_id,$formId);
+        if($res)
+            return JsonService::successful('取消成功');
+        else{
+            $error=StorePink::getErrorInfo();
+            if(is_array($error))
+                return JsonService::status($error['status'],$error['msg']);
+            else
+                return JsonService::fail($error);
+        }
+    }
+
+    /**
+     * TODO 生成海报
+     */
+    public function pink_share_poster()
+    {
+        list($pinkId) = UtilService::postMore([['id',0]],null,true);
+        $pinkInfo = StorePink::getPinkUserOne($pinkId);
+        $storeCombinationInfo = StoreCombination::getCombinationOne($pinkInfo['cid']);
+        $data['title'] = $storeCombinationInfo['title'];
+        if(stripos($storeCombinationInfo['image'], '/public/uploads/'))
+            $data['image'] = ROOT_PATH.substr($storeCombinationInfo['image'],stripos($storeCombinationInfo['image'], '/public/uploads/'),strlen($storeCombinationInfo['image']));
+        else
+            $data['image'] = $storeCombinationInfo['image'];
+        $data['price'] = $pinkInfo['total_price'];
+        $data['label'] = $pinkInfo['people'].'人团';
+        if($pinkInfo['k_id']) $pinkAll = StorePink::getPinkMember($pinkInfo['k_id']);
+        else $pinkAll = StorePink::getPinkMember($pinkInfo['id']);
+        $count = count($pinkAll)+1;
+        $data['msg'] = '原价¥'.$storeCombinationInfo['product_price'].' 还差'.(int)bcsub((int)$pinkInfo['people'],$count,0).'人拼团成功';
+        try{
+            $name = $pinkId.'_'.$this->userInfo['uid'].'_'.$this->userInfo['is_promoter'].'_pink_share.jpg';
+            $imageInfo = SystemAttachment::getInfo($name,'name');
+            $siteUrl = SystemConfigService::get('site_url').DS;
+            if(!$imageInfo){
+                $valueData = 'id='.$pinkId.'&pid='.$this->uid;
+//                if($this->userInfo['is_promoter'] || SystemConfigService::get('store_brokerage_statu')==2) $valueData.='&pid='.$this->uid;
+                $res = RoutineCode::getPageCode('pages/activity/goods_combination_status/index',$valueData,280);
+                if(!$res) return JsonService::fail('二维码生成失败');
+                $imageInfo = UploadService::imageStream($name,$res,'routine/activity/pink/code');
+                if(!is_array($imageInfo)) return JsonService::fail($imageInfo);
+                if($imageInfo['image_type'] == 1) $remoteImage = UtilService::remoteImage($siteUrl.$imageInfo['dir']);
+                else $remoteImage = UtilService::remoteImage($imageInfo['dir']);
+                if(!$remoteImage['status']) return JsonService::fail($remoteImage['msg']);
+                SystemAttachment::attachmentAdd($imageInfo['name'],$imageInfo['size'],$imageInfo['type'],$imageInfo['dir'],$imageInfo['thumb_path'],1,$imageInfo['image_type'],$imageInfo['time'],2);
+                $url = $imageInfo['dir'];
+            }else $url = $imageInfo['att_dir'];
+            if($imageInfo['image_type'] == 1)
+                $data['url'] = str_replace('//','/',ROOT_PATH.$url);
+            else
+                $data['url'] = $url;
+            $posterImage = UtilService::setShareMarketingPoster($data,'routine/activity/pink/poster');
+            if(!is_array($posterImage)) return JsonService::fail('海报生成失败');
+            SystemAttachment::attachmentAdd($posterImage['name'],$posterImage['size'],$posterImage['type'],$posterImage['dir'],$posterImage['thumb_path'],1,$posterImage['image_type'],$posterImage['time'],2);
+            if($posterImage['image_type'] == 1) $posterImage['dir'] = $siteUrl.$posterImage['dir'];
+            return JsonService::successful('ok',$posterImage['dir']);
+        }catch (\Exception $e){
+            return JsonService::fail('系统错误:生成图片失败',['line'=>$e->getLine(),'message'=>$e->getMessage()]);
+        }
+
+    }
+
+
+}

+ 28 - 21
application/ebapi/controller/PublicApi.php

@@ -17,6 +17,10 @@ use service\UploadService;
 use service\UtilService;
 use service\CacheService;
 use think\Cache;
+use Api\Storage\COS\COS;
+use Api\Storage\OSS\OSS;
+use Api\Storage\Qiniu\Qiniu;
+use app\admin\model\system\SystemAttachment;
 
 /**
  * 小程序公共接口
@@ -55,6 +59,7 @@ class PublicApi extends AuthController
     public function get_logo_url()
     {
         $routine_logo=SystemConfigService::get('routine_logo');
+        if(strstr($routine_logo,'http')===false) $routine_logo=SystemConfigService::get('site_url').$routine_logo;
         return JsonService::successful(['logo_url'=>str_replace('\\','/',$routine_logo)]);
     }
     /**
@@ -94,7 +99,7 @@ class PublicApi extends AuthController
         $info['salesInfo'] = SystemConfigService::get('sales_info');//TODO 促销单品简介
         $logoUrl = SystemConfigService::get('routine_index_logo');//TODO 促销单品简介
         if(strstr($logoUrl,'http')===false) $logoUrl=SystemConfigService::get('site_url').$logoUrl;
-        $logoUrl=str_replace('\\','/',$logoUrl);
+        $logoUrl = str_replace('\\','/',$logoUrl);
         $fastNumber = (int)SystemConfigService::get('fast_number');//TODO 快速选择分类个数
         $bastNumber = (int)SystemConfigService::get('bast_number');//TODO 精品推荐个数
         $firstNumber = (int)SystemConfigService::get('first_number');//TODO 首发新品个数
@@ -179,16 +184,20 @@ class PublicApi extends AuthController
             ['pic',''],
         ]);
         if($post['pic']=='') return $this->fail('缺少删除资源');
-        $type=['php','js','css','html','ttf','otf'];
-        $post['pic']=substr($post['pic'],1);
-        $ext=substr($post['pic'],-3);
-        if(in_array($ext,$type)) return $this->fail('非法操作');
-        if(strstr($post['pic'],'uploads')===false) return $this->fail('非法操作');
         try{
-            if(file_exists($post['pic'])) unlink($post['pic']);
-            if(strstr($post['pic'],'s_')!==false){
-                $pic=str_replace(['s_'],'',$post['pic']);
-                if(file_exists($pic)) unlink($pic);
+            $attinfo = SystemAttachment::get($post['pic']);
+            if($attinfo){
+                if($attinfo['image_type'] == 1){
+                    @unlink(ROOT_PATH.ltrim($attinfo['att_dir'],'.'));
+                    @unlink(ROOT_PATH.ltrim($attinfo['satt_dir'],'.'));
+                }else if($attinfo['image_type'] == 2){
+                    Qiniu::delete($attinfo['name']);
+                }else if($attinfo['image_type'] == 3){
+                    OSS::delete($attinfo['name']);
+                }else if($attinfo['image_type'] == 4){
+                    COS::delete($attinfo['name']);
+                }
+                SystemAttachment::where(['att_id'=>$post['pic']])->delete();
             }
             return $this->successful('删除成功');
         }catch (\Exception $e){
@@ -208,16 +217,14 @@ class PublicApi extends AuthController
         ],$this->request);
         if(Cache::has('start_uploads_'.$this->uid) && Cache::get('start_uploads_'.$this->uid) >= 100) return $this->fail('非法操作');
         $res = UploadService::image($data['filename'],$dir ? $dir: 'store/comment');
-        if($res->status == 200){
-           if(Cache::has('start_uploads_'.$this->uid))
-               $start_uploads=(int)Cache::get('start_uploads_'.$this->uid);
-           else
-               $start_uploads=0;
-            $start_uploads++;
-            Cache::set('start_uploads_'.$this->uid,$start_uploads,86400);
-            return $this->successful('图片上传成功!', ['name' => $res->fileInfo->getSaveName(), 'url' => UploadService::pathToUrl($res->dir)]);
-        }else
-            return $this->fail($res->error);
+        if(!is_array($res)) return $this->fail(isset($res['error']) ? $res['error'] : '上传失败',$res);
+        if(Cache::has('start_uploads_'.$this->uid))
+            $start_uploads=(int)Cache::get('start_uploads_'.$this->uid);
+        else
+            $start_uploads=0;
+        $start_uploads++;
+        Cache::set('start_uploads_'.$this->uid,$start_uploads,86400);
+        return $this->successful('图片上传成功!', ['name' => $res['name'], 'url' => UploadService::pathToUrl($res['dir'])]);
     }
 
     /**
@@ -236,7 +243,7 @@ class PublicApi extends AuthController
     public function get_user_extract_bank(){
         $extractBank = SystemConfigService::get('user_extract_bank')?:[];//提现银行
         $extractBank = str_replace("\r\n","\n",$extractBank);//防止不兼容
-        $data['extractBank'] = explode("\n",$extractBank);
+        $data['extractBank'] = explode("\n",is_array($extractBank)  ? ( isset($extractBank[0]) ? $extractBank[0]: $extractBank): $extractBank);
         $data['minPrice'] = SystemConfigService::get('user_extract_min_price');//提现最低金额
         return $this->successful($data);
     }

+ 4 - 2
application/ebapi/controller/SeckillApi.php

@@ -1,6 +1,7 @@
 <?php
 namespace app\ebapi\controller;
 
+use app\core\util\SystemConfigService;
 use app\ebapi\model\store\StoreProductRelation;
 use app\ebapi\model\store\StoreProductReply;
 use app\ebapi\model\store\StoreSeckill;
@@ -22,7 +23,6 @@ class SeckillApi extends AuthController
      * @return \think\response\Json
      */
     public function seckill_index(){
-        $lovely = GroupDataService::getData('routine_lovely')?:[];//banner图
         $seckillTime = GroupDataService::getData('routine_seckill_time')?:[];//秒杀时间段
         $seckillTimeIndex = 0;
         if(count($seckillTime)){
@@ -55,7 +55,9 @@ class SeckillApi extends AuthController
                 }
             }
         }
-        $data['lovely'] = isset($lovely[0]) ? $lovely[0] : '';
+        $data['lovely'] = SystemConfigService::get('seckill_header_banner');
+        if(strstr($data['lovely'],'http')===false) $data['lovely']=SystemConfigService::get('site_url').$data['lovely'];
+        $data['lovely'] = str_replace('\\','/',$data['lovely']);
         $data['seckillTime'] = $seckillTime;
         $data['seckillTimeIndex'] = $seckillTimeIndex;
         return JsonService::successful($data);

+ 27 - 12
application/ebapi/controller/StoreApi.php

@@ -2,6 +2,7 @@
 namespace app\ebapi\controller;
 
 
+use app\admin\model\system\SystemAttachment;
 use app\core\model\routine\RoutineCode;//待完善
 use app\ebapi\model\store\StoreCategory;
 use app\ebapi\model\store\StoreOrderCartInfo;
@@ -12,6 +13,7 @@ use app\ebapi\model\store\StoreProductReply;
 use app\core\util\GroupDataService;
 use service\JsonService;
 use app\core\util\SystemConfigService;
+use service\UploadService;
 use service\UtilService;
 use app\core\util\MiniProgramService;
 use think\Cache;
@@ -43,8 +45,12 @@ class StoreApi extends AuthController
      */
     public function goods_search()
     {
-        list($keyword) = UtilService::getMore([['keyword',0]],null,true);
-        return JsonService::successful(StoreProduct::getSearchStorePage($keyword,$this->uid));
+        list($keyword,$page,$limit) = UtilService::getMore([
+            ['keyword',0],
+            ['page',1],
+            ['limit',8],
+        ],null,true);
+        return JsonService::successful(StoreProduct::getSearchStorePage($keyword,(int)$page,(int)$limit,$this->uid));
     }
     /**
      * 分类页面
@@ -128,6 +134,10 @@ class StoreApi extends AuthController
      */
     public function details($id=0){
         if(!$id || !($storeInfo = StoreProduct::getValidProduct($id))) return JsonService::fail('商品不存在或已下架');
+        //替换windows服务器下正反斜杠问题导致图片无法显示
+        $storeInfo['description'] = preg_replace_callback('#<img.*?src="([^"]*)"[^>]*>#i',function ($imagsSrc){
+            return isset($imagsSrc[1]) && isset($imagsSrc[0]) ? str_replace($imagsSrc[1],str_replace('\\','/',$imagsSrc[1]),$imagsSrc[0]): '';
+        },$storeInfo['description']);
         $storeInfo['userCollect'] = StoreProductRelation::isProductRelation($id,$this->userInfo['uid'],'collect');
         list($productAttr,$productValue) = StoreProductAttr::getProductAttrDetail($id);
         setView($this->userInfo['uid'],$id,$storeInfo['cate_id'],'viwe');
@@ -348,19 +358,24 @@ class StoreApi extends AuthController
         if(!$id) return JsonService::fail('参数错误ID不存在');
         $count = StoreProduct::validWhere()->count();
         if(!$count) return JsonService::fail('参数错误');
-        $path = makePathToUrl('routine/product/',4);
-        if($path == '') return JsonService::fail('生成上传目录失败,请检查权限!');
-        $codePath = $path.$id.'_'.$this->userInfo['uid'].'_product.jpg';
-        $domain = SystemConfigService::get('site_url').'/';
-        if(!file_exists($codePath)){
-            if(!is_dir($path)) mkdir($path,0777,true);
+        $name = $id.'_'.$this->userInfo['uid'].'_'.$this->userInfo['is_promoter'].'_product.jpg';
+        $imageInfo = SystemAttachment::getInfo($name,'name');
+        $siteUrl = SystemConfigService::get('site_url').DS;
+        if(!$imageInfo){
             $data='id='.$id;
             if($this->userInfo['is_promoter'] || SystemConfigService::get('store_brokerage_statu')==2) $data.='&pid='.$this->uid;
             $res = RoutineCode::getPageCode('pages/goods_details/index',$data,280);
-            if($res) file_put_contents($codePath,$res);
-            else return JsonService::fail('二维码生成失败');
-        }
-        return JsonService::successful($domain.$codePath);
+            if(!$res) return JsonService::fail('二维码生成失败');
+            $imageInfo = UploadService::imageStream($name,$res,'routine/product');
+            if(!is_array($imageInfo)) return JsonService::fail($imageInfo);
+            if($imageInfo['image_type'] == 1) $remoteImage = UtilService::remoteImage($siteUrl.$imageInfo['dir']);
+            else $remoteImage = UtilService::remoteImage($imageInfo['dir']);
+            if(!$remoteImage['status']) return JsonService::fail('小程序二维码未能生成',$remoteImage['msg']);
+            SystemAttachment::attachmentAdd($imageInfo['name'],$imageInfo['size'],$imageInfo['type'],$imageInfo['dir'],$imageInfo['thumb_path'],1,$imageInfo['image_type'],$imageInfo['time'],2);
+            $urlCode = $imageInfo['dir'];
+        }else $urlCode = $imageInfo['att_dir'];
+        if($imageInfo['image_type'] == 1) $urlCode = $siteUrl.$urlCode;
+        return JsonService::successful($urlCode);
     }
 
     /**

+ 57 - 23
application/ebapi/controller/UserApi.php

@@ -2,6 +2,8 @@
 namespace app\ebapi\controller;
 
 use Api\Express;
+use app\admin\model\system\SystemAttachment;
+use app\core\model\routine\RoutineQrcode;
 use app\core\model\user\UserLevel;
 use app\core\model\user\UserSign;
 use app\core\model\routine\RoutineCode;//待完善
@@ -24,6 +26,7 @@ use service\CacheService;
 use app\core\util\GroupDataService;
 use service\JsonService;
 use app\core\util\SystemConfigService;
+use service\UploadService;
 use service\UtilService;
 use think\Request;
 use think\Cache;
@@ -56,6 +59,14 @@ class UserApi extends AuthController
     {
         return JsonService::successful(UserSign::getSignList($this->uid,$page,$limit));
     }
+    /*
+   * 获取图片储存位置
+   *
+   * */
+    public function picture_storage_location()
+    {
+        return JsonService::successful((int)SystemConfigService::get('upload_type'));
+    }
     /*
      * 获取当前登录的用户信息
      * */
@@ -113,13 +124,19 @@ class UserApi extends AuthController
         $this->userInfo['orderStatusSum'] = StoreOrder::getOrderStatusSum($this->uid);//累计消费
         $this->userInfo['extractTotalPrice'] = UserExtract::userExtractTotalPrice($this->uid);//累计提现
         if($this->userInfo['brokerage'] > $this->userInfo['extractTotalPrice']) {
-            $this->userInfo['brokerage']=bcsub($this->userInfo['brokerage'],$this->userInfo['extractTotalPrice'],2);//减去已提现金额
-            $extract_price=UserExtract::userExtractTotalPrice($this->uid,0);
-            $this->userInfo['brokerage']=$extract_price < $this->userInfo['brokerage'] ? bcsub($this->userInfo['brokerage'],$extract_price,2) : 0;//减去审核中的提现金额
+            $orderYuePrice = StoreOrder::getOrderStatusYueSum($this->uid);//余额累计消费
+            $systemAdd = UserBill::getSystemAdd($this->uid);//后台添加余额
+            $yueCount = bcadd($this->userInfo['recharge'],$systemAdd,2);// 后台添加余额 + 累计充值  = 非佣金的总金额
+            $orderYuePrice = $yueCount > $orderYuePrice ? 0 : bcsub($orderYuePrice,$yueCount,2);// 余额累计消费(使用佣金消费的金额)
+            $this->userInfo['brokerage'] = bcsub($this->userInfo['brokerage'],$this->userInfo['extractTotalPrice'],2);//减去已提现金额
+            $extract_price = UserExtract::userExtractTotalPrice($this->uid,0);
+            $this->userInfo['brokerage'] = $extract_price < $this->userInfo['brokerage'] ? bcsub($this->userInfo['brokerage'],$extract_price,2) : 0;//减去审核中的提现金额
+            $this->userInfo['brokerage'] = $this->userInfo['brokerage'] > $orderYuePrice ? bcsub($this->userInfo['brokerage'],$orderYuePrice,2) : 0;//减掉余额支付
         }else{
             $this->userInfo['brokerage']=0;
         }
-        $this->userInfo['extractPrice'] = (float)bcsub($this->userInfo['brokerage'],$this->userInfo['extractTotalPrice'],2) > 0 ? : 0;//可提现
+        $this->userInfo['extractPrice'] = (float)bcsub($this->userInfo['brokerage'],$this->userInfo['extractTotalPrice'],2) > 0 ?
+            bcsub($this->userInfo['brokerage'],$this->userInfo['extractTotalPrice'],2) : 0;//可提现
         $this->userInfo['statu'] = (int)SystemConfigService::get('store_brokerage_statu');
         $vipId=UserLevel::getUserLevel($this->uid);
         $this->userInfo['vip']=$vipId !==false ? true : false;
@@ -128,6 +145,7 @@ class UserApi extends AuthController
             $this->userInfo['vip_icon']=UserLevel::getUserLevelInfo($vipId,'icon');
             $this->userInfo['vip_name']=UserLevel::getUserLevelInfo($vipId,'name');
         }
+        if(!SystemConfigService::get('vip_open')) $this->userInfo['vip']=false;
         unset($this->userInfo['pwd']);
         return JsonService::successful($this->userInfo);
     }
@@ -288,7 +306,7 @@ class UserApi extends AuthController
         if(!$price || $price <=0) return JsonService::fail('参数错误');
         $storeMinRecharge = SystemConfigService::get('store_user_min_recharge');
         if($price < $storeMinRecharge) return JsonService::fail('充值金额不能低于'.$storeMinRecharge);
-        $rechargeOrder = UserRecharge::addRecharge($this->userInfo['uid'],$price);
+        $rechargeOrder = UserRecharge::addRecharge($this->userInfo['uid'],$price,'routine');
         if(!$rechargeOrder) return JsonService::fail('充值订单生成失败!');
         try{
             return JsonService::successful(UserRecharge::jsPay($rechargeOrder));
@@ -376,6 +394,7 @@ class UserApi extends AuthController
             ['name',''],
             ['bankname',''],
             ['cardnum',''],
+            ['weixin',''],
         ],$this->request);
         if(UserExtract::userExtract($this->userInfo,$data))
             return JsonService::successful('申请提现成功!');
@@ -737,33 +756,42 @@ class UserApi extends AuthController
      * 分销二维码海报生成
      */
     public function user_spread_banner_list(){
-        header('content-type:image/jpg');
         try{
             $routineSpreadBanner = GroupDataService::getData('routine_spread_banner');
             if(!count($routineSpreadBanner)) return JsonService::fail('暂无海报');
-            $pathCode = makePathToUrl('routine/spread/code',3);
-            if($pathCode == '') return JsonService::fail('生成上传目录失败,请检查权限!');
-            $picName = $pathCode.DS.$this->userInfo['uid'].'.jpg';
-            $picName = trim(str_replace(DS, '/',$picName,$loop));
-            $res = RoutineCode::getShareCode($this->uid, 'spread', '', $picName);
-            if($res) file_put_contents($picName,$res);
-            else return JsonService::fail('二维码生成失败');
+            $name = $this->userInfo['uid'].'_'.$this->userInfo['is_promoter'].'_user.jpg';
+            $imageInfo = SystemAttachment::getInfo($name,'name');
+            $siteUrl = SystemConfigService::get('site_url').DS;
+            //检测远程文件是否存在
+            if(isset($imageInfo['att_dir']) && strstr($imageInfo['att_dir'],'http')!==false && UtilService::CurlFileExist($imageInfo['att_dir']) === false){
+                $imageInfo=null;
+                SystemAttachment::where(['name'=>$name])->delete();
+            }
+            if(!$imageInfo){
+                $res = RoutineCode::getShareCode($this->uid, 'spread', '', '');
+                if(!$res) return JsonService::fail('二维码生成失败');
+                $imageInfo = UploadService::imageStream($name,$res['res'],'routine/spread/code');
+                if(!is_array($imageInfo)) return JsonService::fail($imageInfo);
+                SystemAttachment::attachmentAdd($imageInfo['name'],$imageInfo['size'],$imageInfo['type'],$imageInfo['dir'],$imageInfo['thumb_path'],1,$imageInfo['image_type'],$imageInfo['time'],2);
+                RoutineQrcode::setRoutineQrcodeFind($res['id'],['status'=>1,'time'=>time(),'qrcode_url'=>$imageInfo['dir']]);
+                $urlCode = $imageInfo['dir'];
+            }else $urlCode = $imageInfo['att_dir'];
+            if($imageInfo['image_type'] == 1) $urlCode = ROOT_PATH.$urlCode;
             $res = true;
-            $url = SystemConfigService::get('site_url').'/';
-            $domainTop = substr($url,0,5);
-            if($domainTop != 'https') $url = 'https:'.substr($url,5,strlen($url));
-            $pathCode = makePathToUrl('routine/spread/poster',3);
+            $domainTop = substr($siteUrl,0,5);
+            if($domainTop != 'https') $siteUrl = 'https:'.substr($siteUrl,5,strlen($siteUrl));
             $filelink=[
-                'Bold'=>'public/static/font/SourceHanSansCN-Bold.otf',
-                'Normal'=>'public/static/font/SourceHanSansCN-Normal.otf',
+                'Bold'=>'public/static/font/Alibaba-PuHuiTi-Regular.otf',
+                'Normal'=>'public/static/font/Alibaba-PuHuiTi-Regular.otf',
             ];
             if(!file_exists($filelink['Bold'])) return JsonService::fail('缺少字体文件Bold');
             if(!file_exists($filelink['Normal'])) return JsonService::fail('缺少字体文件Normal');
             foreach ($routineSpreadBanner as $key=>&$item){
+                $posterInfo = '海报生成失败:(';
                 $config = array(
                     'image'=>array(
                         array(
-                            'url'=>ROOT_PATH.$picName,     //二维码资源
+                            'url'=>strstr($urlCode,ROOT_PATH) === false && strpos($urlCode,'http') === false ? str_replace('//','/',ROOT_PATH.$urlCode) : $urlCode,     //二维码资源
                             'stream'=>0,
                             'left'=>114,
                             'top'=>790,
@@ -796,9 +824,15 @@ class UserApi extends AuthController
                     ),
                     'background'=>$item['pic']
                 );
-                $filename = ROOT_PATH.$pathCode.'/'.$item['id'].'_'.$this->uid.'.png';
-                $res = $res && UtilService::setSharePoster($config,$filename);
-                if($res) $item['poster'] = $url.$pathCode.'/'.$item['id'].'_'.$this->uid.'.png';
+                $res = $res && $posterInfo = UtilService::setSharePoster($config,'routine/spread/poster');
+                if(!is_array($posterInfo)) return JsonService::fail($posterInfo);
+                SystemAttachment::attachmentAdd($posterInfo['name'],$posterInfo['size'],$posterInfo['type'],$posterInfo['dir'],$posterInfo['thumb_path'],1,$posterInfo['image_type'],$posterInfo['time'],2);
+                if($res){
+                    if($posterInfo['image_type'] == 1) $item['poster'] = $siteUrl.$posterInfo['dir'];
+                    else $item['poster'] = $posterInfo['dir'];
+                    $item['poster'] = str_replace('\\','/',$item['poster']);
+                    if(strstr($item['poster'],'http')===false) $item['poster']=SystemConfigService::get('site_url').$item['poster'];
+                }
             }
             if($res) return JsonService::successful($routineSpreadBanner);
             else return JsonService::fail('生成图片失败');

+ 194 - 0
application/ebapi/model/store/StoreBargain.php

@@ -0,0 +1,194 @@
+<?php
+/**
+ *
+ * @author: xaboy<365615158@qq.com>
+ * @day: 2017/12/18
+ */
+
+namespace app\ebapi\model\store;
+
+use basic\ModelBasic;
+use traits\ModelTrait;
+
+class StoreBargain extends ModelBasic
+{
+    use ModelTrait;
+
+    /**
+     * 正在开启的砍价活动
+     * @return $this
+     */
+    public static function validWhere($status = 1){
+        return  self::where('is_del',0)->where('status',$status)->where('start_time','LT',time())->where('stop_time','GT',time());
+    }
+
+    /**
+     * 判断砍价产品是否开启
+     * @param int $bargainId
+     * @return int|string
+     */
+    public static function validBargain($bargainId = 0){
+        $model = self::validWhere();
+        return $bargainId ? $model->where('id',$bargainId)->count() : $model->count();
+    }
+
+    /**
+     * TODO 获取正在开启的砍价产品编号
+     * @return array
+     */
+    public static function validBargainNumber(){
+        return self::validWhere()->column('id');
+    }
+
+    /**
+     * TODO 获取正在进行中的砍价产品
+     * @param int $offset
+     * @param int $limit
+     * @param string $field
+     * @return array
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\ModelNotFoundException
+     * @throws \think\exception\DbException
+     */
+    public static function getList($offset = 0,$limit = 20,$field = 'id,product_id,title,price,min_price,image'){
+        $model = self::validWhere();
+        $list = $model->field($field)->limit($offset,$limit)->select()->each(function ($item){ $item['people'] = count(StoreBargainUser::getUserIdList($item['id']));});
+        if($list) return $list->toArray();
+        else return [];
+    }
+
+    /**
+     * TODO 获取一条正在进行中的砍价产品
+     * @param int $bargainId  $bargainId 砍价产品编号
+     * @param string $field
+     * @return array
+     * @throws \think\Exception
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\ModelNotFoundException
+     * @throws \think\exception\DbException
+     */
+    public static function getBargainTerm($bargainId = 0,$field = 'id,product_id,bargain_num,num,unit_name,image,title,price,min_price,image,description,start_time,stop_time,rule'){
+        if(!$bargainId) return [];
+        $model = self::validWhere();
+        $bargain = $model->field($field)->where('id',$bargainId)->find();
+        if($bargain) return $bargain->toArray();
+        else return [];
+    }
+
+    /**
+     * 获取一条砍价产品
+     * @param int $bargainId
+     * @param string $field
+     * @return array
+     */
+    public static function getBargain($bargainId = 0,$field = 'id,product_id,title,price,min_price,image'){
+        if(!$bargainId) return [];
+        $model = new self();
+        $bargain = $model->field($field)->where('id',$bargainId)->find();
+        if($bargain) return $bargain->toArray();
+        else return [];
+    }
+
+    /**
+     * 获取最高价和最低价
+     * @param int $bargainId
+     * @return array
+     */
+    public static function getBargainMaxMinPrice($bargainId = 0){
+        if(!$bargainId) return [];
+        return self::where('id',$bargainId)->field('bargain_min_price,bargain_max_price')->find()->toArray();
+    }
+
+    /**
+     * 获取砍价次数
+     * @param int $bargainId
+     * @return mixed
+     */
+    public static function getBargainNum($bargainId = 0){
+       return self::where('id',$bargainId)->value('bargain_num');
+    }
+
+    /**
+     * 判断当前砍价是否活动进行中
+     * @param int $bargainId
+     * @return bool
+     */
+    public static function setBargainStatus($bargainId = 0){
+        $model = self::validWhere();
+        $count = $model->where('id',$bargainId)->count();
+        if($count) return true;
+        else return false;
+    }
+
+    /**
+     * 获取库存
+     * @param int $bargainId
+     * @return mixed
+     */
+    public static function getBargainStock($bargainId = 0){
+        return self::where('id',$bargainId)->value('stock');
+    }
+    /**
+     * 修改销量和库存
+     * @param $num
+     * @param $CombinationId
+     * @return bool
+     */
+    public static function decBargainStock($num,$bargainId)
+    {
+        $res = false !== self::where('id',$bargainId)->dec('stock',$num)->inc('sales',$num)->update();
+        return $res;
+    }
+
+    /**
+     * 增加库存减销量
+     * @param $num
+     * @param $CombinationId
+     * @return bool
+     */
+    public static function IncBargainStock($num,$bargainId)
+    {
+        $bargain=self::where('id',$bargainId)->field(['stock','sales'])->find();
+        if(!$bargain) return true;
+        if($bargain->sales > 0) $bargain->sales=bcsub($bargain->sales,$num,0);
+        if($bargain->sales < 0) $bargain->sales=0;
+        $bargain->stock=bcadd($bargain->stock,$num,0);
+        return $bargain->save();
+    }
+
+    /**
+     * TODO 获取所有砍价产品的浏览量
+     * @return mixed
+     */
+    public static function getBargainLook(){
+        return self::sum('look');
+    }
+
+    /**
+     * TODO 获取所有砍价产品的分享量
+     * @return mixed
+     */
+    public static function getBargainShare(){
+        return self::sum('share');
+    }
+
+    /**
+     * TODO 添加砍价产品分享次数
+     * @param int $id
+     * @return StoreBargain|bool
+     */
+    public static function addBargainShare($id = 0){
+        if(!$id) return false;
+        return self::where('id',$id)->inc('share',1)->update();
+    }
+
+    /**
+     * TODO 添加砍价产品浏览次数
+     * @param int $id  $id 砍价产品编号
+     * @return StoreBargain|bool
+     */
+    public static function addBargainLook($id = 0){
+        if(!$id) return false;
+        return self::where('id',$id)->inc('look',1)->update();
+    }
+}

+ 14 - 4
application/ebapi/model/store/StoreCart.php

@@ -174,16 +174,26 @@ class StoreCart extends ModelBasic
                         $invalid[] = $cart;
                     else{
                         $cart['productInfo']['attrInfo'] = $attrInfo;
-                        $cart['truePrice'] = (float)StoreProduct::setLevelPrice($attrInfo['price'],$uid,true);
-                        $cart['vip_truePrice'] = (float)StoreProduct::setLevelPrice($attrInfo['price'],$uid);
+                        if($cart['combination_id'] || $cart['seckill_id'] || $cart['bargain_id']) {
+                            $cart['truePrice'] = $attrInfo['price'];
+                            $cart['vip_truePrice'] = 0;
+                        }else {
+                            $cart['truePrice'] = (float)StoreProduct::setLevelPrice($attrInfo['price'],$uid,true);
+                            $cart['vip_truePrice'] = (float)StoreProduct::setLevelPrice($attrInfo['price'], $uid);
+                        }
                         $cart['trueStock'] = $attrInfo['stock'];
                         $cart['costPrice'] = $attrInfo['cost'];
                         $cart['productInfo']['image'] = empty($attrInfo['image']) ? $cart['productInfo']['image'] : $attrInfo['image'];
                         $valid[] = $cart;
                     }
                 }else{
-                    $cart['truePrice'] = (float)StoreProduct::setLevelPrice($cart['productInfo']['price'],$uid,true);
-                    $cart['vip_truePrice'] = (float)StoreProduct::setLevelPrice($cart['productInfo']['price'],$uid);
+                    if($cart['combination_id'] || $cart['seckill_id'] || $cart['bargain_id']) {
+                        $cart['truePrice'] = $cart['productInfo']['price'];
+                        $cart['vip_truePrice'] = 0;
+                    }else {
+                        $cart['truePrice'] = (float)StoreProduct::setLevelPrice($cart['productInfo']['price'],$uid,true);
+                        $cart['vip_truePrice'] = (float)StoreProduct::setLevelPrice($cart['productInfo']['price'], $uid);
+                    }
                     $cart['trueStock'] = $cart['productInfo']['stock'];
                     $cart['costPrice'] = $cart['productInfo']['cost'];
                     $valid[] = $cart;

+ 1 - 0
application/ebapi/model/store/StoreCategory.php

@@ -59,6 +59,7 @@ class StoreCategory extends ModelBasic
      * @throws \think\exception\DbException
      */
     public static function byIndexList($limit = 4,$field = 'id,cate_name,pid,pic'){
+        if(!$limit) return [];
         return self::where('pid','>',0)->where('is_show',1)->field($field)->order('sort DESC')->limit($limit)->select();
     }
 

+ 187 - 0
application/ebapi/model/store/StoreCombination.php

@@ -0,0 +1,187 @@
+<?php
+/**
+ *
+ * @author: xaboy<365615158@qq.com>
+ * @day: 2017/11/11
+ */
+
+namespace app\ebapi\model\store;
+
+
+use traits\ModelTrait;
+use basic\ModelBasic;
+
+/**
+ * 拼团model
+ * Class StoreCombination
+ * @package app\ebapi\model\store
+ */
+class StoreCombination extends ModelBasic
+{
+    use ModelTrait;
+
+    /**
+     * @param $where
+     * @return array
+     */
+    public static function get_list($length=10){
+        if($post=input('post.')){
+            $where=$post['where'];
+            $model = new self();
+            $model = $model->alias('c');
+            $model = $model->join('StoreProduct s','s.id=c.product_id');
+            $model = $model->where('c.is_show',1)->where('c.is_del',0)->where('c.start_time','LT',time())->where('c.stop_time','GT',time());
+            if(!empty($where['search'])){
+                $model = $model->where('c.title','like',"%{$where['search']}%");
+                $model = $model->whereOr('s.keyword','like',"{$where['search']}%");
+            }
+            $model = $model->field('c.*,s.price as product_price');
+            if($where['key']){
+                if($where['sales']==1){
+                    $model = $model->order('c.sales desc');
+                }else if($where['sales']==2){
+                    $model = $model->order('c.sales asc');
+                }
+                if($where['price']==1){
+                    $model = $model->order('c.price desc');
+                }else if($where['price']==2){
+                    $model = $model->order('c.price asc');
+                }
+                if($where['people']==1){
+                    $model = $model->order('c.people asc');
+                }
+                if($where['default']==1){
+                    $model = $model->order('c.sort desc,c.id desc');
+                }
+            }else{
+                $model = $model->order('c.sort desc,c.id desc');
+            }
+            $page=is_string($where['page'])?(int)$where['page']+1:$where['page']+1;
+            $list = $model->page($page,$length)->select()->toArray();   
+            return ['list'=>$list,'page'=>$page];
+        }
+    }
+
+    /**
+     * 获取所有拼团数据
+     * @param int $limit
+     * @param int $length
+     * @return mixed
+     */
+    public static function getAll($limit = 0,$length = 0){
+        $model = new self();
+        $model = $model->alias('c');
+        $model = $model->join('StoreProduct s','s.id=c.product_id');
+        $model = $model->field('c.*,s.price as product_price');
+        $model = $model->order('c.sort desc,c.id desc');
+        $model = $model->where('c.is_show',1);
+        $model = $model->where('c.is_del',0);
+        $model = $model->where('c.start_time','LT',time());
+        $model = $model->where('c.stop_time','GT',time());
+        if($limit && $length) $model = $model->limit($limit,$length);
+        $list = $model->select();
+        if($list) return $list->toArray();
+        else return [];
+    }
+
+    /*
+     * 获取是否有拼团产品
+     * */
+    public static function getPinkIsOpen()
+    {
+        return self::alias('c')->join('StoreProduct s','s.id=c.product_id')->where('c.is_show',1)->where('c.is_del',0)
+            ->where('c.start_time','LT',time())->where('c.stop_time','GT',time())->count();
+    }
+
+    /**
+     * 获取一条拼团数据
+     * @param $id
+     * @return mixed
+     */
+    public static function getCombinationOne($id){
+        $model = new self();
+        $model = $model->alias('c');
+        $model = $model->join('StoreProduct s','s.id=c.product_id');
+        $model = $model->field('c.*,s.price as product_price');
+        $model = $model->where('c.is_show',1);
+        $model = $model->where('c.is_del',0);
+        $model = $model->where('c.id',$id);
+//        $model = $model->where('c.start_time','LT',time());
+//        $model = $model->where('c.stop_time','GT',time()-86400);
+        $list = $model->find();
+        if($list) return $list->toArray();
+        else return [];
+    }
+
+    /**
+     * 获取推荐的拼团产品
+     * @return mixed
+     */
+    public static function getCombinationHost($limit = 0){
+        $model = new self();
+        $model = $model->alias('c');
+        $model = $model->join('StoreProduct s','s.id=c.product_id');
+        $model = $model->field('c.id,c.image,c.price,c.sales,c.title,c.people,s.price as product_price');
+        $model = $model->where('c.is_del',0);
+        $model = $model->where('c.is_host',1);
+        $model = $model->where('c.start_time','LT',time());
+        $model = $model->where('c.stop_time','GT',time());
+        if($limit) $model = $model->limit($limit);
+        $list = $model->select();
+        if($list) return $list->toArray();
+        else return [];
+    }
+
+    /**
+     * 修改销量和库存
+     * @param $num
+     * @param $CombinationId
+     * @return bool
+     */
+    public static function decCombinationStock($num,$CombinationId)
+    {
+        $res = false !== self::where('id',$CombinationId)->dec('stock',$num)->inc('sales',$num)->update();
+        return $res;
+    }
+
+    /**
+     * 增加库存,减少销量
+     * @param $num
+     * @param $CombinationId
+     * @return bool
+     */
+    public static function incCombinationStock($num,$CombinationId)
+    {
+
+        $combination=self::where('id',$CombinationId)->field(['stock','sales'])->find();
+        if(!$combination) return true;
+        if($combination->sales > 0) $combination->sales=bcsub($combination->sales,$num,0);
+        if($combination->sales < 0) $combination->sales=0;
+        $combination->stock=bcadd($combination->stock,$num,0);
+        return $combination->save();
+    }
+
+    /**
+     * 判断库存是否足够
+     * @param $id
+     * @param $cart_num
+     * @return int|mixed
+     */
+    public static function getCombinationStock($id,$cart_num){
+        $stock = self::where('id',$id)->value('stock');
+        return $stock > $cart_num ? $stock : 0;
+    }
+    /**
+     * 获取产品状态
+     * @param $id
+     * @return mixed
+     */
+    public static function isValidCombination($id){
+        $model = new self();
+        $model = $model->where('id',$id);
+        $model = $model->where('is_del',0);
+        $model = $model->where('is_show',1);
+        return $model->count();
+    }
+
+}

+ 7 - 2
application/ebapi/model/store/StoreCouponIssue.php

@@ -26,8 +26,13 @@ class StoreCouponIssue extends ModelBasic
             if(!$v['is_use']){
                 $v['is_use']=$v['remain_count'] <= 0 && !$v['is_permanent'] ? 2 : $v['is_use'];
             }
-            $v['add_time']=date('Y/m/d',$v['add_time']);
-            $v['end_time']=$v['end_time'] ? date('Y/m/d',$v['end_time']) : date('Y/m/d',time()+86400);
+            if(!$v['end_time']){
+                $v['add_time']= '';
+                $v['end_time'] = '不限时';
+            }else{
+                $v['add_time']=date('Y/m/d',$v['add_time']);
+                $v['end_time']=$v['end_time'] ? date('Y/m/d',$v['end_time']) : date('Y/m/d',time()+86400);
+            }
             $v['coupon_price']=(int)$v['coupon_price'];
         }
         return $list;

+ 227 - 41
application/ebapi/model/store/StoreOrder.php

@@ -8,6 +8,7 @@
 namespace app\ebapi\model\store;
 
 use app\core\model\routine\RoutineTemplate;
+use app\core\util\ApiLogs;
 use app\ebapi\model\user\User;
 use app\ebapi\model\user\UserAddress;
 use app\core\model\user\UserBill;
@@ -21,6 +22,8 @@ use service\HookService;
 use app\core\util\MiniProgramService;
 use app\core\util\SystemConfigService;
 use think\Cache;
+use think\Exception;
+use think\exception\PDOException;
 use traits\ModelTrait;
 
 class StoreOrder extends ModelBasic
@@ -225,7 +228,7 @@ class StoreOrder extends ModelBasic
         foreach ($cartInfo as $cart){
             $cartIds[] = $cart['id'];
             $totalNum += $cart['cart_num'];
-            $gainIntegral = bcadd($gainIntegral,isset($cart['productInfo']['give_integral']) ? $cart['productInfo']['give_integral'] : 0,2);
+            $gainIntegral = bcadd($gainIntegral,isset($cart['productInfo']['give_integral']) ? bcmul($cart['productInfo']['give_integral'],$cart['cart_num'],2) : 0,2);
         }
         $orderInfo = [
             'uid'=>$uid,
@@ -258,6 +261,14 @@ class StoreOrder extends ModelBasic
         $order = self::set($orderInfo);
         if(!$order)return self::setErrorInfo('订单生成失败!');
         $res5 = true;
+        foreach ($cartInfo as $cart)
+        {
+            //减库存加销量
+            if($combinationId) $res5 = $res5 && StoreCombination::decCombinationStock($cart['cart_num'],$combinationId);
+            else if($seckill_id) $res5 = $res5 && StoreSeckill::decSeckillStock($cart['cart_num'],$seckill_id);
+            else if($bargain_id) $res5 = $res5 && StoreBargain::decBargainStock($cart['cart_num'],$bargain_id);
+            else $res5 = $res5 && StoreProduct::decProductStock($cart['cart_num'],$cart['productInfo']['id'],isset($cart['productInfo']['attrInfo']) ? $cart['productInfo']['attrInfo']['unique']:'');
+        }
         //保存购物车商品信息
         $res4 = false !== StoreOrderCartInfo::setCartInfo($order['id'],$cartInfo);
         //购物车状态修改
@@ -281,14 +292,13 @@ class StoreOrder extends ModelBasic
      * */
     public static function RegressionIntegral($order)
     {
-        if($order['paid'] || $order['status']==-2 || $order['is_del']) return false;
-        if($order['use_integral'] < 0) return true;
-        if((int)$order['status']!=-2 && (int)$order['refund_status']!=2 && $order['back_integral'] >= $order['use_integral'])
-            return self::setErrorInfo('已退积分或该状态无法回退积分');
+        if($order['paid'] || $order['status']==-2 || $order['is_del']) return true;
+        if($order['use_integral'] <= 0) return true;
+        if((int)$order['status']!=-2 && (int)$order['refund_status']!=2 && $order['back_integral'] >= $order['use_integral']) return true;
         $res=User::bcInc($order['uid'],'integral',$order['use_integral']);
         if(!$res) return self::setErrorInfo('回退积分增加失败');
         UserBill::income('积分回退',$order['uid'],'integral','deduction',$order['use_integral'],$order['unique'],User::where('uid',$order['uid'])->value('integral'),'购买商品失败,回退积分'.floatval($order['use_integral']));
-        return self::where('order_id',$order['order_id'])->update(['back_integral'=>$order['use_integral']]);
+        return false !== self::where('order_id',$order['order_id'])->update(['back_integral'=>$order['use_integral']]);
     }
 
     /*
@@ -298,11 +308,11 @@ class StoreOrder extends ModelBasic
      * */
     public static function RegressionStock($order)
     {
-        if($order['paid'] || $order['status']==-2 || $order['is_del']) return false;
-        $combinationId=$order['combination_id'];
-        $seckill_id=$order['seckill_id'];
-        $bargain_id=$order['bargain_id'];
-        $res5=true;
+        if($order['paid'] || $order['status'] == -2 || $order['is_del']) return true;
+        $combinationId = $order['combination_id'];
+        $seckill_id = $order['seckill_id'];
+        $bargain_id = $order['bargain_id'];
+        $res5 = true;
         $cartInfo=StoreOrderCartInfo::where('cart_id','in',$order['cart_id'])->select();
         foreach ($cartInfo as $cart)
         {
@@ -322,10 +332,10 @@ class StoreOrder extends ModelBasic
      * */
     public static function RegressionCoupon($order)
     {
-        if($order['paid'] || $order['status']==-2 || $order['is_del']) return false;
+        if($order['paid'] || $order['status']==-2 || $order['is_del']) return true;
         $res=true;
         if($order['coupon_id'] && StoreCouponUser::be(['id'=>$order['coupon_id'],'uid'=>$order['uid'],'status'=>1])){
-            $res= $res && StoreCouponUser::where(['id'=>$order['coupon_id'],'uid'=>$order['uid']])->update(['status'=>0,'use_time'=>0]);
+            $res= $res && false !== StoreCouponUser::where(['id'=>$order['coupon_id'],'uid'=>$order['uid']])->update(['status'=>0,'use_time'=>0]);
         }
         return $res;
     }
@@ -340,11 +350,12 @@ class StoreOrder extends ModelBasic
         if(!$order) return self::setErrorInfo('没有查到此订单');
         self::beginTrans();
         try{
-            $res=self::RegressionIntegral($order) && self::RegressionCoupon($order);
+            $res=self::RegressionIntegral($order) && self::RegressionStock($order) && self::RegressionCoupon($order);
             if($res){
                 $order->is_del=1;
+                $order->save();
                 self::commitTrans();
-                return $order->save();
+                return true;
             }
         }catch (\Exception $e){
             self::rollbackTrans();
@@ -472,21 +483,29 @@ class StoreOrder extends ModelBasic
         $order = self::where('order_id',$orderId)->find();
         $resPink = true;
         $res1 = self::where('order_id',$orderId)->update(['paid'=>1,'pay_type'=>$paytype,'pay_time'=>time()]);//订单改为支付
-        $cartInfo = self::getDb('StoreOrderCartInfo')->where('oid', $order['id'])->column('cart_info', 'unique') ?: [];
-        foreach ($cartInfo as $k => &$cart) $cart = json_decode($cart, true);
-        $res2 = true;
-        foreach ($cartInfo as $k => &$cart) {  //减库存加销量
-            if ($cart['combination_id']) $res2 = $res2 && StoreCombination::decCombinationStock($cart['cart_num'], $cart['combination_id']);
-            else if ($cart['seckill_id']) $res2 = $res2 && StoreSeckill::decSeckillStock($cart['cart_num'], $cart['seckill_id']);
-            else if ($cart['bargain_id']) $res2 = $res2 && StoreBargain::decBargainStock($cart['cart_num'], $cart['bargain_id']);
-            else $res2 = $res2 && StoreProduct::decProductStock($cart['cart_num'], $cart['productInfo']['id'], isset($cart['productInfo']['attrInfo']) ? $cart['productInfo']['attrInfo']['unique'] : '');
-        }
         User::bcInc($order['uid'],'pay_count',1,'uid');
         if($order->combination_id && $res1 && !$order->refund_status) $resPink = StorePink::createPink($order);//创建拼团
         $oid = self::where('order_id',$orderId)->value('id');
         StoreOrderStatus::status($oid,'pay_success','用户付款成功');
         RoutineTemplate::sendOrderSuccess($formId,$orderId);
-        HookService::afterListen('user_level',User::where('uid',$order['uid'])->find(),false,UserBehavior::class);
+        HookService::afterListen('user_level',User::where('uid',$order['uid'])->find(),null,false,UserBehavior::class);
+        //TODO 订单通知给管理员
+        try{
+            $pay_type = '微信支付';
+            if($order['pay_type']=='weixin'){
+                $pay_type = '微信支付';
+            }else if($order['pay_type']=='yue'){
+                $pay_type = '余额支付';
+            }
+            $nickname=User::where('uid',$order['uid'])->value('nickname');
+            \app\core\util\WechatTemplateService::sendAdminNoticeTemplate([
+                'first'=>"亲,您有一个新订单 \n订单号:{$order['order_id']} \n支付金额:{$order['pay_price']} \n支付方式:{$pay_type} \n微信昵称:{$nickname}",
+                'keyword1'=>'新订单',
+                'keyword2'=>'已支付',
+                'keyword3'=>date('Y/m/d H:i',time()),
+                'remark'=>'用户备注:'.$order['mark'],
+            ]);
+        }catch(\Exception $e){}
         $res = $res1 && $resPink;
         return false !== $res;
     }
@@ -554,18 +573,42 @@ class StoreOrder extends ModelBasic
             RoutineTemplate::sendOut('ORDER_POSTAGE_SUCCESS',$order['uid'],$group,$url);
         }
     }
-
+    /** 收货后发送模版消息
+     * @param $order
+     */
     public static function orderTakeAfter($order)
     {
-//        $openid = WechatUser::getOpenId($order['uid']);
-//        RoutineTemplateService::sendTemplate($openid,RoutineTemplateService::ORDER_TAKE_SUCCESS,[
-//            'first'=>'亲,您的订单已成功签收,快去评价一下吧',
-//            'keyword1'=>$order['order_id'],
-//            'keyword2'=>'已收货',
-//            'keyword3'=>date('Y/m/d H:i',time()),
-//            'keyword4'=>implode(',',StoreOrderCartInfo::getProductNameList($order['id'])),
-//            'remark'=>'点击查看订单详情'
-//        ],Url::build('My/order',['uni'=>$order['order_id']],true,true));
+        $title = '';
+        $cartInfo = self::getDb('StoreOrderCartInfo')->where('oid', $order['id'])->column('cart_info');
+        if(count($cartInfo)){
+            foreach ($cartInfo as $key=>&$cart){
+                $cart = json_decode($cart,true);
+                $title .= $cart['productInfo']['store_name'].',';
+            }
+        }
+        if(strlen(trim($title))) $title = substr($title,0,bcsub(strlen($title),1,0));
+        else{
+            $cartInfo = self::getDb('store_cart')->alias('a')->where('a.id','in',implode(',',json_decode($order['cart_id'],true)))->find();
+            $title = StoreProduct::getProductField($cartInfo['product_id'],'store_name');
+        }
+        if($order['is_channel']){//小程序
+            RoutineTemplate::sendOut('OREDER_TAKEVER',$order['uid'],[
+                'keyword1'=>$order['order_id'],
+                'keyword2'=>$title,
+                'keyword3'=>$order['pay_price'],
+                'keyword4'=>date('Y-m-d H:i:s',time()),
+            ]);
+        }else{
+            $openid = WechatUser::where('uid',$order['uid'])->value('openid');
+            \app\core\util\WechatTemplateService::sendTemplate($openid,\app\core\util\WechatTemplateService::ORDER_TAKE_SUCCESS,[
+                'first'=>'亲,您的订单已收货',
+                'keyword1'=>$order['order_id'],
+                'keyword2'=>'已收货',
+                'keyword3'=>date('Y-m-d H:i:s',time()),
+                'keyword4'=>$title,
+                'remark'=>'感谢您的光临!'
+            ]);
+        }
     }
 
     /**
@@ -609,6 +652,7 @@ class StoreOrder extends ModelBasic
             try{
                 HookService::listen('store_product_order_user_take_delivery',$order,$uid,false,GoodsBehavior::class);
             }catch (\Exception $e){
+                self::rollbackTrans();
                 return self::setErrorInfo($e->getMessage());
             }
             self::commitTrans();
@@ -644,7 +688,28 @@ class StoreOrder extends ModelBasic
         }else if(!$order['paid']){
             $status['_type'] = 0;
             $status['_title'] = '未支付';
-            $status['_msg'] = '立即支付订单吧';
+            //系统预设取消订单时间段
+            $keyValue=['order_cancel_time','order_activity_time','order_bargain_time','order_seckill_time','order_pink_time'];
+            //获取配置
+            $systemValue=SystemConfigService::more($keyValue);
+            //格式化数据
+            $systemValue=self::setValeTime($keyValue,is_array($systemValue) ? $systemValue:[]);
+            if($order['pink_id'] || $order['combination_id']){
+                $order_pink_time=$systemValue['order_pink_time']  ? $systemValue['order_pink_time'] : $systemValue['order_activity_time'];
+                $time=bcadd($order['add_time'],$order_pink_time*3600,0);
+                $status['_msg'] = '请在'.date('Y-m-d H:i:s',$time).'前完成支付!';
+            }else if($order['seckill_id']){
+                $order_seckill_time=$systemValue['order_seckill_time']  ? $systemValue['order_seckill_time'] : $systemValue['order_activity_time'];
+                $time=bcadd($order['add_time'],$order_seckill_time*3600,0);
+                $status['_msg'] = '请在'.date('Y-m-d H:i:s',$time).'前完成支付!';
+            }else if($order['bargain_id']){
+                $order_bargain_time=$systemValue['order_bargain_time']  ? $systemValue['order_bargain_time'] : $systemValue['order_activity_time'];
+                $time=bcadd($order['add_time'],$order_bargain_time*3600,0);
+                $status['_msg'] = '请在'.date('Y-m-d H:i:s',$time).'前完成支付!';
+            }else{
+                $time=bcadd($order['add_time'],$systemValue['order_cancel_time']*3600,0);
+                $status['_msg'] = '请在'.date('Y-m-d H:i:s',$time).'前完成支付!';
+            }
             $status['_class'] = 'nobuy';
         }else if($order['refund_status'] == 1){
             $status['_type'] = -1;
@@ -676,10 +741,22 @@ class StoreOrder extends ModelBasic
                 $status['_class'] = 'state-nfh';
             }
         }else if($order['status'] == 1){
-            $status['_type'] = 2;
-            $status['_title'] = '待收货';
-            $status['_msg'] = date('m月d日H时i分',StoreOrderStatus::getTime($order['id'],'delivery_goods')).'服务商已发货';
-            $status['_class'] = 'state-ysh';
+           if($order['delivery_type'] == 'send'){//TODO 送货
+               $status['_type'] = 2;
+               $status['_title'] = '待收货';
+               $status['_msg'] = date('m月d日H时i分',StoreOrderStatus::getTime($order['id'],'delivery')).'服务商已送货';
+               $status['_class'] = 'state-ysh';
+           }else if($order['delivery_type'] == 'express'){//TODO  发货
+               $status['_type'] = 2;
+               $status['_title'] = '待收货';
+               $status['_msg'] = date('m月d日H时i分',StoreOrderStatus::getTime($order['id'],'delivery_goods')).'服务商已发货';
+               $status['_class'] = 'state-ysh';
+           }else if($order['delivery_type'] == 'fictitious'){
+               $status['_type'] = 2;
+               $status['_title'] = '虚拟发货';
+               $status['_msg'] = date('m月d日H时i分',StoreOrderStatus::getTime($order['id'],'delivery_fictitious')).'服务商已发货';
+               $status['_class'] = 'state-ysh';
+           }
         }else if($order['status'] == 2){
             $status['_type'] = 3;
             $status['_title'] = '待评价';
@@ -744,7 +821,7 @@ class StoreOrder extends ModelBasic
     public static function getUserOrderList($uid,$status = '',$page = 0,$limit = 8)
     {
         $list = self::statusByWhere($status,$uid)->where('is_del',0)->where('uid',$uid)
-            ->field('add_time,seckill_id,bargain_id,combination_id,id,order_id,pay_price,total_num,total_price,pay_postage,total_postage,paid,status,refund_status,pay_type,coupon_price,deduction_price,pink_id,delivery_type')
+            ->field('add_time,seckill_id,bargain_id,combination_id,id,order_id,pay_price,total_num,total_price,pay_postage,total_postage,paid,status,refund_status,pay_type,coupon_price,deduction_price,pink_id,delivery_type,is_del')
             ->order('add_time DESC')->page((int)$page,(int)$limit)->select()->toArray();
         foreach ($list as $k=>$order){
             $list[$k] = self::tidyOrder($order,true);
@@ -938,7 +1015,116 @@ class StoreOrder extends ModelBasic
         return self::where(['uid'=>$uid,'is_del'=>0,'paid'=>1])->sum('pay_price');
     }
 
+
+    /**
+     * 获取余额支付的金额
+     * @param $uid
+     * @return float|int
+     */
+    public static function getOrderStatusYueSum($uid)
+    {
+        return self::where(['uid'=>$uid,'is_del'=>0,'pay_type'=>'yue','paid'=>1])->sum('pay_price');
+    }
     public static function getPinkOrderId($id){
         return self::where('id',$id)->value('order_id');
     }
+
+    /*
+     * 未支付订单自动取消
+     * @param int $limit 分页截取条数
+     * @param $prefid 缓存名称
+     * @param $expire 缓存时间
+     * */
+    public static function orderUnpaidCancel($limit=10,$prefid=ApiLogs::ORDER_UNPAID_PAGE,$expire=3600)
+    {
+        //系统预设取消订单时间段
+        $keyValue=['order_cancel_time','order_activity_time','order_bargain_time','order_seckill_time','order_pink_time'];
+        //未支付查询条件
+        $UnPaidwhere=['paid'=>0,'is_del'=>0,'status'=>0,'refund_status'=>0];
+        //获取配置
+        $systemValue=SystemConfigService::more($keyValue);
+        //格式化数据
+        $systemValue=self::setValeTime($keyValue,is_array($systemValue) ? $systemValue:[]);
+        //检查是否有未支付的订单
+        $unPidCount=self::where($UnPaidwhere)->count();
+        if(!$unPidCount) return null;
+        //总分页条数
+        $pagesSum=ceil(bcdiv($unPidCount,$limit,2));
+        if(Cache::has($prefid)){
+            $pages=Cache::get($prefid);
+            $pages++;
+            Cache::set($prefid,$pages,$expire);
+        }else{
+            $pages=1;
+            Cache::set($prefid,$pages,$expire);
+        }
+        if($pages > $pagesSum) Cache::set($prefid,0,$expire);
+        self::beginTrans();
+        try{
+            $res=true;
+            $orderList = self::where($UnPaidwhere)->field(['add_time','pink_id','order_id','seckill_id','bargain_id','combination_id','status','cart_id','use_integral',
+                'refund_status','uid','unique','back_integral','coupon_id','paid','is_del'])->page($pages,$limit)->select();
+            foreach ($orderList as $order){
+                if($order['seckill_id']){
+                    //优先使用单独配置的过期时间
+                    $order_seckill_time=$systemValue['order_seckill_time']  ? $systemValue['order_seckill_time'] : $systemValue['order_activity_time'];
+                    $res=$res && self::RegressionAll($order_seckill_time,$order);
+                }else if($order['bargain_id']){
+                    $order_bargain_time=$systemValue['order_bargain_time'] ? $systemValue['order_bargain_time'] : $systemValue['order_activity_time'];
+                    $res=$res && self::RegressionAll($order_bargain_time,$order);
+                }else if($order['pink_id'] || $order['combination_id']){
+                    $order_pink_time=$systemValue['order_pink_time'] ? $systemValue['order_pink_time'] : $systemValue['order_activity_time'];
+                    $res=$res && self::RegressionAll($order_pink_time,$order);
+                }else{
+                    $res=$res && self::RegressionAll($systemValue['order_cancel_time'],$order);
+                }
+            }
+            if($res) self::commitTrans();
+        }catch (PDOException $e){
+            self::rollbackTrans();
+            ApiLogs::writeLog(['file'=>$e->getFile(),'line'=>$e->getLine(),'message'=>$e->getMessage()],'s');
+        }catch (\think\Exception $e){
+            self::rollbackTrans();
+            ApiLogs::recodeErrorLog($e);
+        }
+
+    }
+
+    /*
+     * 未支付订单超过预设时间回退所有,如果不设置未支付过期时间,将不取消订单
+     * @param int $time 预设时间
+     * @param array $order 订单详情
+     * @return boolean
+     * */
+    protected static function RegressionAll($time,$order)
+    {
+        if($time==0) return true;
+        if(($order['add_time']+bcmul($time,3600,0)) < time()){
+            $res1=self::RegressionStock($order);
+            $res2=self::RegressionIntegral($order);
+            $res3=self::RegressionCoupon($order);
+            $res = $res1 && $res2 && $res3;
+            if($res) $res = false !== self::where(['order_id'=>$order['order_id']])->update(['is_del'=>1,'mark'=>'订单未支付已超过系统预设时间']);
+            return $res;
+        }else
+            return true;
+    }
+
+    /*
+     * 格式化数据
+     * @param $array 原本数据键
+     * @param $array 需要格式化的数据
+     * @param int $default 默认值
+     * @return array
+     * */
+    protected static function setValeTime(array $array,$value,$default=0)
+    {
+        foreach ($array as $item) {
+            if(!isset($value[$item]))
+                $value[$item]=$default;
+            else if(is_string($value[$item]))
+                $value[$item]=(float)$value[$item];
+        }
+        return $value;
+    }
 }

+ 2 - 2
application/ebapi/model/store/StorePink.php

@@ -356,7 +356,7 @@ class StorePink extends ModelBasic
                 'keyword1'=>StoreCombination::where('id',$pink['cid'])->value('title'),
                 'keyword2'=>User::where('uid',self::where('id',$pink['k_id'])->value('uid'))->value('nickname'),
                 'keyword3'=>date('Y-m-d H:i:s',$pink['add_time']),
-                'keyword3'=>$pink['total_price'],
+                'keyword4'=>$pink['total_price'],
             ],'','/pages/order_details/index?order_id='.$pink['order_id']);
             //处理拼团完成
             list($pinkAll,$pinkT,$count,$idAll,$uidAll)=self::getPinkMemberAndPinkK($pink);
@@ -394,7 +394,7 @@ class StorePink extends ModelBasic
                 'keyword2'=>date('Y-m-d H:i:s',$pink['stop_time']),
                 'keyword3'=>StoreCombination::where('id',$pink['cid'])->value('title'),
                 'keyword4'=>$pink['order_id'],
-                'keyword4'=>$pink['total_price'],
+                'keyword5'=>$pink['total_price'],
             ],'','/pages/order_details/index?order_id='.$pink['order_id']);
             if($res) return true;
             else return false;

+ 61 - 11
application/ebapi/model/store/StoreProduct.php

@@ -20,7 +20,16 @@ class StoreProduct extends ModelBasic
 
     protected function getSliderImageAttr($value)
     {
-        return json_decode($value,true)?:[];
+         $sliderImage=json_decode($value,true)?:[];
+         foreach ($sliderImage as &$item){
+             $item=str_replace('\\','/',$item);
+         }
+         return $sliderImage;
+    }
+
+    protected function getImageAttr($value)
+    {
+        return str_replace('\\','/',$value);
     }
 
     public static function getValidProduct($productId,$field = 'add_time,browse,cate_id,code_path,cost,description,ficti,give_integral,id,image,is_bargain,is_benefit,is_best,is_del,is_hot,is_new,is_postage,is_seckill,is_show,keyword,mer_id,mer_use,ot_price,postage,price,sales,slider_image,sort,stock,store_info,store_name,unit_name,vip_price,IFNULL(sales,0) + IFNULL(ficti,0) as fsales')
@@ -79,11 +88,30 @@ class StoreProduct extends ModelBasic
      * @param string $value
      * @return array
      * */
-    public static function getSearchStorePage($keyword,$uid)
+    public static function getSearchStorePage($keyword,$page,$limit,$uid,$cutApart=[' ',',','-'])
     {
         $model = self::validWhere();
-        if(strlen(trim($keyword))) $model = $model->where('store_name|keyword','LIKE',"%$keyword%");
-        $list = $model->field('id,store_name,cate_id,image,IFNULL(sales,0) + IFNULL(ficti,0) as sales,price,stock')->select();
+        $keyword = trim($keyword);
+        if(strlen($keyword)) {
+            $cut = false;
+            foreach ($cutApart as $val){
+                if(strstr($keyword,$val) !== false){
+                    $cut = $val;
+                    break;
+                }
+            }
+            if($cut !== false){
+                $keywordArray = explode($cut,$keyword);
+                $sql = [];
+                foreach ($keywordArray as $item){
+                    $sql[] = '(`store_name` LIKE "%'.$item.'%"  OR `keyword` LIKE "%'.$item.'%")';
+                }
+                $model = $model->where(implode(' OR ',$sql));
+            }else{
+                $model = $model->where('store_name|keyword','LIKE',"%$keyword%");
+            }
+        }
+        $list = $model->field('id,store_name,cate_id,image,ficti as sales,price,stock')->page($page,$limit)->select();
         return self::setLevelPrice($list,$uid);
     }
     /**
@@ -97,7 +125,10 @@ class StoreProduct extends ModelBasic
         $model = self::where('is_new',1)->where('is_del',0)->where('mer_id',0)
             ->where('stock','>',0)->where('is_show',1)->field($field)
             ->order('sort DESC, id DESC');
-        if($limit) $model->limit($limit);
+        if($limit)
+            $model->limit($limit);
+        else
+            return [];
         $list=$model->select();
         $list=count($list) ? $list->toArray() : [];
         return self::setLevelPrice($list,$uid);
@@ -141,10 +172,14 @@ class StoreProduct extends ModelBasic
      */
     public static function getBestProduct($field = '*',$limit = 0,$uid=0)
     {
+
         $model = self::where('is_best',1)->where('is_del',0)->where('mer_id',0)
             ->where('stock','>',0)->where('is_show',1)->field($field)
             ->order('sort DESC, id DESC');
-        if($limit) $model->limit($limit);
+        if($limit)
+            $model->limit($limit);
+        else
+            return [];
         return self::setLevelPrice($model->select(),$uid);
     }
 
@@ -157,6 +192,10 @@ class StoreProduct extends ModelBasic
     public static function setLevelPrice($list,$uid,$isSingle=false)
     {
         if(is_object($list)) $list=count($list) ? $list->toArray() : [];
+        if(!SystemConfigService::get('vip_open')){
+            if(is_array($list)) return $list;
+            return $isSingle ? $list : 0;
+        }
         $levelId=UserLevel::getUserLevel($uid);
         if($levelId){
             $discount=UserLevel::getUserLevelInfo($levelId,'discount');
@@ -246,11 +285,18 @@ class StoreProduct extends ModelBasic
      * */
     public static function incProductStock($num,$productId,$unique = '')
     {
+        $product=self::where('id',$productId)->field(['sales','stock'])->find();
+        if(!$product) return true;
+        if($product->sales > 0) $product->sales=bcsub($product->sales,$num,0);
+        if($product->sales < 0) $product->sales=0;
         if($unique){
             $res = false !== StoreProductAttrValuemodel::incProductAttrStock($productId,$unique,$num);
-            $res = $res && self::where('id',$productId)->setDec('sales',$num);
+            //没有修改销量则直接返回
+            if($product->sales==0) return true;
+            $res = $res && $product->save();
         }else{
-            $res = false !== self::where('id',$productId)->inc('stock',$num)->dec('sales',$num)->update();
+            $product->stock=bcadd($product->stock,$num,0);
+            $res = false !== $product->save();
         }
         return $res;
     }
@@ -268,7 +314,7 @@ class StoreProduct extends ModelBasic
                 if($value['cost'] > $value['price'])
                     $maxPrice=0;
                 else
-                    $maxPrice=bcmul($store_brokerage_ratio,bcsub($value['price'],$value['cost']),0);
+                    $maxPrice=bcmul($store_brokerage_ratio,bcsub($value['price'],$value['cost'],0),0);
                 unset($value);
             }else $maxPrice=0;
 
@@ -277,16 +323,20 @@ class StoreProduct extends ModelBasic
                 if($value['cost'] > $value['price'])
                     $minPrice=0;
                 else
-                    $minPrice=bcmul($store_brokerage_ratio,bcsub($value['price'],$value['cost']),0);
+                    $minPrice=bcmul($store_brokerage_ratio,bcsub($value['price'],$value['cost'],0),0);
                 unset($value);
             }else $minPrice=0;
             if($minPrice==0 && $maxPrice==0)
                 return 0;
+            else if($minPrice == 0 && $maxPrice)
+                return $maxPrice;
+            else if($maxPrice == 0 && $minPrice)
+                return $minPrice;
             else
                 return $minPrice.'~'.$maxPrice;
         }else{
             if($storeInfo['cost'] < $storeInfo['price'])
-                return bcmul($store_brokerage_ratio,bcsub($storeInfo['price'],$storeInfo['cost']),0);
+                return bcmul($store_brokerage_ratio,bcsub($storeInfo['price'],$storeInfo['cost'],2),2);
             else
                 return 0;
         }

+ 6 - 2
application/ebapi/model/store/StoreSeckill.php

@@ -141,7 +141,11 @@ class StoreSeckill extends ModelBasic
      * @return bool
      */
     public static function incSeckillStock($num = 0,$seckillId = 0){
-        $res = false !== self::where('id',$seckillId)->inc('stock',$num)->dec('sales',$num)->update();
-        return $res;
+        $seckill=self::where('id',$seckillId)->field(['stock','sales'])->find();
+        if(!$seckill) return true;
+        if($seckill->sales > 0) $seckill->sales=bcsub($seckill->sales,$num,0);
+        if($seckill->sales < 0) $seckill->sales=0;
+        $seckill->stock=bcadd($seckill->stock,$num,0);
+        return $seckill->save();
     }
 }

+ 102 - 30
application/ebapi/model/user/User.php

@@ -26,8 +26,8 @@ class User extends ModelBasic
 
     public static function updateWechatUser($wechatUser,$uid)
     {
-        $userinfo=self::where('uid',$uid)->find();
-        if($userinfo->spread_uid){
+        $userInfo = self::where('uid',$uid)->find();
+        if($userInfo->spread_uid){
             return self::edit([
                 'nickname'=>$wechatUser['nickname']?:'',
                 'avatar'=>$wechatUser['headimgurl']?:'',
@@ -36,16 +36,31 @@ class User extends ModelBasic
             $data=[
                 'nickname' => $wechatUser['nickname'] ?: '',
                 'avatar' => $wechatUser['headimgurl'] ?: '',
-                'is_promoter' =>$userinfo->is_promoter,
+                'is_promoter' =>$userInfo->is_promoter,
                 'spread_uid' => 0,
                 'spread_time' =>0,
                 'last_time' => time(),
                 'last_ip' => Request::instance()->ip(),
             ];
-            if(isset($wechatUser['code']) && !$userinfo->is_promoter && $wechatUser['code']){
-                $data['is_promoter']=1;
-                $data['spread_uid']=$wechatUser['code'];
-                $data['spread_time']=time();
+            //TODO 获取后台分销类型
+            $storeBrokerageStatus = SystemConfigService::get('store_brokerage_statu');
+            $storeBrokerageStatus = $storeBrokerageStatus ? $storeBrokerageStatus : 1;
+            if(isset($wechatUser['code']) && $wechatUser['code']){
+                if($storeBrokerageStatus == 1){
+                    $spreadCount = self::where('uid',$wechatUser['code'])->count();
+                    if($spreadCount){
+                        $spreadInfo = self::where('uid',$wechatUser['code'])->find();
+                        if($spreadInfo->is_promoter){
+                            //TODO 只有扫码才可以获得推广权限
+//                            if(isset($wechatUser['isPromoter'])) $data['is_promoter'] = $wechatUser['isPromoter'] ? 1 : 0;
+                        }
+                    }
+                }
+                $spreadInfo = self::where('uid',$wechatUser['code'])->find();
+                if($spreadInfo->spread_uid != $uid && $wechatUser['code'] != $uid){
+                    $data['spread_uid'] = $wechatUser['code'];
+                    $data['spread_time'] = time();
+                }
             }
             return self::edit($data, $uid, 'uid');
         }
@@ -71,7 +86,7 @@ class User extends ModelBasic
             'nickname'=>$routineUser['nickname']?:'',
             'avatar'=>$routineUser['headimgurl']?:'',
             'spread_uid'=>$spread_uid,
-            'is_promoter'=>$spread_uid || $storeBrokerageStatu != 1 ? 1: 0,
+//            'is_promoter'=>$spread_uid || $storeBrokerageStatu != 1 ? 1: 0,
             'spread_time'=>$spread_uid ? time() : 0,
             'uid'=>$routineUser['uid'],
             'add_time'=>$routineUser['add_time'],
@@ -131,63 +146,120 @@ class User extends ModelBasic
 
 
     /**
-     * 小程序用户一级分销
+     * TODO 一级返佣
      * @param $orderInfo
      * @return bool
+     * @throws \think\Exception
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\ModelNotFoundException
+     * @throws \think\exception\DbException
      */
     public static function backOrderBrokerage($orderInfo)
     {
+        //TODO 如果时营销产品不返佣金
+        if(isset($orderInfo['combination_id']) && $orderInfo['combination_id']) return true;
+        if(isset($orderInfo['seckill_id']) && $orderInfo['seckill_id']) return true;
+        if(isset($orderInfo['bargain_id']) && $orderInfo['bargain_id']) return true;
+        //TODO 支付金额减掉邮费
+        $orderInfo['pay_price'] = bcsub($orderInfo['pay_price'],$orderInfo['pay_postage'],2);
+        //TODO 获取购买商品的用户
         $userInfo = User::getUserInfo($orderInfo['uid']);
+        //TODO 当前用户不存在 或者 没有上级 直接返回
         if(!$userInfo || !$userInfo['spread_uid']) return true;
-        $storeBrokerageStatu = SystemConfigService::get('store_brokerage_statu') ? : 1;//获取后台分销类型
-        if($storeBrokerageStatu == 1){
-            if(!User::be(['uid'=>$userInfo['spread_uid'],'is_promoter'=>1])) return true;
+        //TODO 获取后台分销类型  1 指定分销 2 人人分销
+        $storeBrokerageStatus = SystemConfigService::get('store_brokerage_statu');
+        $storeBrokerageStatus = $storeBrokerageStatus ? $storeBrokerageStatus : 1;
+        //TODO 指定分销 判断 上级是否时推广员  如果不是推广员直接跳转二级返佣
+        if($storeBrokerageStatus == 1){
+            if(!User::be(['uid'=>$userInfo['spread_uid'],'is_promoter'=>1])) return self::backOrderBrokerageTwo($orderInfo);
         }
-        $brokerageRatio = (SystemConfigService::get('store_brokerage_ratio') ?: 0)/100;
-        if($brokerageRatio <= 0) return true;
-        $cost = isset($orderInfo['cost']) ? $orderInfo['cost'] : 0;//成本价
-        if($cost > $orderInfo['pay_price']) return true;//成本价大于支付价格时直接返回
-        //支付金额减去邮费
-        $orderInfo['pay_price'] = bcsub($orderInfo['pay_price'],$orderInfo['pay_postage'],2);
-        $brokeragePrice = bcmul(bcsub($orderInfo['pay_price'],$cost,2),$brokerageRatio,2);
+        //TODO 获取后台一级返佣比例
+        $storeBrokerageRatio = SystemConfigService::get('store_brokerage_ratio');
+        //TODO 一级返佣比例 小于等于零时直接返回 不返佣
+        if($storeBrokerageRatio <= 0) return true;
+        //TODO 计算获取一级返佣比例
+        $brokerageRatio = bcdiv($storeBrokerageRatio,100,2);
+        //TODO 成本价
+        $cost = isset($orderInfo['cost']) ? $orderInfo['cost'] : 0;
+        //TODO 成本价大于等于支付价格时直接返回
+        if($cost >= $orderInfo['pay_price']) return true;
+        //TODO 获取订单毛利
+        $payPrice = bcsub($orderInfo['pay_price'],$cost,2);
+        //TODO 返佣金额 = 毛利 / 一级返佣比例
+        $brokeragePrice = bcmul($payPrice,$brokerageRatio,2);
+        //TODO 返佣金额小于等于0 直接返回不返佣金
         if($brokeragePrice <= 0) return true;
+        //TODO 获取上级推广员信息
+        $spreadUserInfo = User::getUserInfo($userInfo['spread_uid']);
+        //TODO 上级推广员返佣之后的金额
+        $balance = bcadd($spreadUserInfo['now_money'],$brokeragePrice,2);
         $mark = $userInfo['nickname'].'成功消费'.floatval($orderInfo['pay_price']).'元,奖励推广佣金'.floatval($brokeragePrice);
         self::beginTrans();
-        $res1 = UserBill::income('获得推广佣金',$userInfo['spread_uid'],'now_money','brokerage',$brokeragePrice,$orderInfo['id'],0,$mark);
+        //TODO 添加推广记录
+        $res1 = UserBill::income('获得推广佣金',$userInfo['spread_uid'],'now_money','brokerage',$brokeragePrice,$orderInfo['id'],$balance,$mark);
+        //TODO 添加用户余额
         $res2 = self::bcInc($userInfo['spread_uid'],'now_money',$brokeragePrice,'uid');
         $res = $res1 && $res2;
         self::checkTrans($res);
-        if($res) self::backOrderBrokerageTwo($orderInfo);
+        //TODO 一级返佣成功 跳转二级返佣
+        if($res) return self::backOrderBrokerageTwo($orderInfo);
         return $res;
     }
 
     /**
-     * 小程序 二级推广
+     * TODO 二级推广
      * @param $orderInfo
      * @return bool
+     * @throws \think\Exception
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\ModelNotFoundException
+     * @throws \think\exception\DbException
      */
     public static function backOrderBrokerageTwo($orderInfo){
+        //TODO 获取购买商品的用户
         $userInfo = User::getUserInfo($orderInfo['uid']);
+        //TODO 获取上推广人
         $userInfoTwo = User::getUserInfo($userInfo['spread_uid']);
+        //TODO 上推广人不存在 或者 上推广人没有上级 直接返回
         if(!$userInfoTwo || !$userInfoTwo['spread_uid']) return true;
-        $storeBrokerageStatu = SystemConfigService::get('store_brokerage_statu') ? : 1;//获取后台分销类型
-        if($storeBrokerageStatu == 1){
+        //TODO 获取后台分销类型  1 指定分销 2 人人分销
+        $storeBrokerageStatus = SystemConfigService::get('store_brokerage_statu');
+        $storeBrokerageStatus = $storeBrokerageStatus ? $storeBrokerageStatus : 1;
+        //TODO 指定分销 判断 上上级是否时推广员  如果不是推广员直接返回
+        if($storeBrokerageStatus == 1){
             if(!User::be(['uid'=>$userInfoTwo['spread_uid'],'is_promoter'=>1]))  return true;
         }
-        $brokerageRatio = (SystemConfigService::get('store_brokerage_two') ?: 0)/100;
-        if($brokerageRatio <= 0) return true;
-        $cost = isset($orderInfo['cost']) ? $orderInfo['cost'] : 0;//成本价
-        if($cost > $orderInfo['pay_price']) return true;//成本价大于支付价格时直接返回
-        $brokeragePrice = bcmul(bcsub($orderInfo['pay_price'],$cost,2),$brokerageRatio,2);
+        //TODO 获取二级返佣比例
+        $storeBrokerageTwo = SystemConfigService::get('store_brokerage_two');
+        //TODO 二级返佣比例小于等于0 直接返回
+        if($storeBrokerageTwo <= 0) return true;
+        //TODO 计算获取二级返佣比例
+        $brokerageRatio = bcdiv($storeBrokerageTwo,100,2);
+        //TODO 获取成本价
+        $cost = isset($orderInfo['cost']) ? $orderInfo['cost'] : 0;
+        //TODO 成本价大于等于支付价格时直接返回
+        if($cost >= $orderInfo['pay_price']) return true;
+        //TODO 获取订单毛利
+        $payPrice = bcsub($orderInfo['pay_price'],$cost,2);
+        //TODO 返佣金额 = 毛利 / 二级返佣比例
+        $brokeragePrice = bcmul($payPrice,$brokerageRatio,2);
+        //TODO 返佣金额小于等于0 直接返回不返佣金
         if($brokeragePrice <= 0) return true;
+        //TODO 获取上上级推广员信息
+        $spreadUserInfoTwo = User::getUserInfo($userInfoTwo['spread_uid']);
+        //TODO 获取上上级推广员返佣之后余额
+        $balance = bcadd($spreadUserInfoTwo['now_money'],$brokeragePrice,2);
         $mark = '二级推广人'.$userInfo['nickname'].'成功消费'.floatval($orderInfo['pay_price']).'元,奖励推广佣金'.floatval($brokeragePrice);
         self::beginTrans();
-        $res1 = UserBill::income('获得推广佣金',$userInfoTwo['spread_uid'],'now_money','brokerage',$brokeragePrice,$orderInfo['id'],0,$mark);
+        //TODO 添加返佣记录
+        $res1 = UserBill::income('获得推广佣金',$userInfoTwo['spread_uid'],'now_money','brokerage',$brokeragePrice,$orderInfo['id'],$balance,$mark);
+        //TODO 添加用户余额
         $res2 = self::bcInc($userInfoTwo['spread_uid'],'now_money',$brokeragePrice,'uid');
         $res = $res1 && $res2;
         self::checkTrans($res);
         return $res;
     }
+
     /*
      *  获取推荐人
      * @param int $two_uid

+ 16 - 3
application/ebapi/model/user/UserExtract.php

@@ -51,9 +51,22 @@ class UserExtract extends ModelBasic
             return self::setErrorInfo('提现方式不存在');
         $userInfo = User::get($userInfo['uid']);
         $brokerage = UserBill::getBrokerage($userInfo['uid']);//获取总佣金
-        $extractTotalPrice = self::userExtractTotalPrice($userInfo['uid']);//累计提现
-        $extractPrice = (float)bcsub($brokerage,$extractTotalPrice,2);//减去已提现金额
-        $extractPrice = (float)bcsub($extractPrice,self::userExtractTotalPrice($userInfo['uid'],0),2);//减去提现申请中的金额
+        $recharge = UserBill::getRecharge($userInfo['uid']);//累计充值
+        $extractTotalPrice = UserExtract::userExtractTotalPrice($userInfo['uid']);//累计提现
+        if($brokerage > $extractTotalPrice) {
+            $orderYuePrice = StoreOrder::getOrderStatusYueSum($userInfo['uid']);//余额累计消费
+            $systemAdd = UserBill::getSystemAdd($userInfo['uid']);//后台添加余额
+            $yueCount = bcadd($recharge,$systemAdd,2);// 后台添加余额 + 累计充值  = 非佣金的总金额
+            $orderYuePrice = $yueCount > $orderYuePrice ? 0 : bcsub($orderYuePrice,$yueCount,2);// 余额累计消费(使用佣金消费的金额)
+            $brokerage = bcsub($brokerage,$extractTotalPrice,2);//减去已提现金额
+            $extract_price = self::userExtractTotalPrice($userInfo['uid'],0);
+            $brokerage = $extract_price < $brokerage ? bcsub($brokerage,$extract_price,2) : 0;//减去审核中的提现金额
+            $brokerage = $brokerage > $orderYuePrice ? bcsub($brokerage,$orderYuePrice,2) : 0;//减掉余额支付
+        }else{
+            $brokerage=0;
+        }
+        $extractPrice = (float)bcsub($brokerage,$extractTotalPrice,2) > 0 ?
+            bcsub($brokerage,$extractTotalPrice,2) : 0;//可提现
         if($extractPrice < 0) return self::setErrorInfo('提现佣金不足'.$data['money']);
         if($data['money'] > $extractPrice) return self::setErrorInfo('提现佣金不足'.$data['money']);
         $balance = bcsub($userInfo['now_money'],$data['money'],2);

+ 10 - 4
application/ebapi/model/user/WechatUser.php

@@ -73,32 +73,38 @@ class WechatUser extends ModelBasic
         $routineInfo['user_type'] = 'routine';//用户类型
         $page = '';//跳转小程序的页面
         $spid = 0;//绑定关系uid
+        $isCOde=false;
         //获取是否有扫码进小程序
         if($routine['code']){
             $info = RoutineQrcode::getRoutineQrcodeFindType($routine['code']);
             if($info){
                 $spid = $info['third_id'];
                 $page = $info['page'];
+                $isCOde=true;
             }else{
                 $spid = $routine['spid'];
             }
         }else if($routine['spid']) $spid = $routine['spid'];
         //  判断unionid  存在根据unionid判断
-        $routineInfo['code']=$spid;
         if($routineInfo['unionid'] != '' && self::be(['unionid'=>$routineInfo['unionid']])){
             self::edit($routineInfo,$routineInfo['unionid'],'unionid');
             $uid = self::where('unionid',$routineInfo['unionid'])->value('uid');
+            $routineInfo['code']=$spid;
+            $routineInfo['isPromoter']=$isCOde;
             User::updateWechatUser($routineInfo,$uid);
         }else if(self::be(['routine_openid'=>$routineInfo['routine_openid']])){ //根据小程序openid判断
             self::edit($routineInfo,$routineInfo['routine_openid'],'routine_openid');
             $uid = self::where('routine_openid',$routineInfo['routine_openid'])->value('uid');
+            $routineInfo['code']=$spid;
+            $routineInfo['isPromoter']=$isCOde;
             User::updateWechatUser($routineInfo,$uid);
         }else{
             $routineInfo['add_time'] = time();//用户添加时间
             $routineInfo = self::set($routineInfo);
-            if(User::isUserSpread($spid)) {
-                $res = User::setRoutineUser($routineInfo,$spid); //用户上级
-            }else $res = User::setRoutineUser($routineInfo);
+//            if(User::isUserSpread($spid)) {
+//                $res = User::setRoutineUser($routineInfo,$spid); //用户上级
+//            }else
+            $res = User::setRoutineUser($routineInfo,$spid);
             $uid = $res->uid;
         }
         $data['page'] = $page;

+ 2 - 2
application/version.php

@@ -1,2 +1,2 @@
-version=CRMEB-DTKY v2.6.03
-version_code=131
+version=CRMEB-DT v2.6.13
+version_code=135

+ 57 - 25
application/wap/controller/AuthApi.php

@@ -9,6 +9,7 @@ namespace app\wap\controller;
 
 
 use Api\Express;
+use app\core\util\WechatService;
 use app\wap\model\store\StoreBargain;
 use app\wap\model\store\StoreBargainUser;
 use app\wap\model\store\StoreBargainUserHelp;
@@ -155,18 +156,29 @@ class AuthApi extends AuthController
 
     public function get_user_collect_product($first = 0,$limit = 8)
     {
-        $list = StoreProductRelation::where('A.uid',$this->userInfo['uid'])
-            ->field('B.id pid,B.store_name,B.price,B.ot_price,B.sales,B.image,B.is_del,B.is_show')->alias('A')
-            ->where('A.type','collect')->where('A.category','product')
-            ->order('A.add_time DESC')->join('__STORE_PRODUCT__ B','A.product_id = B.id')
-            ->limit($first,$limit)->select()->toArray();
-        foreach ($list as $k=>$product){
+        $productList = StoreProductRelation::getProductRelation($this->userInfo['uid'], $first, $limit);
+        $seckillList = StoreProductRelation::getSeckillRelation($this->userInfo['uid'], $first, $limit);
+        $sort = [];
+        $list = [];
+        foreach ($productList as $key=>&$product){
             if($product['pid']){
-                $list[$k]['is_fail'] = $product['is_del'] && $product['is_show'];
+                $product['is_fail'] = $product['is_del'] && $product['is_show'];
+                $sort[] = $product['add_time'];
+                array_push($list,$product);
             }else{
-                unset($list[$k]);
+                unset($productList[$key]);
             }
         }
+        foreach ($seckillList as $key=>&$seckill){
+            if($seckill['pid']){
+                $seckill['is_fail'] = $seckill['is_del'] && $seckill['is_show'];
+                $sort[] = $seckill['add_time'];
+                array_push($list,$seckill);
+            }else{
+                unset($seckillList[$key]);
+            }
+        }
+        array_multisort($sort,SORT_DESC,SORT_NUMERIC,$list);
         return JsonService::successful($list);
     }
 
@@ -488,16 +500,18 @@ class AuthApi extends AuthController
             $keyword = base64_decode(htmlspecialchars($encodedData));
         }
         $model = StoreProduct::validWhere();
-        if($cId && $sId){
-            $product_ids=\think\Db::name('store_product_cate')->where('cate_id',$sId)->column('product_id');
+        if($cId){
+            $sids = StoreCategory::pidBySidList($cId);
+            $sids[] = $cId;
+            if($sId) $sids[] = $sId;
+            $sId = implode(',',$sids);
+        }
+        if($sId){
+            $product_ids = \think\Db::name('store_product_cate')->where('cate_id','IN',$sId)->column('product_id');
             if(count($product_ids))
                 $model=$model->where('id',"in",$product_ids);
             else
                 $model=$model->where('cate_id',-1);
-        }elseif($cId){
-            $sids = StoreCategory::pidBySidList($cId)?:[];
-            $sids[] = $cId;
-            $model->where('cate_id','IN',$sids);
         }
         if(!empty($keyword)) $model->where('keyword|store_name','LIKE',"%$keyword%");
         if($news) $model->where('is_new',1);
@@ -564,15 +578,29 @@ class AuthApi extends AuthController
                 $now_user = StoreService::field("uid,nickname")->where(array("uid"=>$params["uid"]))->find();
                 if(!$now_user)$now_user = User::field("uid,nickname")->where(array("uid"=>$params["uid"]))->find();
                 if($params["to_uid"]) {
-                    $head = '您有新的消息,请注意查收!';
-                    WechatTemplateService::sendTemplate(WechatUser::uidToOpenid($params["to_uid"]),WechatTemplateService::SERVICE_NOTICE,[
-                        'first'=>$head,
-                        'keyword1'=>$now_user["nickname"],
-                        'keyword2'=>"客服提醒",
-                        'keyword3'=> preg_replace('/<img.*? \/>/','[图片]',$value["msn"]),
-                        'keyword4'=>date('Y-m-d H:i:s',time()),
-                        'remark'=>'点击立即查看消息'
-                    ],Url::build('service/service_ing',['to_uid'=>$now_user["uid"],'mer_id'=>$params["mer_id"]],true,true));
+                    $userInfo = WechatUser::where('uid',$params["to_uid"])->field('nickname,subscribe,openid,headimgurl')->find();
+                    $head = '客服提醒';
+                    $description = '您有新的消息,请注意查收!';
+                    $url = Url::build('service/service_ing',['to_uid'=>$now_user["uid"],'mer_id'=>$params["mer_id"]],true,true);
+                    $message = WechatService::newsMessage($head,$description,$url,$userInfo['headimgurl']);
+                    if($userInfo){
+                        $userInfo = $userInfo->toArray();
+                        if($userInfo['subscribe'] && $userInfo['openid']){
+                            try {
+                                WechatService::staffService()->message($message)->to($userInfo['openid'])->send();
+                            } catch (\Exception $e) {
+                                $errorLog = $userInfo['nickname'].'发送失败'.$e->getMessage();
+                            }
+                        }
+                    }
+//                    WechatTemplateService::sendTemplate(WechatUser::uidToOpenid($params["to_uid"]),WechatTemplateService::SERVICE_NOTICE,[
+//                        'first'=>$head,
+//                        'keyword1'=>$now_user["nickname"],
+//                        'keyword2'=>"客服提醒",
+//                        'keyword3'=> preg_replace('/<img.*? \/>/','[图片]',$value["msn"]),
+//                        'keyword4'=>date('Y-m-d H:i:s',time()),
+//                        'remark'=>'点击立即查看消息'
+//                    ],Url::build('service/service_ing',['to_uid'=>$now_user["uid"],'mer_id'=>$params["mer_id"]],true,true));
                 }
             }
         }
@@ -683,8 +711,12 @@ class AuthApi extends AuthController
             ->field('A.*,B.coupon_price,B.use_min_price')->order('B.sort DESC,A.id DESC')->limit($limit)->select()->toArray()?:[];
         $list_coupon=[];
         foreach ($list as $k=>&$v){
-            if(!($v['is_use']=StoreCouponIssueUser::be(['uid'=>$this->userInfo['uid'],'issue_coupon_id'=>$v['id']])) && $v['total_count'] > 0 && $v['remain_count'] >0){
-                array_push($list_coupon,$v);
+            if(!($v['is_use']=StoreCouponIssueUser::be(['uid'=>$this->userInfo['uid'],'issue_coupon_id'=>$v['id']]))){
+                if($v['is_permanent'] == 0 && $v['total_count'] > 0 && $v['remain_count'] >0){
+                    array_push($list_coupon,$v);
+                }else if($v['is_permanent'] == 1){
+                    array_push($list_coupon,$v);
+                }
             }
         }
         return JsonService::successful($list_coupon);

+ 1 - 1
application/wap/controller/AuthController.php

@@ -38,7 +38,7 @@ class AuthController extends WapBasic
         }catch (\Exception $e){
             Cookie::set('is_login',0);
             $url=$this->request->url(true);
-            return $this->redirect(Url::build('Login/index',['ref'=>base64_encode(htmlspecialchars($url))]));
+            return $this->redirect(Url::build('Login/index').'?ref='.base64_encode(htmlspecialchars($url)));
         }
         $this->userInfo = User::getUserInfo($uid);
         if(!$this->userInfo || !isset($this->userInfo['uid'])) return $this->failed('读取用户信息失败!');

+ 1 - 1
application/wap/controller/My.php

@@ -66,7 +66,7 @@ class My extends AuthController
         $signList = UserSign::userSignBillWhere($this->userInfo['uid'])
             ->field('number,add_time')->order('id DESC')
             ->limit(30)->select()->toArray();
-        $goodsList = StoreProduct::getNewProduct('image,price,sales,store_name,id','0,20')->toArray();
+        $goodsList = StoreProduct::getNewProduct('image,price,IFNULL(sales,0) + IFNULL(ficti,0) AS sales,store_name,id','0,20')->toArray();
         $this->assign(compact('signed','signCount','signList','goodsList'));
         return $this->fetch();
     }

+ 9 - 10
application/wap/controller/PublicApi.php

@@ -8,6 +8,7 @@
 namespace app\wap\controller;
 
 
+use app\admin\model\system\SystemAttachment;
 use app\wap\model\store\StoreCombination;
 use app\admin\model\system\SystemGroup;
 use app\admin\model\system\SystemGroupData;
@@ -17,6 +18,7 @@ use app\wap\model\store\StoreProduct;
 use app\wap\model\wap\ArticleCategory;
 use service\FileService;
 use service\JsonService;
+use service\UploadService;
 use service\UtilService;
 use think\Cache;
 
@@ -62,7 +64,7 @@ class PublicApi
                 ->where('A.mer_id',0)->where('B.pid',$cate['id'])
                 ->join('__STORE_CATEGORY__ B','B.id = A.cate_id')
                 ->order('A.is_benefit DESC,A.sort DESC,A.add_time DESC')
-                ->limit($limit)->field('A.id,A.image,A.store_name,A.sales,A.price,A.unit_name')->select()->toArray();
+                ->limit($limit)->field('A.id,A.image,A.store_name,IFNULL(A.sales,0) + IFNULL(A.ficti,0) as sales,A.price,A.unit_name')->select()->toArray();
             if(count($cate['product']))
                 $result[] = $cate;
         }
@@ -88,7 +90,7 @@ class PublicApi
             $StoreProductmodel = $StoreProductmodel->where('is_postage',1);
 
         $list = $StoreProductmodel->where('mer_id',0)->order('is_best DESC,sort DESC,add_time DESC')
-            ->limit($first,$limit)->field('id,image,store_name,sales,price,unit_name')->select()->toArray();
+            ->limit($first,$limit)->field('id,image,store_name,IFNULL(sales,0) + IFNULL(ficti,0) as sales,price,unit_name')->select()->toArray();
 
         return JsonService::successful($list);
     }
@@ -96,7 +98,7 @@ class PublicApi
     public function get_best_product_list($first = 0,$limit = 8)
     {
         $list = StoreProduct::validWhere()->where('mer_id',0)->order('is_best DESC,sort DESC,add_time DESC')
-            ->limit($first,$limit)->field('id,image,store_name,sales,price,unit_name')->select()->toArray();
+            ->limit($first,$limit)->field('id,image,store_name,IFNULL(sales,0) + IFNULL(ficti,0) as sales,price,unit_name')->select()->toArray();
         return JsonService::successful($list);
     }
 
@@ -106,7 +108,6 @@ class PublicApi
         $mediaIds = explode(',',$mediaIds);
         $temporary = \app\core\util\WechatService::materialTemporaryService();
         $pathList = [];
-        $dir='public'.DS.'uploads'.DS.'wechat'.DS.'media';
         foreach ($mediaIds as $mediaId){
             if(!$mediaId) continue;
             try{
@@ -115,12 +116,10 @@ class PublicApi
                 continue;
             }
             $name = substr(md5($mediaId),12,20).'.jpg';
-            $path = '.'.DS.$dir.DS.$name;
-            $file=new FileService();
-            $res=$file->create_dir($dir);
-            if(!$res) return JsonService::fail('生成文件保存目录失败!请检查权限!');
-            $res = file_put_contents($path,$content);
-            if($res) $pathList[] = UtilService::pathToUrl($path);
+            $res = UploadService::imageStream($name,$content,'wechat/media');
+            if(!is_array($res)) return JsonService::fail($res);
+            SystemAttachment::attachmentAdd($res['name'],$res['size'],$res['type'],$res['dir'],$res['thumb_path'],1,$res['image_type'],$res['time']);
+            $pathList[] = UtilService::pathToUrl($res['dir']);
         }
         return JsonService::successful($pathList);
     }

+ 8 - 4
application/wap/controller/Store.php

@@ -93,6 +93,10 @@ class Store extends AuthController
                 $sort[] = $v['is_get'] = StoreCouponIssueUser::be(['uid'=>$this->userInfo['uid'],'issue_coupon_id'=>$v['id']]) ? 1:0;
                 array_push($lists,$v);
             }
+            else if((int)$v['is_permanent']==1){
+                $sort[] = $v['is_get'] = StoreCouponIssueUser::be(['uid'=>$this->userInfo['uid'],'issue_coupon_id'=>$v['id']]) ? 1:0;
+                array_push($lists,$v);
+            }
         }
         array_multisort($sort,SORT_ASC,SORT_NUMERIC,$lists);
         $this->assign(compact('lists'));
@@ -218,7 +222,7 @@ class Store extends AuthController
             'user'=>$user,
             'site_name'=>$site_name,
             'site_logo'=>$site_logo,
-            'wechat_qrcode'=>$wechat_qrcode,
+            'wechat_qrcode'=>str_replace('\\','/',$wechat_qrcode),
             'pindAll'=>$pindAll,
             'storeInfo'=>$combinationOne,
             'reply'=>StoreProductReply::getRecProductReply($combinationOne['product_id']),
@@ -288,11 +292,11 @@ class Store extends AuthController
     public function seckill_detail($id = ''){
 
         if(!$id || !($storeInfo = StoreSeckill::getValidProduct($id))) return $this->failed('商品不存在或已下架!');
-        $storeInfo['userLike'] = StoreProductRelation::isProductRelation($storeInfo['product_id'],$this->userInfo['uid'],'like','product_seckill');
+        $storeInfo['userLike'] = StoreProductRelation::isProductRelation($storeInfo['id'],$this->userInfo['uid'],'like','product_seckill');
 
-        $storeInfo['like_num'] = StoreProductRelation::productRelationNum($storeInfo['product_id'],'like','product_seckill');
+        $storeInfo['like_num'] = StoreProductRelation::productRelationNum($storeInfo['id'],'like','product_seckill');
 
-        $storeInfo['userCollect'] = StoreProductRelation::isProductRelation($storeInfo['product_id'],$this->userInfo['uid'],'collect','product_seckill');
+        $storeInfo['userCollect'] = StoreProductRelation::isProductRelation($storeInfo['id'],$this->userInfo['uid'],'collect','product_seckill');
         list($productAttr,$productValue) = StoreProductAttr::getProductAttrDetail($storeInfo['product_id']);
         $wechatInfo = WechatUser::get($this->userInfo['uid']);
         setView($this->userInfo['uid'],$id,$storeInfo['product_id'],'viwe','seckill');

+ 0 - 0
application/wap/controller/WapBasic.php


部分文件因为文件数量过多而无法显示