소스 검색

更新3.1版本

liaofei 6 년 전
부모
커밋
dacdfa50e1
100개의 변경된 파일3047개의 추가작업 그리고 1068개의 파일을 삭제
  1. 2 2
      crmeb/.version
  2. 4 11
      crmeb/app/admin/controller/AdminException.php
  3. 1 2
      crmeb/app/admin/controller/Index.php
  4. 2 2
      crmeb/app/admin/controller/agent/AgentManage.php
  5. 39 1
      crmeb/app/admin/controller/article/Article.php
  6. 1 1
      crmeb/app/admin/controller/article/ArticleCategory.php
  7. 1 1
      crmeb/app/admin/controller/article/WechatNews.php
  8. 65 11
      crmeb/app/admin/controller/order/StoreOrder.php
  9. 3 4
      crmeb/app/admin/controller/setting/SystemConfig.php
  10. 1 1
      crmeb/app/admin/controller/setting/SystemGroupData.php
  11. 5 2
      crmeb/app/admin/controller/store/CopyTaobao.php
  12. 1 1
      crmeb/app/admin/controller/store/StoreCategory.php
  13. 1 1
      crmeb/app/admin/controller/store/StoreInfoMana.php
  14. 15 7
      crmeb/app/admin/controller/store/StoreProduct.php
  15. 1 1
      crmeb/app/admin/controller/system/SystemAttachment.php
  16. 3 1
      crmeb/app/admin/controller/system/SystemCleardata.php
  17. 14 5
      crmeb/app/admin/controller/system/SystemDatabackup.php
  18. 0 1
      crmeb/app/admin/controller/system/SystemFile.php
  19. 97 0
      crmeb/app/admin/controller/system/SystemStore.php
  20. 1 1
      crmeb/app/admin/controller/ump/StoreSeckill.php
  21. 1 1
      crmeb/app/admin/controller/user/UserLevel.php
  22. 3 3
      crmeb/app/admin/controller/wechat/Reply.php
  23. 1 1
      crmeb/app/admin/controller/wechat/StoreService.php
  24. 4 4
      crmeb/app/admin/controller/wechat/WechatUser.php
  25. 2 1
      crmeb/app/admin/controller/widget/Images.php
  26. 6 0
      crmeb/app/admin/model/article/Article.php
  27. 35 19
      crmeb/app/admin/model/order/StoreOrder.php
  28. 2 1
      crmeb/app/admin/model/store/StoreProductAttr.php
  29. 5 2
      crmeb/app/admin/model/store/StoreProductAttrValue.php
  30. 18 1
      crmeb/app/admin/model/system/SystemAttachment.php
  31. 66 0
      crmeb/app/admin/model/system/SystemStore.php
  32. 1 1
      crmeb/app/admin/model/ump/StoreCombination.php
  33. 2 2
      crmeb/app/admin/model/user/User.php
  34. 2 2
      crmeb/app/admin/model/user/UserExtract.php
  35. 2 1
      crmeb/app/admin/model/wechat/WechatUser.php
  36. 1 1
      crmeb/app/admin/view/article/article/create.php
  37. 29 5
      crmeb/app/admin/view/article/article/index.php
  38. 83 0
      crmeb/app/admin/view/article/article/relation.php
  39. 1 1
      crmeb/app/admin/view/login/index.php
  40. 16 1
      crmeb/app/admin/view/order/store_order/index.php
  41. 4 2
      crmeb/app/admin/view/order/store_order/order_info.php
  42. 88 0
      crmeb/app/admin/view/order/store_order/write_order.php
  43. 0 1
      crmeb/app/admin/view/record/record/chart_combination.php
  44. 1 1
      crmeb/app/admin/view/setting/system_config_tab/sonconfigtab.php
  45. 3 2
      crmeb/app/admin/view/sms/sms_config/index.php
  46. 1 0
      crmeb/app/admin/view/store/copy_taobao/index.php
  47. 5 1
      crmeb/app/admin/view/store/store_category/index.php
  48. 5 1
      crmeb/app/admin/view/store/store_product/attr.php
  49. 243 0
      crmeb/app/admin/view/system/system_store/index.php
  50. 92 1
      crmeb/app/admin/view/wechat/wechat_news_category/send_news.php
  51. 2 2
      crmeb/app/admin/view/wechat/wechat_user/index.php
  52. 3 3
      crmeb/app/admin/view/widget/images.php
  53. 14 5
      crmeb/app/api/ApiExceptionHandle.php
  54. 33 9
      crmeb/app/api/controller/AuthController.php
  55. 18 0
      crmeb/app/api/controller/BaiduController.php
  56. 30 5
      crmeb/app/api/controller/PublicController.php
  57. 3 3
      crmeb/app/api/controller/activity/StoreBargainController.php
  58. 11 9
      crmeb/app/api/controller/activity/StoreCombinationController.php
  59. 10 9
      crmeb/app/api/controller/activity/StoreSeckillController.php
  60. 93 22
      crmeb/app/api/controller/order/StoreOrderController.php
  61. 61 47
      crmeb/app/api/controller/store/StoreProductController.php
  62. 1 1
      crmeb/app/api/controller/user/UserBillController.php
  63. 45 3
      crmeb/app/api/controller/user/UserController.php
  64. 44 22
      crmeb/app/api/controller/wechat/AuthController.php
  65. 25 0
      crmeb/app/api/controller/wechat/WechatController.php
  66. 2 1
      crmeb/app/event.php
  67. 7 0
      crmeb/app/models/article/Article.php
  68. 6 5
      crmeb/app/models/store/StoreBargain.php
  69. 8 0
      crmeb/app/models/store/StoreCart.php
  70. 1 1
      crmeb/app/models/store/StoreCategory.php
  71. 11 7
      crmeb/app/models/store/StoreCouponIssue.php
  72. 494 230
      crmeb/app/models/store/StoreOrder.php
  73. 97 95
      crmeb/app/models/store/StorePink.php
  74. 30 2
      crmeb/app/models/store/StoreProduct.php
  75. 8 1
      crmeb/app/models/store/StoreProductAttr.php
  76. 73 0
      crmeb/app/models/system/Cache.php
  77. 62 0
      crmeb/app/models/system/SystemStore.php
  78. 52 31
      crmeb/app/models/system/SystemUserLevel.php
  79. 18 18
      crmeb/app/models/system/SystemUserTask.php
  80. 125 15
      crmeb/app/models/user/User.php
  81. 32 0
      crmeb/app/models/user/UserAddress.php
  82. 14 11
      crmeb/app/models/user/UserExtract.php
  83. 45 27
      crmeb/app/models/user/UserLevel.php
  84. 29 4
      crmeb/app/models/user/UserRecharge.php
  85. 47 61
      crmeb/app/models/user/UserSign.php
  86. 6 5
      crmeb/app/models/user/UserTaskFinish.php
  87. 6 0
      crmeb/app/models/user/UserToken.php
  88. 29 25
      crmeb/app/models/user/WechatUser.php
  89. 1 1
      crmeb/config/app.php
  90. 1 1
      crmeb/config/cache.php
  91. 1 1
      crmeb/config/session.php
  92. 14 1
      crmeb/crmeb/exceptions/AuthException.php
  93. 1 12
      crmeb/crmeb/interfaces/ProviderInterface.php
  94. 26 0
      crmeb/crmeb/services/ApiErrorCode.php
  95. 0 2
      crmeb/crmeb/services/CustomerService.php
  96. 1 1
      crmeb/crmeb/services/FileService.php
  97. 24 2
      crmeb/crmeb/services/SMSService.php
  98. 292 176
      crmeb/crmeb/services/UploadService.php
  99. 112 80
      crmeb/crmeb/services/UtilService.php
  100. 0 0
      crmeb/crmeb/services/WechatService.php

+ 2 - 2
crmeb/.version

@@ -1,2 +1,2 @@
-version=CRMEB-KYDT v3.01
-version_code=132
+version=CRMEB-DT v3.1
+version_code=133

+ 4 - 11
crmeb/app/admin/controller/AdminException.php

@@ -27,17 +27,10 @@ class AdminException extends Handle
         if ($e instanceof ValidateException) {
             return app('json')->make(422, $e->getError());
         }
-        // 请求异常
-        if (env("APP_DEBUG") == true) {              //如是开启调试,就走原来的方法
-            return parent::render($request, $e);
-        } else {
-            if ($e instanceof \Exception && request()->isAjax()) {
-                return app('json')->fail(['code' => $e->getCode(), 'message' => $e->getMessage(), 'file' => $e->getFile()]);
-            } else {
-                $title = '系统错误';
-                $msg = addslashes($e->getMessage());
-                return \response(view('public/500', compact('title', 'msg'))->getContent());
-            }
+        if ($e instanceof \Exception && request()->isAjax()) {
+            return app('json')->fail(['code' => $e->getCode(), 'message' => $e->getMessage(), 'file' => $e->getFile()]);
         }
+
+        return parent::render($request, $e);
     }
 }

+ 1 - 2
crmeb/app/admin/controller/Index.php

@@ -12,6 +12,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\models\store\StoreOrder;
 use crmeb\services\SystemConfigService;
 use FormBuilder\Json;
 
@@ -29,8 +30,6 @@ 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),

+ 2 - 2
crmeb/app/admin/controller/agent/AgentManage.php

@@ -211,7 +211,7 @@ class AgentManage extends AuthController
         if(!$imageInfo){
             $res = \app\models\routine\RoutineCode::getShareCode($uid, 'spread', '', '');
             if(!$res) throw new \think\Exception('二维码生成失败');
-            $imageInfo = UploadService::imageStream($name,$res['res'],'routine/spread/code');
+            $imageInfo = UploadService::getInstance()->setUploadPath('routine/spread/code')->imageStream($name,$res['res']);
             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']]);
@@ -246,7 +246,7 @@ class AgentManage extends AuthController
             if(!$imageInfo){
                 $res = \app\models\routine\RoutineCode::getShareCode($uid, 'spread', '', '');
                 if(!$res) return JsonService::fail('二维码生成失败');
-                $imageInfo = UploadService::imageStream($name,$res['res'],'routine/spread/code');
+                $imageInfo = UploadService::getInstance()->setUploadPath('routine/spread/code')->imageStream($name,$res['res']);
                 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']);
                 RoutineQrcode::setRoutineQrcodeFind($res['id'],['status'=>1,'time'=>time(),'qrcode_url'=>$imageInfo['dir']]);

+ 39 - 1
crmeb/app/admin/controller/article/Article.php

@@ -99,7 +99,7 @@ class Article extends AuthController
      * @return \think\response\Json
      */
     public function upload_image(){
-        $res = Upload::Image($_POST['file'],'wechat/image/'.date('Ymd'));
+        $res = Upload::getInstance()->setUploadPath('wechat/image/'.date('Ymd'))->image($_POST['file']);
         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']]);
@@ -187,4 +187,42 @@ class Article extends AuthController
         $this->assign(ArticleModel::getAll($where));
         return $this->fetch();
     }
+
+    /**
+     * 关联文章 id
+     * @param int $id
+     */
+    public function relation($id = 0)
+    {
+        $this->assign('id',$id);
+        return $this->fetch();
+    }
+
+    /**
+     * 保存选择的产品
+     * @param int $id
+     */
+    public function edit_article($id = 0)
+    {
+        if(!$id) return Json::fail('缺少参数');
+        list($product_id) = Util::postMore([
+            ['product_id',0]
+        ],$this->request,true);
+        if(ArticleModel::edit(['product_id'=>$product_id],['id'=>$id]))
+            return Json::successful('保存成功');
+        else
+            return Json::fail('保存失败');
+    }
+    /**
+     * 取消绑定的产品id
+     * @param int $id
+     */
+    public function unrelation($id = 0)
+    {
+        if(!$id) return Json::fail('缺少参数');
+        if(ArticleModel::edit(['product_id'=>0],$id))
+            return Json::successful('取消关联成功!');
+        else
+            return Json::fail('取消失败');
+    }
 }

+ 1 - 1
crmeb/app/admin/controller/article/ArticleCategory.php

@@ -72,7 +72,7 @@ class ArticleCategory extends AuthController
      * s上传图片
      * */
     public function upload(){
-        $res = Upload::image('file','article');
+        $res = Upload::getInstance()->setUploadPath('article')->image('file');
         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'])]);

+ 1 - 1
crmeb/app/admin/controller/article/WechatNews.php

@@ -89,7 +89,7 @@ class WechatNews extends AuthController
      * @return \think\response\Json
      */
     public function upload_image(){
-        $res = Upload::Image($_POST['file'],'wechat/image/'.date('Ymd'));
+        $res = Upload::getInstance()->setUploadPath('wechat/image/'.date('Ymd'))->image($_POST['file']);
         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['thumb_path']]);

+ 65 - 11
crmeb/app/admin/controller/order/StoreOrder.php

@@ -10,6 +10,7 @@ use app\admin\controller\AuthController;
 use app\admin\model\system\Express;
 use crmeb\repositories\OrderRepository;
 use crmeb\services\ExpressService;
+use crmeb\services\JsonService;
 use crmeb\services\MiniProgramService;
 use crmeb\services\UtilService;
 use crmeb\services\WechatService;
@@ -22,7 +23,6 @@ use app\admin\model\user\User;
 use app\admin\model\user\UserBill;
 use crmeb\basic\BaseModel;
 use crmeb\services\CacheService;
-use crmeb\services\JsonService;
 use crmeb\services\UtilService as Util;
 use crmeb\services\JsonService as Json;
 use think\facade\Db;
@@ -85,6 +85,41 @@ class StoreOrder extends AuthController
         ]);
         return JsonService::successlayui(StoreOrderModel::OrderList($where));
     }
+
+    /**
+     * 核销码核销
+     * @param string $verify_code
+     * @return html
+     */
+    public function write_order($verify_code = '',$is_confirm = 0)
+    {
+        if($this->request->isAjax()){
+            if(!$verify_code) return JsonService::fail('缺少核销码!');
+            StoreOrderModel::beginTrans();
+            $orderInfo = StoreOrderModel::where('verify_code',$verify_code)->where('paid',1)->where('refund_status',0)->find();
+            if(!$orderInfo) return JsonService::fail('核销订单不存在!');
+            if($orderInfo->status > 0) return JsonService::fail('订单已核销!');
+            if($orderInfo->combination_id && $orderInfo->pink_id){
+                $res = StorePink::where('id',$orderInfo->pink_id)->where('status','<>',2)->count();
+                if($res) return JsonService::fail('拼团订单暂未成功无法核销!');
+            }
+            if($is_confirm == 0){
+                $orderInfo['nickname'] = User::where(['uid'=>$orderInfo['uid']])->value('nickname');
+                return JsonService::successful($orderInfo);
+            }
+            $orderInfo->status = 2;
+            if($orderInfo->save()) {
+                StoreOrderModel::commitTrans();
+                return JsonService::successful('核销成功!');
+            }else {
+                StoreOrderModel::rollbackTrans();
+                return JsonService::fail('核销失败');
+            }
+        }else
+            $this->assign('is_layui',1);
+            return $this->fetch();
+    }
+
     public function orderchart(){
         $where = Util::getMore([
             ['status',''],
@@ -268,6 +303,8 @@ class StoreOrder extends AuthController
                 return Json::fail('暂时不支持其他发货类型');
                 break;
         }
+        //短信发送
+        event('ShortMssageSend',[StoreOrderModel::where('id',$id)->value('order_id'),'Deliver']);
         return Json::successful('修改成功!');
     }
 
@@ -371,16 +408,22 @@ class StoreOrder extends AuthController
         if($order['paid'] == 1 && $order['status'] == 1) $data['status'] = 2;
         else if($order['pay_type'] == 'offline') $data['status'] = 2;
         else return Json::fail('请先发货或者送货!');
-        if(!StoreOrderModel::edit($data,$id))
-            return Json::fail(StoreOrderModel::getErrorInfo('收货失败,请稍候再试!'));
-        else{
-            try{
+        StoreOrderModel::beginTrans();
+        try{
+            if(!StoreOrderModel::edit($data,$id)) {
+                StoreOrderModel::rollbackTrans();
+                return Json::fail(StoreOrderModel::getErrorInfo('收货失败,请稍候再试!'));
+            }else{
                 OrderRepository::storeProductOrderTakeDeliveryAdmin($order, $id);
-            }catch (\Exception $e){
-                return Json::fail($e->getMessage());
+                StoreOrderStatus::setStatus($id,'take_delivery','已收货');
+                StoreOrderModel::commitTrans();
+                //发送短信
+                event('ShortMssageSend',[$order['order_id'],'Receiving']);
+                return Json::successful('收货成功!');
             }
-            StoreOrderStatus::setStatus($id,'take_delivery','已收货');
-            return Json::successful('收货成功!');
+         }catch (\Exception $e){
+            StoreOrderModel::rollbackTrans();
+            return Json::fail($e->getMessage());
         }
     }
     /**
@@ -461,9 +504,11 @@ class StoreOrder extends AuthController
             if(!$res) return Json::fail('余额退款失败!');
         }
         $resEdit = StoreOrderModel::edit($data,$id);
+        $res = true;
         if($resEdit){
             $data['type'] = $type;
-            if($data['type'] == 1)  StorePink::setRefundPink($id);
+            if($data['type'] == 1)  $res = StorePink::setRefundPink($id);
+            if(!$res) return Json::fail('修改失败');
             try{
                 OrderRepository::storeProductOrderRefundY($data, $id);
             }catch (\Exception $e){
@@ -475,7 +520,7 @@ class StoreOrder extends AuthController
             return Json::successful('修改成功!');
         }else{
             StoreOrderStatus::setStatus($id,'refund_price','退款给用户'.$refund_price.'元失败');
-            return Json::successful('修改失败!');
+            return Json::fail('修改失败!');
         }
     }
     public function order_info($oid = '')
@@ -690,4 +735,13 @@ class StoreOrder extends AuthController
        $this->assign(StoreOrderStatus::systemPage($oid));
        return $this->fetch();
     }
+
+    /*
+     * 订单列表推荐人详细
+     */
+    public function order_spread_user($uid){
+        $spread = User::where('uid',$uid)->find();
+        $this->assign('spread',$spread);
+        return $this->fetch();
+    }
 }

+ 3 - 4
crmeb/app/admin/controller/setting/SystemConfig.php

@@ -1,7 +1,6 @@
 <?php
 namespace app\admin\controller\setting;
 
-use app\admin\model\system\SystemAttachment;
 use think\facade\Route as Url;
 use crmeb\services\FormBuilder as Form;
 use crmeb\services\UtilService as Util;
@@ -250,7 +249,7 @@ class SystemConfig extends AuthController
      * @param $id
      * @return mixed
      */
-    public function edit_cinfig($id){
+    public function edit_config($id){
         $menu = ConfigModel::get($id)->getData();
         if(!$menu) return Json::fail('数据不存在!');
         $formbuider = array();
@@ -342,7 +341,7 @@ class SystemConfig extends AuthController
      * 删除子字段
      * @return \think\response\Json
      */
-    public function delete_cinfig(){
+    public function delete_config(){
         $id = input('id');
         if(!ConfigModel::del($id))
             return Json::fail(ConfigModel::getErrorInfo('删除失败,请稍候再试!'));
@@ -395,7 +394,7 @@ class SystemConfig extends AuthController
     * 文件上传
     * */
    public function file_upload(){
-       $res = Upload::file($this->request->param('file','file'),'config/file');
+       $res = Upload::getInstance()->setUploadPath('config/file')->file($this->request->param('file','file'));
        if(!$res->status) return Json::fail($res->error);
        return Json::successful('上传成功!',['filePath'=>$res->filePath]);
    }

+ 1 - 1
crmeb/app/admin/controller/setting/SystemGroupData.php

@@ -250,7 +250,7 @@ class SystemGroupData extends AuthController
 
     public function upload()
     {
-        $res = Upload::image('file','common');
+        $res = Upload::getInstance()->setUploadPath('common')->image('file');
         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'])]);

+ 5 - 2
crmeb/app/admin/controller/store/CopyTaobao.php

@@ -156,6 +156,7 @@ class CopyTaobao extends AuthController
         $images = $this->getTaobaoImg($html);
         $images = array_merge($images);
         $this->productInfo['slider_image'] = isset($images['gaoqing']) ? $images['gaoqing'] : (array)$images;
+        $this->productInfo['slider_image'] = array_slice($this->productInfo['slider_image'],0,5);
         //获取产品详情请求链接
         $link = $this->getTaobaoDesc($html);
         //获取请求内容
@@ -184,6 +185,7 @@ class CopyTaobao extends AuthController
         $images = $this->getTianMaoImg($html);
         $images = array_merge($images);
         $this->productInfo['slider_image'] = $images;
+        $this->productInfo['slider_image'] = array_slice($this->productInfo['slider_image'],0,5);
         $this->productInfo['image'] = is_array($this->productInfo['slider_image']) && isset($this->productInfo['slider_image'][0]) ? $this->productInfo['slider_image'][0] : '';
         //获取产品详情请求链接
         $link = $this->getTianMaoDesc($html);
@@ -214,6 +216,7 @@ class CopyTaobao extends AuthController
             $this->productInfo['slider_image'] = $images['gaoqing'];
         } else
             $this->productInfo['slider_image'] = $images;
+        $this->productInfo['slider_image'] = array_slice($this->productInfo['slider_image'],0,5);
         $this->productInfo['image'] = is_array($this->productInfo['slider_image']) && isset($this->productInfo['slider_image'][0]) ? $this->productInfo['slider_image'][0] : '';
         //获取产品详情请求链接
         $link = $this->get1688Desc($html);
@@ -391,7 +394,7 @@ class CopyTaobao extends AuthController
             return JsonService::fail('插入数据库错误', ['line' => $e->getLine(), 'messag' => $e->getMessage()]);
         } catch (\Exception $e) {
             ProductModel::rollbackTrans();
-            return JsonService::fail('系统错误', ['line' => $e->getLine(), 'messag' => $e->getMessage()]);
+            return JsonService::fail('系统错误', ['line' => $e->getLine(), 'messag' => $e->getMessage(),'file'=>$e->getFile()]);
         }
     }
 
@@ -766,7 +769,7 @@ class CopyTaobao extends AuthController
         $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/' . $date_dir);
+        $imageInfo = UploadService::getInstance()->setUploadPath('attach/' . $date_dir)->imageStream($name, $content);
         if (!is_array($imageInfo)) return $imageInfo;
         $date['path'] = $imageInfo['dir'];
         $date['name'] = $imageInfo['name'];

+ 1 - 1
crmeb/app/admin/controller/store/StoreCategory.php

@@ -107,7 +107,7 @@ class StoreCategory extends AuthController
      */
     public function upload()
     {
-        $res = Upload::image('file','store/category'.date('Ymd'));
+        $res = Upload::getInstance()->setUploadPath('store/category'.date('Ymd'))->image('file');
         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'])]);

+ 1 - 1
crmeb/app/admin/controller/store/StoreInfoMana.php

@@ -68,7 +68,7 @@ class StoreInfoMana extends AuthController
      * */
     public function upload()
     {
-        $res = Upload::image('file','article/'.date('Ymd'));
+        $res = Upload::getInstance()->setUploadPath('article/'.date('Ymd'))->image('file');
         SystemAttachment::attachmentAdd($res['name'],$res['size'],$res['type'],$res['dir'],$res['thumb_path'],2,$res['image_type'],$res['time']);
         if(is_array($res))
             return Json::successful('图片上传成功!',['name'=>$res['name'],'url'=>Upload::pathToUrl($res['thumb_path'])]);

+ 15 - 7
crmeb/app/admin/controller/store/StoreProduct.php

@@ -142,7 +142,8 @@ class StoreProduct extends AuthController
             Form::input('store_name','产品名称')->col(Form::col(24)),
             Form::input('store_info','产品简介')->type('textarea'),
             Form::input('keyword','产品关键字')->placeholder('多个用英文状态下的逗号隔开'),
-            Form::input('unit_name','产品单位','件'),
+            Form::input('unit_name','产品单位','件')->col(Form::col(12)),
+            Form::input('bar_code','产品条码','')->placeholder('请输入商品条形码')->col(Form::col(12)),
             Form::frameImageOne('image','产品主图片(305*305px)',Url::buildUrl('admin/widget.images/index',array('fodder'=>'image')))->icon('image')->width('100%')->height('500px'),
             Form::frameImages('slider_image','产品轮播图(640*640px)',Url::buildUrl('admin/widget.images/index',array('fodder'=>'slider_image')))->maxLength(5)->icon('images')->width('100%')->height('500px')->spin(0),
             Form::number('price','产品售价')->min(0)->col(8),
@@ -159,7 +160,8 @@ class StoreProduct extends AuthController
             Form::radio('is_benefit','促销单品',0)->options([['label'=>'是','value'=>1],['label'=>'否','value'=>0]])->col(8),
             Form::radio('is_best','精品推荐',0)->options([['label'=>'是','value'=>1],['label'=>'否','value'=>0]])->col(8),
             Form::radio('is_new','首发新品',0)->options([['label'=>'是','value'=>1],['label'=>'否','value'=>0]])->col(8),
-            Form::radio('is_postage','是否包邮',0)->options([['label'=>'是','value'=>1],['label'=>'否','value'=>0]])->col(8)
+            Form::radio('is_postage','是否包邮',0)->options([['label'=>'是','value'=>1],['label'=>'否','value'=>0]])->col(8),
+            Form::radio('is_good','是否优品推荐',0)->options([['label'=>'是','value'=>1],['label'=>'否','value'=>0]])->col(8),
         ];
         $form = Form::make_post_form('添加产品',$field,Url::buildUrl('save'),2);
         $this->assign(compact('form'));
@@ -172,7 +174,7 @@ class StoreProduct extends AuthController
      */
     public function upload()
     {
-        $res = Upload::image('file','store/product/'.date('Ymd'));
+        $res = Upload::getInstance()->setUploadPath('store/product/'.date('Ymd'))->image('file');
         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'])]);
@@ -193,6 +195,7 @@ class StoreProduct extends AuthController
             'store_info',
             'keyword',
             ['unit_name','件'],
+            'bar_code',
             ['image',[]],
             ['slider_image',[]],
             ['postage',0],
@@ -211,6 +214,7 @@ class StoreProduct extends AuthController
             ['is_new',0],
             ['mer_use',0],
             ['is_postage',0],
+            ['is_good',0],
         ]);
         if(count($data['cate_id']) < 1) return Json::fail('请选择产品分类');
         $cate_id=$data['cate_id'];
@@ -269,12 +273,13 @@ class StoreProduct extends AuthController
             Form::input('store_name','产品名称',$product->getData('store_name')),
             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::input('unit_name','产品单位',$product->getData('unit_name'))->col(12),
+            Form::input('bar_code','产品条码',$product->getData('bar_code'))->col(12),
             Form::frameImageOne('image','产品主图片(305*305px)',Url::buildUrl('admin/widget.images/index',array('fodder'=>'image')),$product->getData('image'))->icon('image')->width('100%')->height('500px'),
             Form::frameImages('slider_image','产品轮播图(640*640px)',Url::buildUrl('admin/widget.images/index',array('fodder'=>'slider_image')),json_decode($product->getData('slider_image'),1) ? : [])->maxLength(5)->icon('images')->width('100%')->height('500px'),
-            Form::number('price','产品售价',$product->getData('price'))->min(0)->precision(2)->col(8),
+            Form::number('price','产品售价',$product->getData('price'))->min(0)->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),
+            Form::number('give_integral','赠送积分',$product->getData('give_integral'))->min(0)->col(8),
             Form::number('postage','邮费',$product->getData('postage'))->min(0)->col(8),
             Form::number('sales','销量',$product->getData('sales'))->min(0)->precision(0)->col(8)->readonly(1),
             Form::number('ficti','虚拟销量',$product->getData('ficti'))->min(0)->precision(0)->col(8),
@@ -286,7 +291,8 @@ class StoreProduct extends AuthController
             Form::radio('is_benefit','促销单品',$product->getData('is_benefit'))->options([['label'=>'是','value'=>1],['label'=>'否','value'=>0]])->col(8),
             Form::radio('is_best','精品推荐',$product->getData('is_best'))->options([['label'=>'是','value'=>1],['label'=>'否','value'=>0]])->col(8),
             Form::radio('is_new','首发新品',$product->getData('is_new'))->options([['label'=>'是','value'=>1],['label'=>'否','value'=>0]])->col(8),
-            Form::radio('is_postage','是否包邮',$product->getData('is_postage'))->options([['label'=>'是','value'=>1],['label'=>'否','value'=>0]])->col(8)
+            Form::radio('is_postage','是否包邮',$product->getData('is_postage'))->options([['label'=>'是','value'=>1],['label'=>'否','value'=>0]])->col(8),
+            Form::radio('is_good','是否优品推荐',$product->getData('is_good'))->options([['label'=>'是','value'=>1],['label'=>'否','value'=>0]])->col(8),
         ];
         $form = Form::make_post_form('编辑产品',$field,Url::buildUrl('update',array('id'=>$id)),2);
         $this->assign(compact('form'));
@@ -306,6 +312,7 @@ class StoreProduct extends AuthController
             'store_name',
             'store_info',
             'keyword',
+            'bar_code',
             ['unit_name','件'],
             ['image',[]],
             ['slider_image',[]],
@@ -324,6 +331,7 @@ class StoreProduct extends AuthController
             ['is_new',0],
             ['mer_use',0],
             ['is_postage',0],
+            ['is_good',0],
         ]);
         if(count($data['cate_id']) < 1) return Json::fail('请选择产品分类');
         $cate_id=$data['cate_id'];

+ 1 - 1
crmeb/app/admin/controller/system/SystemAttachment.php

@@ -21,7 +21,7 @@ class SystemAttachment extends AuthController
      */
     public function upload()
     {
-        $res = Upload::image('upfile','editor/'.date('Ymd'));
+        $res = Upload::getInstance()->setUploadPath('editor/'.date('Ymd'))->image('upfile');
         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'];

+ 3 - 1
crmeb/app/admin/controller/system/SystemCleardata.php

@@ -41,12 +41,13 @@ class SystemclearData  extends AuthController
         self::clearData('store_bargain_user',1);
         self::clearData('store_bargain_user_help',1);
         self::clearData('store_product_reply',1);
+        self::clearData('store_product_cate',1);
         self::clearData('routine_qrcode',1);
         self::clearData('routine_form_id',1);
         self::clearData('user_sign',1);
         self::clearData('user_task_finish',1);
         self::clearData('user_level',1);
-        self::clearData('token',1);
+        self::clearData('user_token',1);
         self::clearData('user_group',1);
         $this->delDirAndFile('./public/uploads/store/comment');
         self::clearData('store_product_relation',1);
@@ -62,6 +63,7 @@ class SystemclearData  extends AuthController
         self::clearData('store_combination_attr_result',1);
         self::clearData('store_combination_attr_value',1);
         self::clearData('store_product_attr',1);
+        self::clearData('store_product_cate',1);
         self::clearData('store_product_attr_result',1);
         self::clearData('store_product_attr_value',1);
         self::clearData('store_seckill',1);

+ 14 - 5
crmeb/app/admin/controller/system/SystemDatabackup.php

@@ -5,6 +5,7 @@ namespace app\admin\controller\system;
 use app\admin\controller\AuthController;
 use crmeb\services\JsonService as Json;
 use \crmeb\services\MysqlBackupService as Backup;
+use think\facade\Env;
 use think\facade\Session;
 use think\facade\Db;
 
@@ -55,7 +56,7 @@ class SystemDatabackup extends AuthController
      */
     public function seetable()
     {
-        $database = config("database.database");
+        $database = Env::get("database.database");
         $tablename = request()->param('tablename');
         $res = Db::query("select * from information_schema.columns where table_name = '" . $tablename . "' and table_schema = '" . $database . "'");
         $html = '';
@@ -98,8 +99,12 @@ class SystemDatabackup extends AuthController
     {
         $tables = request()->post('tables/a');
         $db = $this->DB;
-        $res = $db->optimize($tables);
-        return Json::successful($res ? '优化成功' : '优化失败');
+        try{
+            $db->optimize($tables);
+            return Json::successful( '优化成功' );
+        }catch (\Exception $e){
+            return Json::fail($e->getMessage());
+        }
     }
 
     /**
@@ -109,8 +114,12 @@ class SystemDatabackup extends AuthController
     {
         $tables = request()->post('tables/a');
         $db = $this->DB;
-        $res = $db->repair($tables);
-        return Json::successful($res ? '修复成功' : '修复失败');
+        try{
+            $db->repair($tables);
+            return Json::successful( '修复成功' );
+        }catch (\Exception $e){
+            return Json::fail($e->getMessage());
+        }
     }
 
     /**

+ 0 - 1
crmeb/app/admin/controller/system/SystemFile.php

@@ -51,7 +51,6 @@ class SystemFile extends AuthController
                 }
             }
         }
-        //var_dump($fileAll['dir']);
         //兼容windows
         $uname = php_uname('s');
         if (strstr($uname, 'Windows') !== false) $dir = ltrim($dir, '\\');

+ 97 - 0
crmeb/app/admin/controller/system/SystemStore.php

@@ -0,0 +1,97 @@
+<?php
+
+namespace app\admin\controller\system;
+
+use app\admin\controller\AuthController;
+use app\admin\model\system\SystemConfig;
+use crmeb\services\JsonService;
+use crmeb\services\SystemConfigService;
+use app\admin\model\system\SystemStore as SystemStoreModel;
+use crmeb\services\UtilService;
+
+/**
+ * 门店管理控制器
+ * Class SystemAttachment
+ * @package app\admin\controller\system
+ *
+ */
+class SystemStore extends AuthController
+{
+
+    /*
+     * 门店设置
+     * */
+    public function index()
+    {
+        $store = SystemStoreModel::getStoreDispose();
+        $this->assign(compact('store'));
+        return $this->fetch();
+    }
+
+    /*
+     * 位置选择
+     * */
+    public function select_address()
+    {
+        $key = SystemConfigService::get('tengxun_map_key');
+        if(!$key) return $this->failed('请前往设置->系统设置->物流配置 配置腾讯地图KEY','#');
+        $this->assign(compact('key'));
+        return $this->fetch();
+    }
+
+    /*
+     * 保存修改门店信息
+     * param int $id
+     * */
+    public function save($id = 0)
+    {
+        $data = UtilService::postMore([
+            ['name',''],
+            ['introduction',''],
+            ['image',''],
+            ['phone',''],
+            ['address',''],
+            ['detailed_address',''],
+            ['latlng',''],
+            ['valid_time',[]],
+            ['day_time',[]],
+        ]);
+        SystemStoreModel::beginTrans();
+        try{
+            $data['address'] = implode(',',$data['address']);
+            $data['latlng'] = explode(',',$data['latlng']);
+            if(!isset($data['latlng'][0]) || !isset($data['latlng'][1])) return JsonService::fail('请选择门店位置');
+            $data['latitude'] = $data['latlng'][0];
+            $data['longitude'] = $data['latlng'][1];
+            $data['valid_time'] = implode(' - ',$data['valid_time']);
+            $data['day_time'] = implode(' - ',$data['day_time']);
+            unset($data['latlng']);
+            if($data['image'] && strstr($data['image'],'http') === false){
+                $site_url = SystemConfig::getConfigValue('site_url');
+                $data['image'] = $site_url.$data['image'];
+            }
+            if($id){
+                if(SystemStoreModel::where('id',$id)->update($data)){
+                    SystemStoreModel::commitTrans();
+                    return JsonService::success('修改成功');
+                }else{
+                    SystemStoreModel::rollbackTrans();
+                    return JsonService::fail('修改失败或者您没有修改什么!');
+                }
+            }else{
+                $data['add_time'] = time();
+                $data['is_show'] = 1;
+                if($res=SystemStoreModel::create($data)){
+                    SystemStoreModel::commitTrans();
+                    return JsonService::success('保存成功',['id'=>$res->id]);
+                }else{
+                    SystemStoreModel::rollbackTrans();
+                    return JsonService::fail('保存失败!');
+                }
+            }
+        }catch (\Exception $e){
+            SystemStoreModel::rollbackTrans();
+            return JsonService::fail($e->getMessage());
+        }
+    }
+}

+ 1 - 1
crmeb/app/admin/controller/ump/StoreSeckill.php

@@ -191,7 +191,7 @@ class StoreSeckill extends AuthController
      */
     public function upload()
     {
-        $res = Upload::image('file','store/product/'.date('Ymd'));
+        $res = Upload::getInstance()->setUploadPath('store/product/'.date('Ymd'))->image('file');
         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'])]);

+ 1 - 1
crmeb/app/admin/controller/user/UserLevel.php

@@ -262,7 +262,7 @@ class UserLevel extends AuthController
             ['illustrate',''],
         ]);
         if(!$data['task_type']) return JsonService::fail('请选择任务类型');
-        if($data['number'] < 0) return JsonService::fail('请输入限定数量');
+        if($data['number'] < 1) return JsonService::fail('请输入限定数量,数量不能小于1');
         $tash=SystemUserTask::getTaskType($data['task_type']);
         if($tash['max_number']!=0 && $data['number'] > $tash['max_number']) return JsonService::fail('您设置的限定数量超出最大限制,最大限制为:'.$tash['max_number']);
         $data['name']=SystemUserTask::setTaskName($data['task_type'],$data['number']);

+ 3 - 3
crmeb/app/admin/controller/wechat/Reply.php

@@ -82,7 +82,8 @@ class Reply extends AuthController
     {
         $name = $this->request->post('file');
         if(!$name) return Json::fail('请上传图片');
-        $res = Upload::image($name,'wechat/image',true,true,null,'uniqid',1);
+        $res = Upload::getInstance()->setUploadType(1)->setUploadPath('wechat/image')
+            ->setAutoValidate(true)->image($name);
         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']);
@@ -92,8 +93,7 @@ class Reply extends AuthController
     {
         $name = $this->request->post('file');
         if(!$name) return Json::fail('请上传声音');
-        $autoValidate['size'] = 2097152;
-        $res = Upload::file($name,'wechat/voice',true,$autoValidate);
+        $res = Upload::getInstance()->setUploadPath('wechat/voice')->setAutoValidate(true)->file($name);
         return $res->status === true ? Json::successful('上传成功',$res->filePath) : Json::fail($res->error);
     }
 

+ 1 - 1
crmeb/app/admin/controller/wechat/StoreService.php

@@ -136,7 +136,7 @@ class StoreService extends AuthController
      */
     public function upload()
     {
-        $res = Upload::image('file','store/product/'.date('Ymd'));
+        $res = Upload::getInstance()->setUploadPath('store/product/'.date('Ymd'))->image('file');
         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'])]);

+ 4 - 4
crmeb/app/admin/controller/wechat/WechatUser.php

@@ -249,11 +249,11 @@ class WechatUser extends AuthController
     public function group($refresh = 0)
     {
         $list=[];
-        if($refresh == 1) {
-            UserModel::clearUserGroup();
-            $this->redirect(Url::buildUrl('group'));
-        }
         try{
+            if($refresh == 1) {
+                UserModel::clearUserGroup();
+                $this->redirect(Url::buildUrl('group'));
+            }
             $list = UserModel::getUserGroup();
         }catch (\Exception $e){}
         $this->assign(compact('list'));

+ 2 - 1
crmeb/app/admin/controller/widget/Images.php

@@ -71,7 +71,8 @@ class Images extends AuthController
         $upload_type = $this->request->get('upload_type',0);
         try{
             $path = make_path('attach');
-            $res = Upload::image('file',$path,true,true,null,'uniqid',$upload_type);
+            $res = Upload::getInstance()->setUploadPath($path)->setAutoValidate(true)
+                ->setUploadType($upload_type)->image('file');
             if(is_object($res) && $res->status === false){
                 $info = array(
                     'code' =>400,

+ 6 - 0
crmeb/app/admin/model/article/Article.php

@@ -12,6 +12,7 @@
 
 namespace app\admin\model\article;
 
+use app\admin\model\store\StoreProduct;
 use app\admin\model\system\SystemAdmin;
 use crmeb\traits\ModelTrait;
 use crmeb\basic\BaseModel;
@@ -30,6 +31,10 @@ class Article extends BaseModel {
 
     protected $name = 'article';
 
+    public function profile()
+    {
+        return $this->hasOne(StoreProduct::class,'id','product_id')->field('store_name');
+    }
     /**
      * 获取配置分类
      * @param array $where
@@ -53,6 +58,7 @@ class Article extends BaseModel {
             else $item['admin_name'] = Merchant::where('id',$item['mer_id'])->value('mer_name').'---》'.MerchantAdmin::where('id',$item['admin_id'])->value('real_name');
             $item['content'] = Db::name('ArticleContent')->where('nid',$item['id'])->value('content');
             $item['catename'] = Db::name('ArticleCategory')->where('id',$item['cid'])->value('title');
+            $item['store_name'] = $item->profile->store_name ?? '';
         },$where);
     }
 

+ 35 - 19
crmeb/app/admin/model/order/StoreOrder.php

@@ -46,13 +46,14 @@ class StoreOrder extends BaseModel
 
     public static function orderCount(){
         $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['wf']=self::statusByWhere(1,new self())->where(['is_system_del'=>0,'shipping_type'=>1])->count();
+        $data['ds']=self::statusByWhere(2,new self())->where(['is_system_del'=>0,'shipping_type'=>1])->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['write_off'] =self::statusByWhere(5,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();
@@ -61,7 +62,7 @@ class StoreOrder extends BaseModel
     }
 
     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,r.phone');
+        $model = self::getOrderWhere($where,self::alias('a')->join('user r','r.uid=a.uid','LEFT'),'a.','r')->field('a.*,r.nickname,r.phone,r.spread_uid');
         if($where['order']!=''){
             $model = $model->order(self::setOrder($where['order']));
         }else{
@@ -72,14 +73,18 @@ class StoreOrder extends BaseModel
         }else{
             $data=($data=$model->page((int)$where['page'],(int)$where['limit'])->select()) && count($data) ? $data->toArray() : [];
         }
-//        $data=($data=$model->page((int)$where['page'],(int)$where['limit'])->select()) && count($data) ? $data->toArray() : [];
+
         foreach ($data as &$item){
             $_info = Db::name('store_order_cart_info')->where('oid',$item['id'])->field('cart_info')->select();
             $_info = count($_info) ? $_info->toArray() : [];
             foreach ($_info as $k=>$v){
-                $_info[$k]['cart_info'] = json_decode($v['cart_info'],true);
+                $cart_info = json_decode($v['cart_info'],true);
+                if(!isset($cart_info['productInfo'])) $cart_info['productInfo']=[];
+                $_info[$k]['cart_info'] = $cart_info;
+                unset($cart_info);
             }
             $item['_info'] = $_info;
+            $item['spread_nickname'] = Db::name('user')->where('uid',$item['spread_uid'])->value('nickname');
             $item['add_time'] = date('Y-m-d H:i:s',$item['add_time']);
             if($item['pink_id'] || $item['combination_id']){
                 $pinkStatus = StorePink::where('order_id_key',$item['id'])->value('status');
@@ -108,8 +113,13 @@ class StoreOrder extends BaseModel
                 $item['pink_name'] = '[砍价订单]';
                 $item['color'] = '#12c5e9';
             }else{
-                $item['pink_name'] = '[普通订单]';
-                $item['color'] = '#895612';
+                if($item['shipping_type']==1){
+                    $item['pink_name'] = '[普通订单]';
+                    $item['color'] = '#895612';
+                }else if($item['shipping_type']==2){
+                    $item['pink_name'] = '[核销订单]';
+                    $item['color'] = '#8956E8';
+                }
             }
             if($item['paid']==1){
                 switch ($item['pay_type']){
@@ -139,10 +149,14 @@ class StoreOrder extends BaseModel
             }
             if($item['paid']==0 && $item['status']==0){
                 $item['status_name']='未支付';
-            }else if($item['paid']==1 && $item['status']==0 && $item['refund_status']==0){
+            }else if($item['paid']==1 && $item['status']==0 && $item['shipping_type']==1 && $item['refund_status']==0){
                 $item['status_name']='未发货';
-            }else if($item['paid']==1 && $item['status']==1 && $item['refund_status']==0){
+            }else if($item['paid']==1 && $item['status']==0 && $item['shipping_type']==2 && $item['refund_status']==0){
+                $item['status_name']='未核销';
+            }else if($item['paid']==1 && $item['status']==1 && $item['shipping_type']==1 && $item['refund_status']==0){
                 $item['status_name']='待收货';
+            }else if($item['paid']==1 && $item['status']==1 && $item['shipping_type']==2 && $item['refund_status']==0){
+                $item['status_name']='未核销';
             }else if($item['paid']==1 && $item['status']==2 && $item['refund_status']==0){
                 $item['status_name']='待评价';
             }else if($item['paid']==1 && $item['status']==3 && $item['refund_status']==0){
@@ -342,21 +356,23 @@ HTML;
         else if($status == 8)
             return $model;
         else if($status == 0)//未支付
-            return $model->where($alert.'paid',0)->where($alert.'status',0)->where($alert.'refund_status',0);
+            return $model->where($alert.'paid',0)->where($alert.'status',0)->where($alert.'refund_status',0)->where($alert.'is_del',0);
         else if($status == 1)//已支付 未发货
-            return $model->where($alert.'paid',1)->where($alert.'status',0)->where($alert.'refund_status',0);
+            return $model->where($alert.'paid',1)->where($alert.'status',0)->where($alert.'shipping_type',1)->where($alert.'refund_status',0)->where($alert.'is_del',0);
         else if($status == 2)//已支付  待收货
-            return $model->where($alert.'paid',1)->where($alert.'status',1)->where($alert.'refund_status',0);
+            return $model->where($alert.'paid',1)->where($alert.'status',1)->where($alert.'shipping_type',1)->where($alert.'refund_status',0)->where($alert.'is_del',0);
+        else if($status == 5)//已支付  待核销
+            return $model->where($alert.'paid',1)->where($alert.'status',0)->where($alert.'shipping_type',2)->where($alert.'refund_status',0)->where($alert.'is_del',0);
         else if($status == 3)// 已支付  已收货  待评价
-            return $model->where($alert.'paid',1)->where($alert.'status',2)->where($alert.'refund_status',0);
+            return $model->where($alert.'paid',1)->where($alert.'status',2)->where($alert.'refund_status',0)->where($alert.'is_del',0);
         else if($status == 4)// 交易完成
-            return $model->where($alert.'paid',1)->where($alert.'status',3)->where($alert.'refund_status',0);
+            return $model->where($alert.'paid',1)->where($alert.'status',3)->where($alert.'refund_status',0)->where($alert.'is_del',0);
         else if($status == -1)//退款中
-            return $model->where($alert.'paid',1)->where($alert.'refund_status',1);
+            return $model->where($alert.'paid',1)->where($alert.'refund_status',1)->where($alert.'is_del',0);
         else if($status == -2)//已退款
-            return $model->where($alert.'paid',1)->where($alert.'refund_status',2);
+            return $model->where($alert.'paid',1)->where($alert.'refund_status',2)->where($alert.'is_del',0);
         else if($status == -3)//退款
-            return $model->where($alert.'paid',1)->where($alert.'refund_status','in','1,2');
+            return $model->where($alert.'paid',1)->where($alert.'refund_status','in','1,2')->where($alert.'is_del',0);
         else if($status == -4)//已删除
             return $model->where($alert.'is_del',1);
         else
@@ -406,7 +422,7 @@ HTML;
             'keyword2'=>$order['pay_price'],
             'keyword3'=>date('Y-m-d H:i:s',$order['add_time']),
             'remark'=>'点击查看订单详情'
-        ],Url::buildUrl('wap/My/order',['uni'=>$order['order_id']],true,true));
+        ],Url::buildUrl('/order/detail/'.$order['order_id'])->suffix('')->domain(true)->build());
     }
 
     /**
@@ -1048,7 +1064,7 @@ HTML;
     {
 
         $order = self::where('id',$oid)->find();
-        $url = Url::buildUrl('wap/My/order',['uni'=>$order['order_id']],true,true);
+        $url = Url::buildUrl('/order/detail/'.$order['order_id'])->suffix('')->domain(true)->build();
         $group = [
             'first'=>'亲,您的订单已发货,请注意查收',
             'remark'=>'点击查看订单详情'

+ 2 - 1
crmeb/app/admin/model/store/StoreProductAttr.php

@@ -91,7 +91,8 @@ class StoreProductAttr extends BaseModel
                 'cost'=>$value['cost'],
                 'stock'=>$value['sales'],
                 'unique'=> StoreProductAttrValue::uniqueId($productId.$suk.uniqid(true)),
-                'image'=>$value['pic']
+                'image'=>$value['pic'],
+                'bar_code'=>$value['bar_code'] ?? '',
             ];
         }
         if(!count($attrGroup) || !count($valueGroup)) return self::setErrorInfo('请设置至少一个属性!');

+ 5 - 2
crmeb/app/admin/model/store/StoreProductAttrValue.php

@@ -57,7 +57,9 @@ class StoreProductAttrValue extends BaseModel
             $stock = self::where('product_id',$productId)->where('unique',$unique)->value('stock');
             $replenishment_num = SystemConfigService::get('store_stock') ?? 0;//库存预警界限
             if($replenishment_num >= $stock){
-                ChannelService::instance()->send('STORE_STOCK', ['id'=>$productId]);
+                try{
+                    ChannelService::instance()->send('STORE_STOCK', ['id'=>$productId]);
+                }catch (\Exception $e){}
             }
         }
         return $res;
@@ -89,7 +91,7 @@ class StoreProductAttrValue extends BaseModel
             $detail = $item['detail'];
             sort($item['detail'],SORT_STRING);
             $suk =  implode(',', $item['detail']);
-            $sukValue = self::where('product_id', $productId)->where('suk', $suk)->column('cost,price,stock as sales,image as pic','suk');
+            $sukValue = self::where('product_id', $productId)->where('suk', $suk)->column('bar_code,cost,price,stock as sales,image as pic','suk');
             if(!count($sukValue)){
                 unset($value[$key]);
             }else{
@@ -98,6 +100,7 @@ class StoreProductAttrValue extends BaseModel
                 $valueNew[$count]['price'] = $sukValue[$suk]['price'];
                 $valueNew[$count]['sales'] = $sukValue[$suk]['sales'];
                 $valueNew[$count]['pic'] = $sukValue[$suk]['pic'];
+                $valueNew[$count]['bar_code'] = $sukValue[$suk]['bar_code'];
                 $valueNew[$count]['check'] = false;
                 $count++;
             }

+ 18 - 1
crmeb/app/admin/model/system/SystemAttachment.php

@@ -117,6 +117,23 @@ class SystemAttachment extends BaseModel
      */
     public static function emptyYesterdayAttachment()
     {
-        return self::whereTime('time','yesterday')->where(['module_type'=>2])->delete();
+        self::beginTrans();
+        try{
+            $list = self::whereTime('time','yesterday')->where(['module_type'=>2])->column('att_dir','att_id');
+            foreach ($list as $att_id => $att_dir){
+                if($att_dir && strstr($att_dir,'uploads') !== false){
+                    if(strstr($att_dir,'http') === false)
+                        @unlink(substr($att_dir,1));
+                    else{
+                        $filedir = substr($att_dir,strpos($att_dir, 'uploads'));
+                        @unlink($filedir);
+                    }
+                }
+                self::del($att_id);
+            }
+            self::commitTrans();
+        }catch (\Exception $e){
+            self::rollbackTrans();
+        }
     }
 }

+ 66 - 0
crmeb/app/admin/model/system/SystemStore.php

@@ -0,0 +1,66 @@
+<?php
+
+
+namespace app\admin\model\system;
+
+use crmeb\traits\ModelTrait;
+use crmeb\basic\BaseModel;
+
+/**
+ * 门店自提 model
+ * Class SystemStore
+ * @package app\admin\model\system
+ */
+class SystemStore extends BaseModel
+{
+    use ModelTrait;
+
+    /**
+     * 数据表主键
+     * @var string
+     */
+    protected $pk = 'id';
+
+    /**
+     * 模型名称
+     * @var string
+     */
+    protected $name = 'system_store';
+
+
+    public static function getLatlngAttr($value,$data)
+    {
+        return $data['latitude'].','.$data['longitude'];
+    }
+
+    public static function verificWhere()
+    {
+        return self::where('is_show',1)->where('is_del',0);
+    }
+    /*
+     * 获取门店信息
+     * @param int $id
+     * */
+    public static function getStoreDispose($id = 0)
+    {
+        if($id)
+            $storeInfo = self::verificWhere()->where('id',$id)->find();
+        else
+            $storeInfo = self::verificWhere()->find();
+        if($storeInfo) {
+            $storeInfo['latlng'] = self::getLatlngAttr(null, $storeInfo);
+            $storeInfo['valid_time'] = $storeInfo['valid_time'] ? explode(' - ', $storeInfo['valid_time']) : [];
+            $storeInfo['day_time'] = $storeInfo['day_time'] ? explode(' - ', $storeInfo['day_time']) : [];
+            $storeInfo['address'] = $storeInfo['address'] ? explode(',', $storeInfo['address']) : [];
+        }else{
+            $storeInfo['latlng'] =[];
+            $storeInfo['valid_time']=[];
+            $storeInfo['valid_time']=[];
+            $storeInfo['day_time']=[];
+            $storeInfo['address']=[];
+            $storeInfo['id']=0;
+        }
+        return $storeInfo;
+    }
+
+}

+ 1 - 1
crmeb/app/admin/model/ump/StoreCombination.php

@@ -181,7 +181,7 @@ class StoreCombination extends BaseModel
         $model = $model->where('c.is_del',0);
         $model = $model->where('c.id',$id);
         $model = $model->where('c.start_time','<',time());
-        $model = $model->where('c.stop_time','>',time()-86400);
+        $model = $model->where('c.stop_time','>',time() - 'c.effective_time');
         $list = $model->find();
         if($list) return $list->toArray();
         else return [];

+ 2 - 2
crmeb/app/admin/model/user/User.php

@@ -503,7 +503,7 @@ class User extends BaseModel
                 ]
             ]
         ];
-       return compact('shop_data','shop_xdata','fenbu_data','fenbu_xdata','seriesdata','xdata','Zoom');
+       return compact('shop_data','shop_xdata','seriesdata','Zoom');
     }
     //获取$date的前一天或者其他的时间段
     public static function getOldDate($where,$moedls=null){
@@ -687,7 +687,7 @@ class User extends BaseModel
             ],
             [
                 'title'=>'本月消费金额',
-                'value'=>StoreOrder::where('uid',$uid)->whereTime('add_time','month')->sum('total_price'),
+                'value'=>StoreOrder::where('uid',$uid)->where('paid',1)->whereTime('add_time','month')->sum('total_price'),
                 'key'=>'元',
                 'class'=>'',
             ]

+ 2 - 2
crmeb/app/admin/model/user/UserExtract.php

@@ -110,7 +110,7 @@ class UserExtract extends BaseModel
                 'keyword2'=>date('Y-m-d H:i:s',time()),
                 'keyword3'=>$extract_number,
                 'remark'=>'错误原因:'.$fail_msg
-            ],Url::buildUrl('wap/my/user_pro',[],true,true));
+            ],Url::buildUrl('/user/cashrecord')->suffix('')->domain(true)->build());
         }else if(strtolower($User['user_type'])=='routine'){
             RoutineTemplate::sendOut('USER_EXTRACT_FALSE',$uid,[
                 'keyword1'=>$fail_msg,
@@ -156,7 +156,7 @@ class UserExtract extends BaseModel
                     'keyword2' => date('Y-m-d H:i:s', time()),
                     'keyword3' => $extractNumber,
                     'remark' => '点击查看我的佣金明细'
-                ], Url::buildUrl('wap/my/user_pro', [], true, true));
+                ], Url::buildUrl('/user/cashrecord')->suffix('')->domain(true)->build());
             }
         }
         return self::edit(['status'=>1],$id);

+ 2 - 1
crmeb/app/admin/model/wechat/WechatUser.php

@@ -738,7 +738,8 @@ use app\admin\model\order\StoreOrderStatus;
 
      public static function clearUserGroup()
      {
-         Cache::rm('_wechat_group');
+
+         Cache::deleteItem('_wechat_group');
      }
 
      /**

+ 1 - 1
crmeb/app/admin/view/article/article/create.php

@@ -19,7 +19,7 @@
 {block name="content"}
 <div class="row">
    <div class="col-sm-12 panel panel-default" >
-       <div class="panel-body">
+       <div class="panel-body" style="padding: 30px">
            <form class="form-horizontal" id="signupForm">
                <div class="form-group">
                    <div class="col-md-12">

+ 29 - 5
crmeb/app/admin/view/article/article/index.php

@@ -43,8 +43,9 @@
                         <th class="text-center" width="10%">图片</th>
                         <th class="text-left" >[分类]标题</th>
                         <th class="text-center" width="8%">浏览量</th>
+                        <th class="text-center">关联标题</th>
                         <th class="text-center" width="15%">添加时间</th>
-                        <th class="text-center" width="15%">操作</th>
+                        <th class="text-center" width="20%">操作</th>
                     </tr>
                     </thead>
                     <tbody>
@@ -56,13 +57,17 @@
                         </td>
                         <td>[{$vo.catename}]{$vo.title}</td>
                         <td>{$vo.visit}</td>
+                        <td>{$vo.store_name}</td>
                         <td>{$vo.add_time|date="Y-m-d H:i:s"}</td>
 
                         <td class="text-center">
-                            <button class="btn btn-info btn-xs" type="button"  onclick="$eb.createModalFrame('编辑','{:Url('create',array('id'=>$vo['id'],'cid'=>$where.cid))}',{w:1100,h:760})"><i class="fa fa-paste"></i> 编辑</button>
-
-                            <button class="btn btn-warning btn-xs del_news_one" data-id="{$vo.id}" type="button" data-url="{:Url('delete',array('id'=>$vo['id']))}" ><i class="fa fa-warning"></i> 删除
-
+                            <button style="margin-top: 5px;" class="btn btn-info btn-xs" type="button"  onclick="$eb.createModalFrame('编辑','{:Url('create',array('id'=>$vo['id'],'cid'=>$where.cid))}',{w:1100,h:760})"><i class="fa fa-paste"></i> 编辑</button>
+                            {if $vo.product_id}
+                            <button style="margin-top: 5px;" class="btn btn-warning btn-xs underline" data-id="{$vo.id}" type="button" data-url="{:Url('unrelation',array('id'=>$vo['id']))}" ><i class="fa fa-warning"></i> 取消关联</button>
+                            {else}
+                            <button style="margin-top: 5px;" class="btn btn-warning btn-xs openWindow" data-id="{$vo.id}" type="button" data-url="{:Url('relation',array('id'=>$vo['id']))}" ><i class="fa fa-warning"></i> 关联</button>
+                            {/if}
+                            <button  style="margin-top: 5px;" class="btn btn-warning btn-xs del_news_one" data-id="{$vo.id}" type="button" data-url="{:Url('delete',array('id'=>$vo['id']))}" ><i class="fa fa-warning"></i> 删除</button>
                         </td>
                     </tr>
                     {/volist}
@@ -97,5 +102,24 @@
             });
         })
     });
+
+    $('.openWindow').on('click',function () {
+        return $eb.createModalFrame('选择产品',$(this).data('url'));
+    });
+
+    $('.underline').on('click',function () {
+        var url=$(this).data('url');
+        $eb.$swal('delete',function(){
+            $eb.axios.get(url).then(function(res){
+                if(res.status == 200 && res.data.code == 200) {
+                    $eb.$swal('success',res.data.msg);
+                    window.location.reload();
+                }else
+                    return Promise.reject(res.data.msg || '取消失败')
+            }).catch(function(err){
+                $eb.$swal('error',err);
+            });
+        },{title:'确认取消关联产品?',text:'取消后可再关联页选择产品重新关联',confirm:'确定'})
+    })
 </script>
 {/block}

+ 83 - 0
crmeb/app/admin/view/article/article/relation.php

@@ -0,0 +1,83 @@
+{extend name="public/container"}
+{block name="content"}
+<div class="layui-fluid">
+    <div class="layui-row layui-col-space15"  id="app">
+        <div class="layui-col-md12">
+            <div class="layui-card">
+                <div class="layui-card-header">搜索条件</div>
+                <div class="layui-card-body">
+                    <form class="layui-form layui-form-pane" action="">
+                        <div class="layui-inline">
+                            <label class="layui-form-label">产品名称</label>
+                            <div class="layui-input-block">
+                                <input type="text" name="store_name" class="layui-input" placeholder="请输入产品名称,关键字,编号">
+                            </div>
+                        </div>
+                        <div class="layui-inline">
+                            <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>
+                            </div>
+                        </div>
+                    </form>
+                </div>
+            </div>
+        </div>
+        <div class="layui-col-md12">
+            <div class="layui-card">
+                <div class="layui-card-body">
+                    <table class="layui-hide" id="List" lay-filter="List"></table>
+                    <!--图片-->
+                    <script type="text/html" id="image">
+                        <img style="cursor: pointer" lay-event="open_image" src="{{d.image}}">
+                    </script>
+                    <!--操作-->
+                    <script type="text/html" id="act">
+                        <button type="button" class="layui-btn layui-btn-normal layui-btn-sm" lay-event='select'>选择</button>
+                    </script>
+                </div>
+            </div>
+        </div>
+    </div>
+</div>
+<script src="{__ADMIN_PATH}js/layuiList.js"></script>
+{/block}
+{block name='script'}
+<script>
+    var id='{$id}';
+    layList.form.render();
+    //加载列表
+    layList.tableList('List',"{:Url('store.store_product/product_ist',['type'=>1])}",function (){
+        return [
+            {field: 'id', title: 'ID', sort: true,event:'id'},
+            {field: 'image', title: '产品图片',templet:'#image'},
+            {field: 'store_name', title: '产品名称',templet:'#store_name'},
+            {field: 'right', title: '操作',align:'center',toolbar:'#act'},
+        ]
+    });
+    //点击事件绑定
+    layList.tool(function (event,data,obj) {
+        switch (event) {
+            case 'select':
+                $eb.$swal('delete',function(){
+                    $eb.axios.post(layList.U({a:'edit_article',q:{id:id}}),{product_id:data.id}).then(function(res){
+                        if(res.status == 200 && res.data.code == 200) {
+                            $eb.$swal('success',res.data.msg);
+                            var index = parent.layer.getFrameIndex(window.name);
+                            parent.layer.close(index);
+                            parent.$(".J_iframe:visible")[0].contentWindow.location.reload();
+                        }else
+                            return Promise.reject(res.data.msg || '关联失败')
+                    }).catch(function(err){
+                        $eb.$swal('error',err);
+                    });
+                },{title:'确定选择此产品?',text:'关联后可在文章列表取消',confirm:'确认'})
+                break;
+        }
+    })
+    //查询
+    layList.search('search',function(where){
+        layList.reload(where);
+    });
+</script>
+{/block}

+ 1 - 1
crmeb/app/admin/view/login/index.php

@@ -3,7 +3,7 @@
 <head>
     <meta charset="utf-8">
     <meta name="viewport" content="width=device-width, initial-scale=1.0">
-    <meta name="renderer" content="webkit">
+    <meta name="robots" content="noindex,nofollow" />
     <title>登录管理系统 -  Powered by CRMEB!</title>
     <meta name="generator" content="CRMEB! v2.5" />
     <meta name="author" content="CRMEB! Team and CRMEB UI Team" />

+ 16 - 1
crmeb/app/admin/view/order/store_order/index.php

@@ -91,6 +91,7 @@
                 <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>
+                        <button class="layui-btn layui-btn-sm layui-btn-warm" data-type="write_order">订单核销</button>
                     </div>
                     <table class="layui-hide" id="List" lay-filter="List"></table>
                     <!--订单-->
@@ -103,6 +104,12 @@
                     <script type="text/html" id="userinfo">
                         {{d.nickname==null ? '暂无信息':d.nickname}}/{{d.uid}}
                     </script>
+                    <!--分销员信息-->
+                    <script type="text/html" id="spread_uid">
+                        {{# if(d.spread_uid != 0){ }}
+                        <button class="btn btn-default btn-xs btn-outline" type="button" onclick="$eb.createModalFrame('推荐人信息','{:Url('order_spread_user')}?uid={{d.spread_uid}}',{w:600,h:400})">{{d.spread_nickname}}</button>
+                        {{# }else{ }}无{{# } }}
+                    </script>
                     <!--支付状态-->
                     <script type="text/html" id="paid">
                         {{#  if(d.pay_type==1){ }}
@@ -169,8 +176,10 @@
                             </li>
                         </ul>
                         {{#  }else if(d._status==2){ }}
+                        {{# if(d.shipping_type==1){ }}
                         <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>
@@ -367,6 +376,7 @@
             {type:'checkbox'},
             {field: 'order_id', title: '订单号', sort: true,event:'order_id',width:'14%',templet:'#order_id'},
             {field: 'nickname', title: '用户信息',templet:'#userinfo',width:'10%',align:'center'},
+            {field: 'spread_uid', title: '推荐人信息',templet:'#spread_uid',width:'10%',align:'center'},
             {field: 'info', title: '商品信息',templet:"#info",height: 'full-20'},
             {field: 'pay_price', title: '实际支付',width:'8%',align:'center'},
             {field: 'paid', title: '支付状态',templet:'#paid',width:'8%',align:'center'},
@@ -449,7 +459,10 @@
             }else{
                 layList.msg('请选择要删除的订单');
             }
-        }
+        },
+        write_order:function () {
+            return $eb.createModalFrame('订单核销',layList.U({a:'write_order'}),{w:500,h:400});
+        },
     };
     $('#container-action').find('button').each(function () {
         $(this).on('click',function(){
@@ -513,6 +526,7 @@
                     {name: '未支付', value: 0,count:orderCount.wz},
                     {name: '未发货', value: 1,count:orderCount.wf,class:true},
                     {name: '待收货', value: 2,count:orderCount.ds},
+                    {name: '待核销', value: 5,count:orderCount.write_off},
                     {name: '待评价', value: 3,count:orderCount.dp},
                     {name: '交易完成', value: 4,count:orderCount.jy},
                     {name: '退款中', value: -1,count:orderCount.tk,class:true},
@@ -590,6 +604,7 @@
             mounted:function () {
                 var that=this;
                 that.getBadge();
+                window.formReload = this.search;
                 layList.laydate.render({
                     elem:this.$refs.date_time,
                     trigger:'click',

+ 4 - 2
crmeb/app/admin/view/order/store_order/order_info.php

@@ -29,9 +29,11 @@
                         <div class="col-xs-6" style="color: #8BC34A;">订单状态:
                             {if condition="$orderInfo['paid'] eq 0 && $orderInfo['status'] eq 0"}
                             未支付
-                            {elseif condition="$orderInfo['paid'] eq 1 && $orderInfo['status'] eq 0 && $orderInfo['refund_status'] eq 0"/}
+                            {elseif condition="$orderInfo['paid'] eq 1 && $orderInfo['shipping_type'] eq 1 && $orderInfo['status'] eq 0 && $orderInfo['refund_status'] eq 0"/}
                             未发货
-                            {elseif condition="$orderInfo['paid'] eq 1 && $orderInfo['status'] eq 1 && $orderInfo['refund_status'] eq 0"/}
+                            {elseif condition="$orderInfo['paid'] eq 1 && $orderInfo['shipping_type'] eq 2 && $orderInfo['status'] eq 0 && $orderInfo['refund_status'] eq 0"/}
+                            待核销
+                            {elseif condition="$orderInfo['paid'] eq 1 && $orderInfo['shipping_type'] eq 1 && $orderInfo['status'] eq 1 && $orderInfo['refund_status'] eq 0"/}
                             待收货
                             {elseif condition="$orderInfo['paid'] eq 1 && $orderInfo['status'] eq 2 && $orderInfo['refund_status'] eq 0"/}
                             待评价

+ 88 - 0
crmeb/app/admin/view/order/store_order/write_order.php

@@ -0,0 +1,88 @@
+{extend name="public/container"}
+{block name="content"}
+<div class="layui-fluid">
+    <div class="layui-row layui-col-space15"  id="app">
+        <!--搜索条件-->
+        <div class="layui-col-md12" v-cloak="">
+            <div class="layui-card">
+                <div class="layui-card-body">
+                    <div class="layui-form-item" style="padding-top: 20px;">
+                        <input style="height: 50px;line-height: 1.5;display: inline;width: 80%;" v-model="verify_code" type="text" name="title" lay-verify="title" autocomplete="off" placeholder="请输入核销码" class="layui-input">
+                        <button style="height: 50px;border-radius: 15px;" type="button" class="layui-btn layui-btn-normal" @click="verify">验证</button>
+                    </div>
+                    <fieldset class="layui-elem-field" v-if="orderInfo.uid">
+                        <legend>订单信息</legend>
+                        <div class="layui-field-box">
+                            <div class="layui-form">
+                                <table class="layui-table">
+                                    <tbody>
+                                        <tr>
+                                            <td>订 单 号</td>
+                                            <td>{{orderInfo.order_id}}</td>
+                                        </tr>
+                                        <tr>
+                                            <td>购买金额</td>
+                                            <td>{{orderInfo.pay_price}}</td>
+                                        </tr>
+                                        <tr>
+                                            <td>购买用户</td>
+                                            <td>{{orderInfo.nickname}}</td>
+                                        </tr>
+                                    </tbody>
+                                </table>
+                            </div>
+                        </div>
+                    </fieldset>
+                    <div class="layui-form-item" style="padding-top: 50px;text-align: center;padding-bottom: 30px;">
+                        <button type="button" class="layui-btn layui-btn-normal" @click="confirm">立即核销</button>
+                    </div>
+                </div>
+            </div>
+        </div>
+    </div>
+</div>
+<script src="{__ADMIN_PATH}js/layuiList.js"></script>
+{/block}
+{block name='script'}
+<script>
+    require(['vue'],function(Vue) {
+        new Vue({
+            el: "#app",
+            data: {
+                verify_code:'',
+                orderInfo:{},
+                is_confirm:false,
+            },
+            methods:{
+                verify:function(){
+                    var that = this;
+                    var reg = /[0-9]{12}/;
+                    if(!this.verify_code) return layList.msg('请填写核销码!');
+                    if(!reg.test(this.verify_code)) return layList.msg('请填写正确的核销码!');
+                    layList.baseGet(layList.U({a:'write_order',q:{verify_code:this.verify_code,is_confirm:0}}),function (res) {
+                        that.orderInfo = res.data;
+                        that.is_confirm = true;
+                    },function (res) {
+                        layList.msg(res.msg);
+                    });
+                },
+                confirm:function () {
+                    var that = this;
+                    if(that.is_confirm === false) return layList.msg('请先验证订单!');
+                    layList.baseGet(layList.U({a:'write_order',q:{verify_code:that.verify_code,is_confirm:1}}),function (res) {
+                        layList.msg(res.msg,function () {
+                            parent.$(".J_iframe:visible")[0].contentWindow.formReload();
+                            parent.layer.close(parent.layer.getFrameIndex(window.name));
+                        });
+                    },function (res) {
+                        layList.msg(res.msg);
+                    });
+                }
+            },
+            mounted:function () {
+
+            }
+        })
+    })
+</script>
+{/block}

+ 0 - 1
crmeb/app/admin/view/record/record/chart_combination.php

@@ -296,7 +296,6 @@
                 this.info();
                 this.getSalesList();
                 this.getProfityList();
-                this.getLackList();
                 this.getTuiPriesList();
                 layList.laydate.render({
                     elem:this.$refs.date_time,

+ 1 - 1
crmeb/app/admin/view/setting/system_config_tab/sonconfigtab.php

@@ -155,7 +155,7 @@
 
                             <td class="text-center">
 
-                                <button class="btn btn-info btn-xs" type="button"  onclick="$eb.createModalFrame('编辑','{:Url('setting.system_config/edit_cinfig',array('id'=>$vo['id']))}')"><i class="fa fa-paste"></i> 编辑</button>
+                                <button class="btn btn-info btn-xs" type="button"  onclick="$eb.createModalFrame('编辑','{:Url('setting.system_config/edit_config',array('id'=>$vo['id']))}')"><i class="fa fa-paste"></i> 编辑</button>
 
                                 <button class="btn btn-warning btn-xs del_config_tab" data-id="{$vo.id}" type="button" data-url="{:Url('setting.system_config/delete_cinfig',array('id'=>$vo['id']))}" ><i class="fa fa-warning"></i> 删除
 

+ 3 - 2
crmeb/app/admin/view/sms/sms_config/index.php

@@ -68,9 +68,10 @@
     new Vue({
         el : '#app'
     });
+    var $f;
     formCreate.formSuccess = function(form,$r){
         <?=$form->getSuccessScript()?>
-        $f.btn.loading(false)();
+        $f.btn.loading(false);
     };
 
     (function () {
@@ -91,7 +92,7 @@
                 if(_b) return ;
                 _b = true;
                 if (!el) el = document.getElementById('configboay');
-                var $f = formCreate.create(getRule(), {
+                $f = formCreate.create(getRule(), {
                     el: el,
                     form:<?=json_encode($form->getConfig('form'))?>,
                     row:<?=json_encode($form->getConfig('row'))?>,

+ 1 - 0
crmeb/app/admin/view/store/copy_taobao/index.php

@@ -27,6 +27,7 @@
             <div class="layui-card">
                 <div class="layui-card-body">
                     <blockquote class="layui-elem-quote layui-quote-nm">
+                        <p style="color: red">注意:当前采集方式为免费采集,受到淘宝店铺影响需要登陆才可以访问产品详情,可能会导致采集程序不稳定,都属于正常现象,尽情谅解,后期会开发出付费接口采集保证稳定采集!</p>
                         链接格式说明: 输入以http或https开头的淘宝、天猫、1688、京东的商品详情页网址,网址正确且商品信息存在时才能入库成功。生成的产品默认是没有上架的,请手动上架产品!轮播图选中的颜色是绿色边框的请注意
                     </blockquote>
                     <div class="layui-form-item">

+ 5 - 1
crmeb/app/admin/view/store/store_category/index.php

@@ -62,7 +62,11 @@
                     </div>
                     <table class="layui-hide" id="List" lay-filter="List"></table>
                     <script type="text/html" id="pic">
+                        {{# if(d.pic){ }}
                         <img style="cursor: pointer" lay-event='open_image' src="{{d.pic}}">
+                        {{# }else{ }}
+                        暂无图片
+                        {{# } }}
                     </script>
                     <script type="text/html" id="is_show">
                         <input type='checkbox' name='id' lay-skin='switch' value="{{d.id}}" lay-filter='is_show' lay-text='显|隐'  {{ d.is_show == 1 ? 'checked' : '' }}>
@@ -101,7 +105,7 @@
             {field: 'pid', title: '查看子分类',templet:'#pid',align:'center',width:'8%'},
             {field: 'pic', title: '分类图标',templet:'#pic',align:'center'},
             {field: 'sort', title: '排序',sort: true,event:'sort',edit:'sort',width:'8%',align:'center'},
-            {field: 'is_show', title: '状态',templet:'#is_show',width:'6%',align:'center'},
+            {field: 'is_show', title: '状态',templet:'#is_show',width:'10%',align:'center'},
             {field: 'right', title: '操作',align:'center',toolbar:'#act',width:'10%',align:'center'},
         ];
     });

+ 5 - 1
crmeb/app/admin/view/store/store_product/attr.php

@@ -116,10 +116,14 @@
                             <span :class="attr.check ? 'check':''">库存:</span>&nbsp;&nbsp;<i-Input placeholder="库存" v-model="attr.sales" style="width: 60%"
                                                                                                   :number="true"></i-Input>
                         </i-Col>
-                        <i-Col span="4">
+                        <i-Col span="6">
                             <span :class="attr.check ? 'check':''">成本价:</span>&nbsp;&nbsp;<i-Input placeholder="成本价" v-model="attr.cost" style="width: 60%"
                                                                                                    :number="true"></i-Input>
                         </i-Col>
+                        <i-Col span="6">
+                            <span :class="attr.check ? 'check':''">产品编号:</span>&nbsp;&nbsp;<i-Input placeholder="产品编号" v-model="attr.bar_code" style="width: 60%"
+                                                                                                   :number="true"></i-Input>
+                        </i-Col>
                         <i-Col span="2" offset="1" style="margin-right: 2px">
                             <div class="demo-upload">
                                 <img :src="attr.pic">

+ 243 - 0
crmeb/app/admin/view/system/system_store/index.php

@@ -0,0 +1,243 @@
+<!DOCTYPE html>
+<html lang="zh-CN">
+<head>
+    {include file="public/head"}
+
+    <link href="/system/frame/css/bootstrap.min.css?v=3.4.0" rel="stylesheet">
+    <link href="/system/frame/css/style.min.css?v=3.0.0" rel="stylesheet">
+    <title>{$title|default=''}</title>
+    <style></style>
+</head>
+<body>
+<div class="wrapper wrapper-content">
+    <div class="row">
+        <div class="col-sm-12">
+            <div class="ibox float-e-margins">
+                <div class="ibox-title">
+                    <h5>门店设置</h5>
+                </div>
+                <div id="store-attr" class="mp-form" v-cloak="">
+                    <i-Form :label-width="80" style="width: 100%">
+                        <template>
+                            <Alert type="warning">除门店简介外其他选项都是必填项</Alert>
+                            <Form-Item>
+                                <Row>
+                                    <i-Col span="13">
+                                        <span>门店名称:</span>
+                                        <i-Input placeholder="门店名称" v-model="form.name" style="width: 80%" type="text"></i-Input>
+                                    </i-Col>
+                                </Row>
+                            </Form-Item>
+                            <Form-Item>
+                                <Row>
+                                    <i-Col span="13">
+                                        <span>门店简介:</span>
+                                        <i-Input placeholder="门店简介" v-model="form.introduction" style="width: 80%" type="text"></i-Input>
+                                    </i-Col>
+                                </Row>
+                            </Form-Item>
+                            <Form-Item>
+                                <Row>
+                                    <i-Col span="13">
+                                        <span>门店电话:</span>
+                                        <i-Input placeholder="门店电话" v-model="form.phone" style="width: 80%" type="text"></i-Input>
+                                    </i-Col>
+                                </Row>
+                            </Form-Item>
+                            <Form-Item>
+                                <Row>
+                                    <i-Col span="13">
+                                        <span>门店地址:</span>
+                                        <Cascader :data="addresData" :value.sync="form.address" @on-change="handleChange" style="width: 80%;display: inline-block;"></Cascader>
+                                    </i-Col>
+                                </Row>
+                            </Form-Item>
+                            <Form-Item>
+                                <Row>
+                                    <i-Col span="13">
+                                        <span>详细地址:</span>
+                                        <i-Input placeholder="详细地址" v-model="form.detailed_address" style="width: 80%" type="text"></i-Input>
+                                    </i-Col>
+                                </Row>
+                            </Form-Item>
+                            <Form-Item>
+                                <Row>
+                                    <i-Col span="13">
+                                        <span>核销时效:</span>
+                                        <Date-picker type="daterange" @on-change="changeValidTime" placeholder="选择日期" :value="form.valid_time"></Date-picker>
+                                    </i-Col>
+                                </Row>
+                            </Form-Item>
+                            <Form-Item>
+                                <Row>
+                                    <i-Col span="13">
+                                        <span>门店营业:</span>
+                                        <Time-picker type="timerange" @on-change="changeDayTime" placement="bottom-end" :value="form.day_time" placeholder="选择时间"></Time-picker>
+                                    </i-Col>
+                                </Row>
+                            </Form-Item>
+                            <Form-Item>
+                                <Row>
+                                    <i-Col span="13">
+                                        <span>门店logo:</span>
+                                        <div class="demo-upload-list" v-if="form.image">
+                                            <template>
+                                                <img :src="form.image">
+                                                <div class="demo-upload-list-cover">
+                                                    <Icon type="ios-eye-outline" @click="visible = true "></Icon>
+                                                    <Icon type="ios-trash-outline" @click="form.image=''"></Icon>
+                                                </div>
+                                            </template>
+                                        </div>
+                                        <div class="ivu-upload" style="display: inline-block; width: 58px;" @click="openWindows('选择图片','{:Url('widget.images/index',['fodder'=>'image'])}')" v-if="!form.image">
+                                            <div class="ivu-upload ivu-upload-drag">
+                                                <div style="width: 58px; height: 58px; line-height: 58px;">
+                                                    <i class="ivu-icon ivu-icon-camera" style="font-size: 20px;"></i>
+                                                </div>
+                                            </div>
+                                        </div>
+                                        <Modal title="查看图片" :visible.sync="visible">
+                                            <img :src="form.image" v-if="visible" style="width: 100%">
+                                        </Modal>
+                                    </i-Col>
+                                </Row>
+                            </Form-Item>
+                            <Form-Item>
+                                <Row>
+                                    <i-Col span="13">
+                                        <span style="float: left">经纬度:</span>
+                                        <Tooltip content="请点击查找位置进行选择位置">
+                                            <i-Input placeholder="经纬度" v-model="form.latlng" :readonly="true" style="width: 80%" >
+                                                <span slot="append" @click="openWindows('查找位置','{:Url('select_address')}',{w:400})" style="cursor:pointer">查找位置</span>
+                                            </i-Input>
+                                        </Tooltip>
+                                    </i-Col>
+                                </Row>
+                            </Form-Item>
+                        </template>
+                        <Form-Item>
+                            <Row>
+                                <i-Col span="8" offset="6">
+                                    <i-Button type="primary" @click="submit">提交</i-Button>
+                                </i-Col>
+                            </Row>
+                        </Form-Item>
+                    </i-Form>
+                </div>
+            </div>
+        </div>
+    </div>
+</div>
+<script src="{__PLUG_PATH}city.js"></script>
+<script>
+    var storeData={:json_encode($store)};
+    mpFrame.start(function(Vue) {
+        $.each(city,function (key,item) {
+            city[key].value = item.label;
+            if(item.children && item.children.length){
+                $.each(item.children,function (i,v) {
+                    city[key].children[i].value=v.label;
+                    if(v.children && v.children.length){
+                        $.each(v.children,function (k,val) {
+                            city[key].children[i].children[k].value=val.label;
+                        });
+                    }
+                });
+            }
+        });
+        new Vue({
+            data() {
+                return {
+                    id:storeData.id || 0,
+                    addresData:city,
+                    form:{
+                        name:storeData.name || '',
+                        introduction:storeData.introduction || '',
+                        phone:storeData.phone || '',
+                        address:storeData.address || [],
+                        image:storeData.image || '',
+                        detailed_address:storeData.detailed_address || '',
+                        latlng:storeData.latlng || '',
+                        valid_time:storeData.valid_time || [],
+                        day_time:storeData.day_time || [],
+                    },
+                    visible:false,
+                }
+            },
+            methods:{
+                changeDayTime:function(date){
+                    this.$set(this.form,'day_time',date);
+                },
+                changeValidTime:function(date){
+                    this.$set(this.form,'valid_time',date);
+                },
+                createFrame:function(title,src,opt){
+                    opt === undefined && (opt = {});
+                    var h = parent.document.body.clientHeight - 100;
+                    return layer.open({
+                        type: 2,
+                        title:title,
+                        area: [(opt.w || 700)+'px', (opt.h || h)+'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'
+                    });
+                },
+                handleChange:function(value,selectedData){
+                    var that = this;
+                    $.each(selectedData,function (key,item) {
+                        that.form.address.push(item.label);
+                    });
+                    that.$set(that.form,'address',that.form.address);
+                },
+                openWindows:function(title,url,opt){
+                    return this.createFrame(title,url,opt);
+                },
+                changeIMG:function(name,url){
+                    this.form[name]=url;
+                },
+                isPhone:function(test){
+                    var reg = /^1[3456789]\d{9}$/;
+                    return reg.test(test);
+                },
+                submit:function () {
+                    var that = this;
+                    if(!that.form.name) return  $eb.message('error','请填写门店行名称');
+                    if(!that.form.phone) return  $eb.message('error','请输入手机号码');
+                    if(!that.isPhone(that.form.phone)) return  $eb.message('error','请输入正确的手机号码');
+                    if(!that.form.address) return  $eb.message('error','请选择门店地址');
+                    if(!that.form.detailed_address) return  $eb.message('error','请填写门店详细地址');
+                    if(!that.form.image) return  $eb.message('error','请选择门店logo');
+                    if(!that.form.valid_time) return  $eb.message('error','请选择核销时效');
+                    if(!that.form.day_time) return  $eb.message('error','请选择门店营业时间');
+                    if(!that.form.latlng) return  $eb.message('error','请选择门店经纬度!');
+                    var index = layer.load(1, {
+                        shade: [0.5,'#fff']
+                    });
+                    $eb.axios.post('{:Url("save")}'+(that.id ? '?id='+that.id : ''),that.form).then(function (res) {
+                        layer.close(index);
+                        layer.msg(res.data.msg);
+                        if(res.data.data.id) that.id=res.data.data.id;
+                    }).catch(function (err) {
+                        console.log(err);
+                        layer.close(index);
+                    })
+                },
+                selectAdderss:function (data) {
+                    //lat 纬度 lng 经度
+                    this.form.latlng=data.latlng.lat+','+data.latlng.lng;
+                }
+            },
+            mounted:function () {
+                window.changeIMG=this.changeIMG;
+                window.selectAdderss=this.selectAdderss;
+            }
+        }).$mount(document.getElementById('store-attr'))
+    })
+</script>

파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 92 - 1
crmeb/app/admin/view/wechat/wechat_news_category/send_news.php


+ 2 - 2
crmeb/app/admin/view/wechat/wechat_user/index.php

@@ -296,7 +296,7 @@
                                                 <span class="caret"></span>
                                             </button>
                                             <ul class="dropdown-menu">
-                                                {eq name="vo.subscribe" value="1"}
+                                                {if $vo.openid && $vo.subscribe == 1}
                                                 <li>
                                                     <a class="save_mark" href="javascript:void(0);"  onclick="$eb.createModalFrame('修改分组','{:Url('edit_user_group',['openid'=>$vo['openid']])}',{w:350,h:500})" >
                                                         修改分组
@@ -318,7 +318,7 @@
                                                         无法操作
                                                     </a>
                                                 </li>
-                                                {/eq}
+                                                {/if}
                                             </ul>
                                         </div>
                                     </td>

+ 3 - 3
crmeb/app/admin/view/widget/images.php

@@ -203,9 +203,9 @@
                 //判断表单限制图片个数
                 if(typeof parent.$f != 'undefined'){
                     //已有图片个数
-                    var nowpics = parent.$f.getValue(parentinputname).length;
-                    //设置最大个数
-                    var maxlength = parent.$f.model()[parentinputname].props.maxLength;
+                    var nowpics = parent.$f.getValue(parentinputname).length,
+                        props = parent.$f.model()[parentinputname].props || {},
+                        maxlength = props.maxLength || 0;
                     //已选图片个数
                     var selectlength = this.selectImages.length;
                     //还可以选择多少张

+ 14 - 5
crmeb/app/api/ApiExceptionHandle.php

@@ -37,12 +37,21 @@ class ApiExceptionHandle extends Handle
     {
         // 添加自定义异常处理机制
         if ($e instanceof DbException) {
-            return app('json')->fail('数据获取失败');
+            return app('json')->fail('数据获取失败',[
+                'file'      => $e->getFile(),
+                'message'   => $e->getMessage(),
+                'line'      => $e->getLine(),
+            ]);
+        }else{
+            return app('json')->fail('系统出现异常',[
+                'message'   => $e->getMessage(),
+                'file'      => $e->getFile(),
+                'code'      => $e->getCode(),
+                'line'      => $e->getLine(),
+                'trace'     => $e->getTrace(),
+                'previous'  => $e->getPrevious(),
+            ]);
         }
-
-        // 其他错误交给系统处理
-        if (env('APP_DEBUG'))
-            return parent::render($request, $e);
     }
 
 }

+ 33 - 9
crmeb/app/api/controller/AuthController.php

@@ -24,13 +24,26 @@ use think\facade\Session;
 
 class AuthController
 {
+    /**
+     * H5账号登陆
+     * @param Request $request
+     * @return mixed
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\ModelNotFoundException
+     * @throws \think\exception\DbException
+     */
     public function login(Request $request)
     {
 
         $user = User::where('account', $request->param('account'))->find();
-        if (!$user || $user->pwd !== md5($request->param('password')))
+        if($user) {
+            if ($user->pwd !== md5($request->param('password')))
+                return app('json')->fail('账号或密码错误');
+            if ($user->pwd === md5(123456))
+                return app('json')->fail('请修改您的初始密码,再尝试登陆!');
+        }else{
             return app('json')->fail('账号或密码错误');
-
+        }
         if (!$user['status'])
             return app('json')->fail('已被禁止,请联系管理员');
 
@@ -109,6 +122,7 @@ class AuthController
             return app('json')->fail('验证码错误');
         if(strlen(trim($password)) < 6 || strlen(trim($password)) > 16)
             return app('json')->fail('密码必须是在6到16位之间');
+        if($password == '123456') return app('json')->fail('密码太过简单,请输入较为复杂的密码');
         $registerStatus = User::register($account, $password, $spread);
         if($registerStatus) return app('json')->success('注册成功');
         return app('json')->fail(User::getErrorInfo('注册失败'));
@@ -135,6 +149,7 @@ class AuthController
             return app('json')->fail('验证码错误');
         if(strlen(trim($password)) < 6 || strlen(trim($password)) > 16)
             return app('json')->fail('密码必须是在6到16位之间');
+        if($password == '123456') return app('json')->fail('密码太过简单,请输入较为复杂的密码');
         $resetStatus = User::reset($account, $password);
         if($resetStatus) return app('json')->success('修改成功');
         return app('json')->fail(User::getErrorInfo('修改失败'));
@@ -186,10 +201,14 @@ class AuthController
             return app('json')->fail('登录失败');
     }
 
-    /*
+    /**
      * H5切换登陆
-     *
-     * */
+     * @param Request $request
+     * @return mixed
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\ModelNotFoundException
+     * @throws \think\exception\DbException
+     */
     public function switch_h5(Request $request){
         $from = $request->post('from','wechat');
         $user = $request->user();
@@ -240,11 +259,14 @@ class AuthController
             return app('json')->fail('登录失败');
     }
 
-
-    /*
+    /**
      * 绑定手机号
-     *
-     * */
+     * @param Request $request
+     * @return mixed
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\ModelNotFoundException
+     * @throws \think\exception\DbException
+     */
     public function binding_phone(Request $request){
         list($phone,$captcha,$step) = UtilService::postMore([
             ['phone',''],
@@ -271,6 +293,8 @@ class AuthController
         $userPhone = $userInfo->phone;
         if(!$userInfo) return app('json')->fail('用户不存在');
         if($userInfo->phone) return app('json')->fail('您的账号已经绑定过手机号码!');
+        if(User::where('phone',$phone)->where('user_type','<>','h5')->count())
+            return app('json')->success('此手机已经绑定,无法多次绑定!');
         if(User::where('account',$phone)->where('phone',$phone)->where('user_type','h5')->find()){
             if(!$step) return app('json')->success('H5已有账号是否绑定此账号上',['is_bind'=>1]);
             $userInfo->phone = $phone;

+ 18 - 0
crmeb/app/api/controller/BaiduController.php

@@ -0,0 +1,18 @@
+<?php
+
+namespace app\api\controller;
+
+/**
+ * 百度小程序授权
+ * Class BaiduController
+ * @package app\api\controller
+ */
+class BaiduController
+{
+
+    public function auth()
+    {
+
+    }
+
+}

+ 30 - 5
crmeb/app/api/controller/PublicController.php

@@ -92,6 +92,9 @@ class PublicController
                 unset($menusInfo[$key]);
             if($value['id'] == 174 && !StoreService::orderServiceStatus($user->uid))
                 unset($menusInfo[$key]);
+            if(!StoreService::orderServiceStatus($user->uid) && $value['wap_url'] === '/order/order_cancellation'){
+                unset($menusInfo[$key]);
+            }
         }
         return app('json')->successful(['routine_my_menus'=>$menusInfo]);
     }
@@ -129,7 +132,7 @@ class PublicController
         ],$request);
         if(!$data['filename']) return app('json')->fail('参数有误');
         if(Cache::has('start_uploads_'.$request->uid()) && Cache::get('start_uploads_'.$request->uid()) >= 100) return app('json')->fail('非法操作');
-        $res = UploadService::image($data['filename'],'store/comment');
+        $res = UploadService::getInstance()->setUploadPath('store/comment')->image($data['filename']);
         if(!is_array($res)) return app('json')->fail($res);
         SystemAttachment::attachmentAdd($res['name'], $res['size'], $res['type'], $res['dir'], $res['thumb_path'],1, $res['image_type'], $res['time'], 2);
         if(Cache::has('start_uploads_'.$request->uid()))
@@ -177,13 +180,35 @@ class PublicController
         return app('json')->fail();
     }
 
-    /*
+    /**
      * 记录用户分享
-     * @return json
-     * */
+     * @param Request $request
+     * @return mixed
+     */
     public function user_share(Request $request){
-        return app('json')->successful(UserBill::setUserShare($request->uid));
+        return app('json')->successful(UserBill::setUserShare($request->uid()));
     }
 
+    /**
+     * 获取图片base64
+     * @param Request $request
+     * @return mixed
+     */
+    public function get_image_base64(Request $request){
+        list($imageUrl,$codeUrl) = UtilService::postMore([
+            ['image',''],
+            ['code',''],
+        ],$request,true);
+        try{
+            $code = $codeUrl ? UtilService::setImageBase64($codeUrl) : false;
+            $image = $imageUrl ? UtilService::setImageBase64($imageUrl) : false;
+            return app('json')->successful(compact('code','image'));
+        }catch (\Exception $e){
+            return app('json')->fail($e->getMessage());
+        }
+    }
+
+
+
 
 }

+ 3 - 3
crmeb/app/api/controller/activity/StoreBargainController.php

@@ -141,11 +141,11 @@ class StoreBargainController
                 $openid = WechatUser::uidToOpenid($bargainUserUid, 'openid');
                 $routineOpenid = WechatUser::uidToOpenid($bargainUserUid, 'routine_openid');
                 if($openid){//公众号
-                    $urlWeChat = Route::buildUrl('activity/dargain_detail/'.$bargainId.'/'.$bargainUserUid)->suffix('')->domain(true)->build();
+                    $urlWeChat = Route::buildUrl('/activity/dargain_detail/'.$bargainId.'/'.$bargainUserUid)->suffix('')->domain(true)->build();
                     WechatTemplateService::sendTemplate($openid,WechatTemplateService::BARGAIN_SUCCESS,[
                         'first'=> '好腻害!你的朋友们已经帮你砍到底价了!',
                         'keyword1'=> $bargainInfo['title'],
-                        'keyword2'=> $bargainInfo['bargain_price_min'],
+                        'keyword2'=> $bargainInfo['min_price'],
                         'remark'=> '点击查看订单详情'
                     ],$urlWeChat);
                 }else if($routineOpenid){ //小程序
@@ -314,7 +314,7 @@ class StoreBargainController
                     if($user['is_promoter'] || SystemConfigService::get('store_brokerage_statu') == 2) $valueData.='&pid='.$user['uid'];
                     $res = RoutineCode::getPageCode('pages/activity/goods_bargain_details/index',$valueData,280);
                     if(!$res) return app('json')->fail('二维码生成失败');
-                    $imageInfo = UploadService::imageStream($name,$res,'routine/activity/bargain/code');
+                    $imageInfo = UploadService::getInstance()->setUploadPath('routine/activity/bargain/code')->imageStream($name,$res);
                     if(!is_array($imageInfo)) return app('json')->fail($imageInfo);
                     if($imageInfo['image_type'] == 1) $remoteImage = UtilService::remoteImage($siteUrl.$imageInfo['dir']);
                     else $remoteImage = UtilService::remoteImage($imageInfo['dir']);

+ 11 - 9
crmeb/app/api/controller/activity/StoreCombinationController.php

@@ -27,8 +27,8 @@ class StoreCombinationController
     public function lst(Request $request)
     {
         list($page, $limit) = UtilService::getMore([
-            ['page',0],
-            ['limit',0],
+            ['page',1],
+            ['limit',10],
         ],$request, true);
         $combinationList = StoreCombination::getAll($page, $limit);
         if(!count($combinationList)) return app('json')->fail('暂无拼团');
@@ -55,15 +55,17 @@ class StoreCombinationController
         if(!$imageInfo){
             $codeUrl = UtilService::setHttpType($siteUrl.'/activity/group_detail/'.$id, 1);//二维码链接
             $imageInfo = UtilService::getQRCodePath($codeUrl, $name);
-            if(!$imageInfo) return app('json')->fail('二维码生成失败');
-            SystemAttachment::attachmentAdd($imageInfo['name'],$imageInfo['size'],$imageInfo['type'],$imageInfo['dir'],$imageInfo['thumb_path'],1,$imageInfo['image_type'],$imageInfo['time'],2);
-            $url = $imageInfo['dir'];
+            if(is_array($imageInfo)){
+                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 = '';
         }else $url = $imageInfo['att_dir'];
         if($imageInfo['image_type'] == 1)
             $url = $siteUrl.$url;
         $combinationOne['image'] = UtilService::setSiteUrl($combinationOne['image'], $siteUrl);
-        $combinationOne['image_base'] = UtilService::setImageBase64(UtilService::setSiteUrl($combinationOne['image'], $siteUrl));
-        $combinationOne['code_base'] = UtilService::setImageBase64($url);
+        $combinationOne['image_base'] = UtilService::setSiteUrl($combinationOne['image'], $siteUrl);
+        $combinationOne['code_base'] = $url;
         $combinationOne['sale_stock'] = 0;
         if($combinationOne['stock'] > 0) $combinationOne['sale_stock'] = 1;
         if(!strlen(trim($combinationOne['unit_name']))) $combinationOne['unit_name'] = '个';
@@ -104,7 +106,7 @@ class StoreCombinationController
         if(isset($pink['is_refund']) && $pink['is_refund']) {
             if($pink['is_refund'] != $pink['id']){
                 $id = $pink['is_refund'];
-                return $this->pink($id);
+                return $this->pink($request,$id);
             }else{
                 return app('json')->fail('订单已退款');
             }
@@ -200,7 +202,7 @@ class StoreCombinationController
                     if($user['is_promoter'] || SystemConfigService::get('store_brokerage_statu')==2) $valueData.='&pid='.$user['uid'];
                     $res = RoutineCode::getPageCode('pages/activity/goods_combination_status/index',$valueData,280);
                     if(!$res) return app('json')->fail('二维码生成失败');
-                    $imageInfo = UploadService::imageStream($name,$res,'routine/activity/pink/code');
+                    $imageInfo = UploadService::getInstance()->setUploadPath('routine/activity/pink/code')->imageStream($name,$res);
                     if(!is_array($imageInfo)) return app('json')->fail($imageInfo);
                     if($imageInfo['image_type'] == 1) $remoteImage = UtilService::remoteImage($siteUrl.$imageInfo['dir']);
                     else $remoteImage = UtilService::remoteImage($imageInfo['dir']);

+ 10 - 9
crmeb/app/api/controller/activity/StoreSeckillController.php

@@ -103,7 +103,7 @@ class StoreSeckillController
      * @param $id
      * @return mixed
      */
-    public function detail(Request $request, $id){
+    public function detail(Request $request, $id,$time = 0){
         if(!$id || !($storeInfo = StoreSeckill::getValidProduct($id))) return app('json')->fail('商品不存在或已下架!');
         $storeInfo = $storeInfo->hidden(['cost','add_time','is_del'])->toArray();
 
@@ -112,17 +112,18 @@ class StoreSeckillController
         $imageInfo = SystemAttachment::getInfo($name,'name');
         $siteUrl = SystemConfigService::get('site_url');
         if(!$imageInfo){
-            $codeUrl = UtilService::setHttpType($siteUrl.'/activity/seckill_detail/'.$id, 1);//二维码链接
+            $codeUrl = UtilService::setHttpType($siteUrl.'/activity/seckill_detail/'.$id.'/'.$time, 1);//二维码链接
             $imageInfo = UtilService::getQRCodePath($codeUrl, $name);
-            if(!$imageInfo) return app('json')->fail('二维码生成失败');
-            SystemAttachment::attachmentAdd($imageInfo['name'],$imageInfo['size'],$imageInfo['type'],$imageInfo['dir'],$imageInfo['thumb_path'],1,$imageInfo['image_type'],$imageInfo['time'],2);
-            $url = $imageInfo['dir'];
+            if(is_array($imageInfo)){
+                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 = '';
         }else $url = $imageInfo['att_dir'];
-        if($imageInfo['image_type'] == 1)
-            $url = $siteUrl.$url;
+        if($imageInfo['image_type'] == 1) $url = $siteUrl.$url;
         $storeInfo['image'] = UtilService::setSiteUrl($storeInfo['image'], $siteUrl);
-        $storeInfo['image_base'] = UtilService::setImageBase64(UtilService::setSiteUrl($storeInfo['image'], $siteUrl));
-        $storeInfo['code_base'] = UtilService::setImageBase64($url);
+        $storeInfo['image_base'] = UtilService::setSiteUrl($storeInfo['image'], $siteUrl);
+        $storeInfo['code_base'] = $url;
         $uid = $request->uid();
         $storeInfo['userLike'] = StoreProductRelation::isProductRelation($id, $uid, 'like', 'product_seckill');
         $storeInfo['like_num'] = StoreProductRelation::productRelationNum($id,'like','product_seckill');

+ 93 - 22
crmeb/app/api/controller/order/StoreOrderController.php

@@ -1,22 +1,27 @@
 <?php
 namespace app\api\controller\order;
 
+use app\admin\model\system\SystemAttachment;
 use app\models\routine\RoutineFormId;
-use app\models\store\StoreBargainUser;
-use app\models\store\StoreCart;
-use app\models\store\StoreCouponUser;
-use app\models\store\StoreOrder;
-use app\models\store\StoreOrderCartInfo;
-use app\models\store\StorePink;
-use app\models\store\StoreProductReply;
+use app\models\store\{
+    StoreBargainUser,
+    StoreCart,
+    StoreCouponUser,
+    StoreOrder,
+    StoreOrderCartInfo,
+    StorePink,
+    StoreProductReply
+};
+use app\models\system\SystemStore;
 use app\models\user\UserAddress;
 use app\models\user\UserLevel;
 use app\Request;
-use crmeb\services\CacheService;
-use crmeb\services\ExpressService;
-use crmeb\services\SystemConfigService;
-use crmeb\services\UtilService;
-use think\facade\Db;
+use crmeb\services\{
+    CacheService,
+    ExpressService,
+    SystemConfigService,
+    UtilService
+};
 
 /**
  * 订单类
@@ -75,6 +80,8 @@ class StoreOrderController
         $data['userInfo'] = $user;
         $data['integralRatio'] = $other['integralRatio'];
         $data['offline_pay_status'] = (int)SystemConfigService::get('offline_pay_status') ?? (int)2;
+        $data['store_self_mention']= (int)SystemConfigService::get('store_self_mention') ?? 0;//门店自提是否开启
+        $data['system_store'] = ($res = SystemStore::getStoreDispose()) ? $res : [];//门店信息
         return app('json')->successful($data);
     }
 
@@ -96,8 +103,9 @@ class StoreOrderController
         $uid = $request->uid();
         if (StoreOrder::be(['order_id|unique' => $key, 'uid' => $uid, 'is_del' => 0]))
             return app('json')->status('extend_order', '订单已生成', ['orderId' => $key, 'key' => $key]);
-        list($addressId, $couponId, $payType, $useIntegral, $mark, $combinationId, $pinkId, $seckill_id, $formId, $bargainId) = UtilService::postMore([
-            'addressId', 'couponId', ['payType', 'yue'], ['useIntegral',0], 'mark', ['combinationId', 0], ['pinkId', 0], ['seckill_id', 0], ['formId', ''], ['bargainId', '']
+        list($addressId, $couponId, $payType, $useIntegral, $mark, $combinationId, $pinkId, $seckill_id, $formId, $bargainId,$shipping_type) = UtilService::postMore([
+            'addressId', 'couponId', ['payType', 'yue'], ['useIntegral',0], 'mark', ['combinationId', 0], ['pinkId', 0], ['seckill_id', 0], ['formId', ''], ['bargainId', ''],
+            ['shipping_type',1],
         ], $request, true);
         $payType = strtolower($payType);
         if ($bargainId){
@@ -115,8 +123,7 @@ class StoreOrderController
             if (StoreOrder::getIsOrderPink($pinkId, $request->uid()))
                 return app('json')->status('ORDER_EXIST', '订单生成失败,你已经参加该团了,请先支付订单', ['orderId' => StoreOrder::getStoreIdPink($pinkId, $request->uid())]);
         }
-        Db::startTrans();
-        $priceGroup = StoreOrder::cacheKeyCreateOrder($request->uid(), $key, $addressId, $payType, (int)$useIntegral, $couponId, $mark, $combinationId, $pinkId, $seckill_id, $bargainId, true, 0);
+        $priceGroup = StoreOrder::cacheKeyCreateOrder($request->uid(), $key, $addressId, $payType, (int)$useIntegral, $couponId, $mark, $combinationId, $pinkId, $seckill_id, $bargainId, true, 0,$shipping_type);
         if($priceGroup)
             return app('json')->status('NONE', 'ok', $priceGroup);
         else
@@ -139,8 +146,9 @@ class StoreOrderController
         $uid = $request->uid();
         if (StoreOrder::be(['order_id|unique' => $key, 'uid' => $uid, 'is_del' => 0]))
             return app('json')->status('extend_order', '订单已生成', ['orderId' => $key, 'key' => $key]);
-        list($addressId, $couponId, $payType, $useIntegral, $mark, $combinationId, $pinkId, $seckill_id, $formId, $bargainId, $from) = UtilService::postMore([
-            'addressId', 'couponId', 'payType', ['useIntegral',0], 'mark', ['combinationId', 0], ['pinkId', 0], ['seckill_id', 0], ['formId', ''], ['bargainId', ''], ['from', 'weixin']
+        list($addressId, $couponId, $payType, $useIntegral, $mark, $combinationId, $pinkId, $seckill_id, $formId, $bargainId, $from,$shipping_type,$real_name,$phone) = UtilService::postMore([
+            'addressId', 'couponId', 'payType', ['useIntegral',0], 'mark', ['combinationId', 0], ['pinkId', 0], ['seckill_id', 0], ['formId', ''], ['bargainId', ''], ['from', 'weixin'],
+            ['shipping_type',1],['real_name',''],['phone','']
         ], $request, true);
         $payType = strtolower($payType);
         if ($bargainId){
@@ -160,12 +168,13 @@ class StoreOrderController
         }
         $isChannel = 1;
         if($from == 'weixin')  $isChannel = 0;
-        $order = StoreOrder::cacheKeyCreateOrder($request->uid(), $key, $addressId, $payType, (int)$useIntegral, $couponId, $mark, $combinationId, $pinkId, $seckill_id, $bargainId, false, $isChannel);
+        $order = StoreOrder::cacheKeyCreateOrder($request->uid(), $key, $addressId, $payType, (int)$useIntegral, $couponId, $mark, $combinationId, $pinkId, $seckill_id, $bargainId, false, $isChannel,$shipping_type,$real_name,$phone);
+        if($order === false) return app('json')->fail(StoreOrder::getErrorInfo('订单生成失败'));
         $orderId = $order['order_id'];
         $info = compact('orderId', 'key');
         if ($orderId) {
-            event('OrderCreated', [$order]);
-
+            event('OrderCreated', [$order]); //订单创建成功事件
+            event('ShortMssageSend',[$orderId,'AdminPlaceAnOrder']);//发送管理员通知
             switch ($payType) {
                 case "weixin":
                     $orderInfo = StoreOrder::where('order_id', $orderId)->find();
@@ -347,8 +356,32 @@ class StoreOrderController
         $order = StoreOrder::getUserOrderDetail($request->uid(),$uni);
         if(!$order) return app('json')->fail('订单不存在');
         $order = $order->toArray();
+        if($order['verify_code']){
+            $verify_code = $order['verify_code'];
+            $verify[] = substr($verify_code,0,4);
+            $verify[] = substr($verify_code,4,4);
+            $verify[] = substr($verify_code,8);
+            $order['_verify_code'] = implode(' ',$verify);
+        }
         $order['add_time_y'] = date('Y-m-d',$order['add_time']);
         $order['add_time_h'] = date('H:i:s',$order['add_time']);
+        $order['system_store'] = SystemStore::getStoreDispose();
+        if($order['shipping_type'] === 2 && $order['verify_code']){
+            $name = $order['verify_code'].'.jpg';
+            $imageInfo = SystemAttachment::getInfo($name,'name');
+            $siteUrl = SystemConfigService::get('site_url');
+            if(!$imageInfo){
+                $imageInfo = UtilService::getQRCodePath($order['verify_code'], $name);
+                if(is_array($imageInfo)){
+                    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 = '';
+            }else $url = $imageInfo['att_dir'];
+            if(isset($imageInfo['image_type']) && $imageInfo['image_type'] == 1) $url = $siteUrl.$url;
+            $order['code'] = $url;
+        }
+        $order['mapKey'] = SystemConfigService::get('tengxun_map_key');
         return app('json')->successful('ok',StoreOrder::tidyOrder($order,true,true));
     }
 
@@ -422,7 +455,7 @@ class StoreOrderController
             $cartNew['truePrice'] = $cart['truePrice'];
             $cartNew['productInfo']['image'] = $cart['productInfo']['image'];
             $cartNew['productInfo']['store_name'] = $cart['productInfo']['store_name'];
-            $cartNew['productInfo']['unit_name'] = $cart['productInfo']['unit_name'];
+            $cartNew['productInfo']['unit_name'] = $cart['productInfo']['unit_name'] ?? '';
             array_push($info, $cartNew);
             unset($cart);
         }
@@ -592,4 +625,42 @@ class StoreOrderController
         return app('json')->successful($cartProduct);
     }
 
+    /**
+    * 门店核销
+     * @param Request $request
+     */
+    public function order_verific(Request $request){
+        list($verify_code,$is_confirm) = UtilService::postMore([
+            ['verify_code',''],
+            ['is_confirm',0]
+        ],$request,true);
+        if(!$verify_code) return app('json')->fail('缺少核销码');
+        $orderInfo = StoreOrder::where('verify_code',$verify_code)->where('paid',1)->where('refund_status',0)->find();
+        if(!$orderInfo) return app('json')->fail('核销的订单不存在或未支付或已退款');
+        if($orderInfo->status > 0) return app('json')->fail('订单已经核销');
+        if($orderInfo->combination_id && $orderInfo->pink_id){
+            $res = StorePink::where('id',$orderInfo->pink_id)->where('status','<>',2)->count();
+            if($res) return app('json')->fail('拼团订单暂未成功无法核销!');
+        }
+        if(!$is_confirm){
+            $orderInfo['image'] = StoreCart::getProductImage($orderInfo->cart_id);
+            return app('json')->success($orderInfo->toArray());
+        }
+        StoreOrder::beginTrans();
+        try{
+            $orderInfo->status = 2;
+            if($orderInfo->save()){
+                StoreOrder::commitTrans();
+                return app('json')->success('核销成功');
+            }else{
+                StoreOrder::rollbackTrans();
+                return app('json')->fail('核销失败');
+            }
+        }catch (\PDOException $e){
+            StoreOrder::rollbackTrans();
+            return app('json')->fail($e->getMessage());
+        }
+
+    }
+
 }

+ 61 - 47
crmeb/app/api/controller/store/StoreProductController.php

@@ -3,6 +3,7 @@
 namespace app\api\controller\store;
 
 use app\admin\model\system\SystemAttachment;
+use app\models\system\SystemStore;
 use app\models\store\StoreProduct;
 use app\models\store\StoreProductAttr;
 use app\models\store\StoreProductRelation;
@@ -34,7 +35,8 @@ class StoreProductController
             ['salesOrder', ''],
             ['news', 0],
             ['page', 0],
-            ['limit', 0]
+            ['limit', 0],
+            ['type', 0]
         ], $request);
         return app('json')->successful(StoreProduct::getProductList($data, $request->uid()));
     }
@@ -54,46 +56,54 @@ class StoreProductController
         if (!$id || !($storeInfo = StoreProduct::getValidProduct($id,'id'))) return app('json')->fail('商品不存在或已下架');
         $userType = $request->get('user_type','wechat');
         $user = $request->user();
-        switch ($userType){
-            case 'wechat':
-                //公众号
-                $name = $id.'_product_detail_'.$user['uid'].'_is_promoter_'.$user['is_promoter'].'.wap.jpg';
-                $imageInfo = SystemAttachment::getInfo($name,'name');
-                $siteUrl = SystemConfigService::get('site_url');
-                if(!$imageInfo){
-                    $codeUrl = UtilService::setHttpType($siteUrl.'/detail/'.$id.'?spread='.$user['uid'], 1);//二维码链接
-                    $imageInfo = UtilService::getQRCodePath($codeUrl, $name);
-                    if(!$imageInfo) return app('json')->fail('二维码生成失败');
-                    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) $url = $siteUrl.$url;
-                return app('json')->successful(['code'=>UtilService::setImageBase64($url)]);
-                break;
-            case 'routine':
-                //小程序
-                $name = $id.'_'.$user['uid'].'_'.$user['is_promoter'].'_product.jpg';
-                $imageInfo = SystemAttachment::getInfo($name,'name');
-                $siteUrl = SystemConfigService::get('site_url').DS;
-                if(!$imageInfo){
-                    $data='id='.$id;
-                    if($user['is_promoter'] || SystemConfigService::get('store_brokerage_statu')==2) $data.='&pid='.$user['uid'];
-                    $res = \app\models\routine\RoutineCode::getPageCode('pages/goods_details/index',$data,280);
-                    if(!$res) return app('json')->fail('二维码生成失败');
-                    $imageInfo = \crmeb\services\UploadService::imageStream($name,$res,'routine/product');
-                    if(is_string($imageInfo)) return app('json')->fail($imageInfo);
-                    if($imageInfo['image_type'] == 1) $remoteImage = UtilService::remoteImage($siteUrl.$imageInfo['dir']);
-                    else $remoteImage = UtilService::remoteImage($imageInfo['dir']);
-                    if(!$remoteImage['status']) return app('json')->fail('小程序二维码未能生成');
-                    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) $url = $siteUrl.$url;
-                return app('json')->successful(['code'=>$url]);
+        try{
+            switch ($userType){
+                case 'wechat':
+                    //公众号
+                    $name = $id.'_product_detail_'.$user['uid'].'_is_promoter_'.$user['is_promoter'].'.wap.jpg';
+                    $imageInfo = SystemAttachment::getInfo($name,'name');
+                    $siteUrl = SystemConfigService::get('site_url');
+                    if(!$imageInfo){
+                        $codeUrl = UtilService::setHttpType($siteUrl.'/detail/'.$id.'?spread='.$user['uid'], 1);//二维码链接
+                        $imageInfo = UtilService::getQRCodePath($codeUrl, $name);
+                        if(is_string($imageInfo)) return app('json')->fail('二维码生成失败');
+                        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) $url = $siteUrl.$url;
+                    return app('json')->successful(['code'=>UtilService::setImageBase64($url)]);
+                    break;
+                case 'routine':
+                    //小程序
+                    $name = $id.'_'.$user['uid'].'_'.$user['is_promoter'].'_product.jpg';
+                    $imageInfo = SystemAttachment::getInfo($name,'name');
+                    $siteUrl = SystemConfigService::get('site_url').DS;
+                    if(!$imageInfo){
+                        $data='id='.$id;
+                        if($user['is_promoter'] || SystemConfigService::get('store_brokerage_statu')==2) $data.='&pid='.$user['uid'];
+                        $res = \app\models\routine\RoutineCode::getPageCode('pages/goods_details/index',$data,280);
+                        if(!$res) return app('json')->fail('二维码生成失败');
+                        $imageInfo = \crmeb\services\UploadService::getInstance()->setUploadPath('routine/product')->imageStream($name,$res);
+                        if(is_string($imageInfo)) return app('json')->fail($imageInfo);
+                        if($imageInfo['image_type'] == 1) $remoteImage = UtilService::remoteImage($siteUrl.$imageInfo['dir']);
+                        else $remoteImage = UtilService::remoteImage($imageInfo['dir']);
+                        if(!$remoteImage['status']) return app('json')->fail('小程序二维码未能生成');
+                        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) $url = $siteUrl.$url;
+                    return app('json')->successful(['code'=>$url]);
+            }
+        }catch (\Exception $e){
+            return app('json')->fail($e->getMessage(),[
+                'code'=>$e->getCode(),
+                'line'=>$e->getLine(),
+                'message'=>$e->getMessage()
+            ]);
         }
     }
 
-    public function detail(Request $request, $id)
+    public function detail(Request $request, $id,$type = 0)
     {
         if (!$id || !($storeInfo = StoreProduct::getValidProduct($id))) return app('json')->fail('商品不存在或已下架');
 
@@ -104,15 +114,16 @@ class StoreProductController
         if(!$imageInfo){
             $codeUrl = UtilService::setHttpType($siteUrl.'/detail/'.$id, 1);//二维码链接
             $imageInfo = UtilService::getQRCodePath($codeUrl, $name);
-            if(!$imageInfo) return app('json')->fail('二维码生成失败');
-            SystemAttachment::attachmentAdd($imageInfo['name'],$imageInfo['size'],$imageInfo['type'],$imageInfo['dir'],$imageInfo['thumb_path'],1,$imageInfo['image_type'],$imageInfo['time'],2);
-            $url = $imageInfo['dir'];
+            if(is_array($imageInfo)){
+                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 = '';
         }else $url = $imageInfo['att_dir'];
-        if($imageInfo['image_type'] == 1)
-            $url = $siteUrl.$url;
+        if($imageInfo['image_type'] == 1) $url = $siteUrl.$url;
         $storeInfo['image'] = UtilService::setSiteUrl($storeInfo['image'], $siteUrl);
-        $storeInfo['image_base'] = UtilService::setImageBase64(UtilService::setSiteUrl($storeInfo['image'], $siteUrl));
-        $storeInfo['code_base'] = UtilService::setImageBase64($url);
+        $storeInfo['image_base'] = UtilService::setSiteUrl($storeInfo['image'], $siteUrl);
+        $storeInfo['code_base'] = $url;
         $uid = $request->uid();
         $data['uid'] = $uid;
         //替换windows服务器下正反斜杠问题导致图片无法显示
@@ -121,7 +132,7 @@ class StoreProductController
         }, $storeInfo['description']);
         $storeInfo['userCollect'] = StoreProductRelation::isProductRelation($id, $uid, 'collect');
         $storeInfo['userLike'] = StoreProductRelation::isProductRelation($id, $uid, 'like');
-        list($productAttr, $productValue) = StoreProductAttr::getProductAttrDetail($id);
+        list($productAttr, $productValue) = StoreProductAttr::getProductAttrDetail($id,$uid,$type);
         setView($uid, $id, $storeInfo['cate_id'], 'viwe');
         $data['storeInfo'] = StoreProduct::setLevelPrice($storeInfo, $uid, true);
         $data['similarity'] = StoreProduct::cateIdBySimilarityProduct($storeInfo['cate_id'], 'id,store_name,image,price,sales,ficti', 4);
@@ -150,7 +161,10 @@ class StoreProductController
                 $data['replyChance'] = bcmul($data['replyChance'], 100, 2);
             }
         } else $data['replyChance'] = 0;
-        $data['mer_id'] = StoreProduct::where('id', $storeInfo['id'])->value('mer_id');
+        $data['mer_id'] = $storeInfo['mer_id'];
+        $data['system_store'] = ($res = SystemStore::getStoreDispose()) ? $res : [];
+        $data['good_list'] = StoreProduct::getGoodList(18,'image,store_name,price,id');
+        $data['mapKey'] = SystemConfigService::get('tengxun_map_key');
         return app('json')->successful($data);
     }
 

+ 1 - 1
crmeb/app/api/controller/user/UserBillController.php

@@ -166,7 +166,7 @@ class UserBillController
                 if(!$imageInfo){
                     $res = RoutineCode::getShareCode($user['uid'], 'spread', '', '');
                     if(!$res) return app('json')->fail('二维码生成失败');
-                    $imageInfo = UploadService::imageStream($name,$res['res'],'routine/spread/code');
+                    $imageInfo = UploadService::getInstance()->setUploadPath('routine/spread/code')->imageStream($name,$res['res']);
                     if(!is_array($imageInfo)) return app('json')->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']]);

+ 45 - 3
crmeb/app/api/controller/user/UserController.php

@@ -31,6 +31,7 @@ use crmeb\services\SystemConfigService;
 use crmeb\services\UploadService;
 use crmeb\services\UtilService;
 use think\facade\Cache;
+use think\facade\Db;
 
 /**
  * 用户类
@@ -40,6 +41,11 @@ use think\facade\Cache;
 class UserController
 {
 
+    /**
+     * 获取用户信息
+     * @param Request $request
+     * @return mixed
+     */
     public function userInfo(Request $request)
     {
         return app('json')->success($request->user()->toArray());
@@ -386,7 +392,7 @@ class UserController
      */
     public function sign_integral(Request $request)
     {
-        $signed = UserSign::getToDayIsSign($request->uid());
+        $signed = UserSign::getIsSign($request->uid());
         if($signed) return app('json')->fail('已签到');
         if(false !== ($integral = UserSign::sign($request->uid())))
             return app('json')->successful('签到获得'.floatval($integral).'积分',['integral'=>$integral]);
@@ -409,8 +415,8 @@ class UserController
         //是否统计签到
         if($sign || $all){
             $user['sum_sgin_day'] = UserSign::getSignSumDay($user['uid']);
-            $user['is_day_sgin'] = UserSign::getToDayIsSign($user['uid']);
-            $user['is_YesterDay_sgin'] = UserSign::getYesterDayIsSign($user['uid']);
+            $user['is_day_sgin'] = UserSign::getIsSign($user['uid']);
+            $user['is_YesterDay_sgin'] = UserSign::getIsSign($user['uid'],'yesterday');
             if(!$user['is_day_sgin'] && !$user['is_YesterDay_sgin']){ $user['sign_num'] = 0;}
         }
         //是否统计积分使用情况
@@ -470,4 +476,40 @@ class UserController
         return app('json')->fail('修改失败');
     }
 
+    /**
+     * 推广人排行
+     * @param Request $request
+     * @return mixed
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\ModelNotFoundException
+     * @throws \think\exception\DbException
+     */
+    public function rank(Request $request){
+        $data = UtilService::getMore([
+            ['page',''],
+            ['limit',''],
+            ['type','']
+        ],$request);
+        $users = User::getRankList($data);
+        return app('json')->success($users);
+    }
+
+    /**
+     * 佣金排行
+     * @param Request $request
+     * @return mixed
+     */
+    public function brokerage_rank(Request $request){
+        $data = UtilService::getMore([
+            ['page',''],
+            ['limit'],
+            ['type']
+        ],$request);
+        return app('json')->success([
+            'rank'    => User::brokerageRank($data),
+            'position'=> User::currentUserRank($request->user()['brokerage_price'])
+        ]);
+
+    }
+
 }

+ 44 - 22
crmeb/app/api/controller/wechat/AuthController.php

@@ -14,13 +14,23 @@ use app\models\user\User;
 use app\models\routine\RoutineFormId;
 use think\facade\Cache;
 
+/**
+ * 小程序相关
+ * Class AuthController
+ * @package app\api\controller\wechat
+ */
 class AuthController
 {
-    /*
+
+    /**
      * 小程序授权登录
-     * @param json
-     *
-     * */
+     * @param Request $request
+     * @return mixed
+     * @throws \Psr\SimpleCache\InvalidArgumentException
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\ModelNotFoundException
+     * @throws \think\exception\DbException
+     */
     public function mp_auth(Request $request)
     {
         $cache_key = '';
@@ -61,10 +71,8 @@ class AuthController
         $userInfo['code'] = $data['spread_code'];
         $userInfo['session_key'] = $session_key;
         $userInfo['login_type'] = $login_type;
-        $dataOauthInfo = WechatUser::routineOauth($userInfo);
-        $userInfo['uid'] = $dataOauthInfo['uid'];
-        $userInfo['page'] = $dataOauthInfo['page'];
-        $userInfo = User::where('uid',$dataOauthInfo['uid'])->find();
+        $uid = WechatUser::routineOauth($userInfo);
+        $userInfo = User::where('uid',$uid)->find();
         if($userInfo->login_type == 'h5' && ($h5UserInfo = User::where(['account'=>$userInfo->phone,'phone'=>$userInfo->phone,'user_type'=>'h5'])->find()))
             $token = UserToken::createToken($userInfo, 'routine');
         else
@@ -81,31 +89,45 @@ class AuthController
             return app('json')->fail('获取用户访问token失败!');
     }
 
-    /*
-     * 获取小程序授权logo
-     * */
-    public function get_logo()
+    /**
+     * 获取授权logo
+     * @param Request $request
+     * @return mixed
+     */
+    public function get_logo(Request $request)
     {
-        $routine_logo=SystemConfigService::get('routine_logo');
-        if(strstr($routine_logo,'http')===false) $routine_logo = SystemConfigService::get('site_url').$routine_logo;
-        return app('json')->successful(['logo_url'=>str_replace('\\','/',$routine_logo)]);
+        $logoType = $request->get('type',1);
+        switch ((int)$logoType){
+            case 1:
+                $logo=SystemConfigService::get('routine_logo');
+                break;
+            case 2:
+                $logo=SystemConfigService::get('wechat_avatar');
+                break;
+            default:
+                $logo = '';
+                break;
+        }
+        if(strstr($logo,'http')===false && $logo) $logo = SystemConfigService::get('site_url').$logo;
+        return app('json')->successful(['logo_url'=>str_replace('\\','/',$logo)]);
     }
 
-    /*
+    /**
      * 保存form id
-     *
-     * */
+     * @param Request $request
+     * @return mixed
+     */
     public function set_form_id(Request $request)
     {
         $formId = $request->post('formId','');
         if(!$formId) return app('json')->fail('缺少form id');
-        RoutineFormId::SetFormId($formId,$request->uid);
-        return app('json')->successful('保存form id 成功!',['uid'=>$request->uid]);
+        RoutineFormId::SetFormId($formId,$request->uid());
+        return app('json')->successful('保存form id 成功!',['uid'=>$request->uid()]);
     }
 
-    /*
+    /**
      * 小程序支付回调
-     * */
+     */
     public function notify()
     {
         MiniProgramService::handleNotify();

+ 25 - 0
crmeb/app/api/controller/wechat/WechatController.php

@@ -11,23 +11,48 @@ use app\Request;
 use crmeb\services\WechatService;
 use think\facade\Cookie;
 
+/**
+ * 微信公众号
+ * Class WechatController
+ * @package app\api\controller\wechat
+ */
 class WechatController
 {
+    /**
+     * 微信公众号服务
+     * @return \think\Response
+     */
     public function serve()
     {
         return WechatService::serve();
     }
 
+    /**
+     * 支付异步回调
+     */
     public function notify()
     {
         WechatService::handleNotify();
     }
 
+    /**
+     * 公众号权限配置信息获取
+     * @param Request $request
+     * @return mixed
+     */
     public function config(Request $request)
     {
         return app('json')->success(json_decode(WechatService::jsSdk($request->get('url')), true));
     }
 
+    /**
+     * 公众号授权登陆
+     * @param Request $request
+     * @return mixed
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\ModelNotFoundException
+     * @throws \think\exception\DbException
+     */
     public function auth(Request $request)
     {
         $spreadId = intval($request->param('spread'));

+ 2 - 1
crmeb/app/event.php

@@ -48,13 +48,14 @@ return [
         'InitLogin' => [], // UserSubscribe 微信授权成功后  ebapi模块 Basic控制器
         'UserLevelAfter' => [], // UserSubscribe 检查是否能成为会员  models模块 user.UserSign Model  store.StoreOrder Model user.UserBill Model
         'OrderCreated' => [], //用户订单创建成功
-        'OrderPaySuccess' => [], //用户订单支付成功
+        'OrderPaySuccess' => [], // OrderSubscribe 用户订单支付成功
         'OrderCreateAgain' => [], //用户再次下单
         'UserOrderRemoved' => [], //用户删除订单
         'UserOrderTake' => [], //用户确认收货
         'UserCommented' => [], //用户评价商品
         'RechargeSuccess' => [], //用户充值成功后
         'ImportNowMoney' => [], //用户佣金转成余额成功后
+        'ShortMssageSend'=>[],//MessageSubscribe 下发短信
     ],
 
     'subscribe' => [

+ 7 - 0
crmeb/app/models/article/Article.php

@@ -1,6 +1,7 @@
 <?php
 namespace app\models\article;
 
+use app\models\store\StoreProduct;
 use crmeb\services\SystemConfigService;
 use think\facade\Db;
 use crmeb\traits\ModelTrait;
@@ -27,6 +28,11 @@ class Article extends BaseModel
 
     use ModelTrait;
 
+    public function profile()
+    {
+        return $this->hasOne(StoreProduct::class,'id','product_id')->field('store_name,image,price,id');
+    }
+
     protected function getImageInputAttr($value)
     {
         return explode(',',$value)?:[];
@@ -45,6 +51,7 @@ class Article extends BaseModel
         if(!$id) return [];
         $list = self::where('status',1)->where('hide',0)->where('id',$id)->order('id desc')->find();
         if($list){
+            $list->store_info = $list->profile ? StoreProduct::setLevelPrice($list->profile->toArray(),0,true) : null;
             $list = $list->hidden(['hide','status','admin_id','mer_id'])->toArray();
             $list["content"] = Db::name('articleContent')->where('nid',$id)->value('content');
             return $list;

+ 6 - 5
crmeb/app/models/store/StoreBargain.php

@@ -66,11 +66,12 @@ class StoreBargain extends BaseModel
      * @return array
      */
     public static function getList($page = 0,$limit = 20,$field = 'id,product_id,title,price,min_price,image'){
-        $model = self::validWhere();
-        if($page) $list = $model->field($field)->page($page,$limit)->select()->each(function ($item){ $item['people'] = count(StoreBargainUser::getUserIdList($item['id']));});
-        else  $list = $model->field($field)->select()->each(function ($item){ $item['people'] = count(StoreBargainUser::getUserIdList($item['id']));});
-        if($list) return $list->toArray();
-        else return [];
+        $model = self::validWhere()->field($field);
+        if($page) $model = $model->page($page,$limit);
+        $list = $model->select()->each(function ($item){
+            $item['people'] = count(StoreBargainUser::getUserIdList($item['id']));
+        });
+        return $list ? $list->toArray() : [];
     }
 
     /**

+ 8 - 0
crmeb/app/models/store/StoreCart.php

@@ -290,4 +290,12 @@ class StoreCart extends BaseModel
         return self::whereIn('id',$ids)->column('product_id','id');
     }
 
+    /**
+    *  获取购物车内最新一张产品图
+     */
+    public static function getProductImage(array $cart_id){
+        return self::whereIn('a.id',$cart_id)->alias('a')->order('a.id desc')
+            ->join('store_product p','p.id = a.product_id')->value('p.image');
+    }
+
 }

+ 1 - 1
crmeb/app/models/store/StoreCategory.php

@@ -81,7 +81,7 @@ class StoreCategory extends BaseModel
 
     public function children()
     {
-        return $this->hasMany(self::class, 'pid','id');
+        return $this->hasMany(self::class, 'pid','id')->where('is_show',1);
     }
 
 }

+ 11 - 7
crmeb/app/models/store/StoreCouponIssue.php

@@ -50,16 +50,20 @@ class StoreCouponIssue extends BaseModel
             }]);
 
         $list = $list->select();
-        foreach ($list as &$v) {
+        foreach ($list as $k=>$v) {
             $v['is_use'] = $uid ? isset($v->used) : false;
-//            if (!$v['is_use']) {
-//                $v['is_use'] = $v['remain_count'] <= 0 && !$v['is_permanent'] ? false : $v['is_use'];
+//            if(!$v['is_use']){
+//                $v['is_use']=$v['remain_count'] <= 0 && !$v['is_permanent'] ? 2 : $v['is_use'];
 //            }
-            if ($v['end_time']) {
-                $v['start_time'] = date('Y/m/d', $v['start_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'] = (float)$v['coupon_price'];
+            $v['coupon_price']=(int)$v['coupon_price'];
+            $list[$k] = $v;
         }
 
         return $list->hidden(['is_del', 'status', 'used', 'add_time'])->toArray();

파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 494 - 230
crmeb/app/models/store/StoreOrder.php


+ 97 - 95
crmeb/app/models/store/StorePink.php

@@ -14,6 +14,7 @@ use app\models\user\WechatUser;
 use crmeb\basic\BaseModel;
 use crmeb\services\WechatTemplateService;
 use crmeb\traits\ModelTrait;
+use think\facade\Log;
 use think\facade\Route;
 
 /**
@@ -195,7 +196,7 @@ class StorePink extends BaseModel
                  $keyword1WeChat = self::where('id|k_id',$pid)->where('uid',$item)->value('order_id');
                  $keyword2WeChat = self::alias('p')->where('p.id|p.k_id',$pid)->where('p.uid',$item)->join('__store_combination__ c','c.id=p.cid')->value('c.title');
                  $remarkWeChat = '点击查看订单详情';
-                 $urlWeChat = Route::buildUrl('order/detail/'.$keyword1WeChat,[],true,true);
+                 $urlWeChat = Route::buildUrl('order/detail/'.$keyword1WeChat)->suffix('')->domain(true)->build();
                  WechatTemplateService::sendTemplate($openid,WechatTemplateService::ORDER_USER_GROUPS_SUCCESS,[
                      'first'=> $firstWeChat,
                      'keyword1'=> $keyword1WeChat,
@@ -228,7 +229,7 @@ class StorePink extends BaseModel
         $routineOpenid = WechatUser::uidToOpenid($uid, 'routine_openid');
         if($isRemove){
             if($openid){//公众号发送模板消息
-                $urlWeChat = Route::buildUrl('order/detail/'.$pink->order_id,[],true,true);
+                $urlWeChat = Route::buildUrl('order/detail/'.$pink->order_id)->suffix('')->domain(true)->build();
                 WechatTemplateService::sendTemplate($openid,WechatTemplateService::ORDER_USER_GROUPS_LOSE,[
                     'first'=>'亲,您的拼团取消',
                     'keyword1'=> $store->title,
@@ -245,7 +246,7 @@ class StorePink extends BaseModel
             }
         }else{
             if($openid){//公众号发送模板消息
-                $urlWeChat = Route::buildUrl('order/detail/'.$pink->order_id,[],true,true);
+                $urlWeChat = Route::buildUrl('order/detail/'.$pink->order_id)->suffix('')->domain(true)->build();
                 WechatTemplateService::sendTemplate($openid,WechatTemplateService::ORDER_USER_GROUPS_LOSE,[
                     'first'=>'亲,您的拼团失败',
                     'keyword1'=> $store->title,
@@ -384,93 +385,95 @@ class StorePink extends BaseModel
         $order = StoreOrder::tidyOrder($order,true)->toArray();
         $openid = WechatUser::uidToOpenid($order['uid'], 'openid');
         $routineOpenid = WechatUser::uidToOpenid($order['uid'], 'routine_openid');
-        $productTitle = StoreCombination::where('id',$order['combination_id'])->value('title');
-        if($order['pink_id']){//拼团存在
-            $res = false;
-            $pink['uid'] = $order['uid'];//用户id
-            if(self::isPinkBe($pink,$order['pink_id'])) return false;
-            $pink['order_id'] = $order['order_id'];//订单id  生成
-            $pink['order_id_key'] = $order['id'];//订单id  数据库id
-            $pink['total_num'] = $order['total_num'];//购买个数
-            $pink['total_price'] = $order['pay_price'];//总金额
-            $pink['k_id'] = $order['pink_id'];//拼团id
-            foreach ($order['cartInfo'] as $v){
-                $pink['cid'] = $v['combination_id'];//拼团产品id
-                $pink['pid'] = $v['product_id'];//产品id
-                $pink['people'] = StoreCombination::where('id',$v['combination_id'])->value('people');//几人拼团
-                $pink['price'] = $v['productInfo']['price'];//单价
-                $pink['stop_time'] = 0;//结束时间
-                $pink['add_time'] = time();//开团时间
-                $res = self::create($pink)->toArray();
-            }
-            if($openid){ //公众号模板消息
-                $urlWeChat = Route::buildUrl('order/detail/'.$order['order_id'],[],true,true);
-                WechatTemplateService::sendTemplate($openid,WechatTemplateService::ORDER_USER_GROUPS_SUCCESS,[
-                    'first'=> '亲,您已成功参与拼团',
-                    'keyword1'=> $order['order_id'],
-                    'keyword2'=> $productTitle,
-                    'remark'=> '点击查看订单详情'
-                ],$urlWeChat);
-            }else if($routineOpenid){
-                RoutineTemplate::sendOut('PINK_TRUE',$order['uid'],[
-                    'keyword1'=>$productTitle,
-                    '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'],
-                ],'','/pages/order_details/index?order_id='.$pink['order_id']);
-            }
-            //处理拼团完成
-            list($pinkAll,$pinkT,$count,$idAll,$uidAll)=self::getPinkMemberAndPinkK($pink);
-            if($pinkT['status']==1){
-                if(!$count)//组团完成
-                    self::PinkComplete($uidAll,$idAll,$pink['uid'],$pinkT);
-                else
-                    self::PinkFail($pinkAll,$pinkT,0);
+        $product = StoreCombination::where('id',$order['combination_id'])->field('effective_time,title')->find();
+        if($product){
+            if($order['pink_id']){//拼团存在
+                $res = false;
+                $pink['uid'] = $order['uid'];//用户id
+                if(self::isPinkBe($pink,$order['pink_id'])) return false;
+                $pink['order_id'] = $order['order_id'];//订单id  生成
+                $pink['order_id_key'] = $order['id'];//订单id  数据库id
+                $pink['total_num'] = $order['total_num'];//购买个数
+                $pink['total_price'] = $order['pay_price'];//总金额
+                $pink['k_id'] = $order['pink_id'];//拼团id
+                foreach ($order['cartInfo'] as $v){
+                    $pink['cid'] = $v['combination_id'];//拼团产品id
+                    $pink['pid'] = $v['product_id'];//产品id
+                    $pink['people'] = StoreCombination::where('id',$v['combination_id'])->value('people');//几人拼团
+                    $pink['price'] = $v['productInfo']['price'];//单价
+                    $pink['stop_time'] = 0;//结束时间
+                    $pink['add_time'] = time();//开团时间
+                    $res = self::create($pink)->toArray();
+                }
+                if($openid){ //公众号模板消息
+                    $urlWeChat = Route::buildUrl('order/detail/'.$order['order_id'])->suffix('')->domain(true)->build();
+                    WechatTemplateService::sendTemplate($openid,WechatTemplateService::ORDER_USER_GROUPS_SUCCESS,[
+                        'first'=> '亲,您已成功参与拼团',
+                        'keyword1'=> $order['order_id'],
+                        'keyword2'=> $product->title,
+                        'remark'=> '点击查看订单详情'
+                    ],$urlWeChat);
+                }else if($routineOpenid){
+                    RoutineTemplate::sendOut('PINK_TRUE',$order['uid'],[
+                        'keyword1'=>$product->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'],
+                    ],'','/pages/order_details/index?order_id='.$pink['order_id']);
+                }
+                //处理拼团完成
+                list($pinkAll,$pinkT,$count,$idAll,$uidAll)=self::getPinkMemberAndPinkK($pink);
+                if($pinkT['status']==1){
+                    if(!$count)//组团完成
+                        self::PinkComplete($uidAll,$idAll,$pink['uid'],$pinkT);
+                    else
+                        self::PinkFail($pinkAll,$pinkT,0);
+                }
+                if($res) return true;
+                else return false;
+            }else{
+                $res = false;
+                $pink['uid'] = $order['uid'];//用户id
+                $pink['order_id'] = $order['order_id'];//订单id  生成
+                $pink['order_id_key'] = $order['id'];//订单id  数据库id
+                $pink['total_num'] = $order['total_num'];//购买个数
+                $pink['total_price'] = $order['pay_price'];//总金额
+                $pink['k_id'] = 0;//拼团id
+                foreach ($order['cartInfo'] as $v){
+                    $pink['cid'] = $v['combination_id'];//拼团产品id
+                    $pink['pid'] = $v['product_id'];//产品id
+                    $pink['people'] = StoreCombination::where('id',$v['combination_id'])->value('people');//几人拼团
+                    $pink['price'] = $v['productInfo']['price'];//单价
+                    $pink['stop_time'] = bcadd(time(),bcmul($product->effective_time,3600,0),0);//结束时间
+                    $pink['add_time'] = time();//开团时间
+                    $res1 = self::create($pink)->toArray();
+                    $res2 = StoreOrder::where('id',$order['id'])->update(['pink_id'=>$res1['id']]);
+                    $res = $res1 && $res2;
+                }
+                // 开团成功发送模板消息
+                if($openid && !$order['is_channel']){ //公众号模板消息
+                    $urlWeChat = Route::buildUrl('/order/detail/'.$pink['order_id'])->suffix('')->domain(true)->build();
+                    WechatTemplateService::sendTemplate($openid,WechatTemplateService::OPEN_PINK_SUCCESS,[
+                        'first'=> '您好,您已成功开团!赶紧与小伙伴们分享吧!!!',
+                        'keyword1'=> $product->title,
+                        'keyword2'=> $pink['total_price'],
+                        'keyword3'=> $pink['people'],
+                        'remark'=> '点击查看订单详情'
+                    ],$urlWeChat);
+                }else if($routineOpenid && $order['is_channel']){
+                    RoutineTemplate::sendOut('OPEN_PINK_SUCCESS',$order['uid'],[
+                        'keyword1'=>date('Y-m-d H:i:s',$pink['add_time']),
+                        'keyword2'=>date('Y-m-d H:i:s',$pink['stop_time']),
+                        'keyword3'=>$product->title,
+                        'keyword4'=>$pink['order_id'],
+                        'keyword4'=>$pink['total_price'],
+                    ],'','/pages/order_details/index?order_id='.$pink['order_id']);
+                }
+                if($res) return true;
+                else return false;
             }
-            if($res) return true;
-            else return false;
         }else{
-            $res = false;
-            $pink['uid'] = $order['uid'];//用户id
-            $pink['order_id'] = $order['order_id'];//订单id  生成
-            $pink['order_id_key'] = $order['id'];//订单id  数据库id
-            $pink['total_num'] = $order['total_num'];//购买个数
-            $pink['total_price'] = $order['pay_price'];//总金额
-            $pink['k_id'] = 0;//拼团id
-            foreach ($order['cartInfo'] as $v){
-                $pink['cid'] = $v['combination_id'];//拼团产品id
-                $pink['pid'] = $v['product_id'];//产品id
-                $pink['people'] = StoreCombination::where('id',$v['combination_id'])->value('people');//几人拼团
-                $pink['price'] = $v['productInfo']['price'];//单价
-//                $stopTime = StoreCombination::where('id',$v['combination_id'])->value('stop_time');//获取拼团产品结束的时间
-//                if($stopTime < time()+86400)  $pink['stop_time'] = $stopTime;//结束时间
-                $pink['stop_time'] = time()+86400;//结束时间
-                $pink['add_time'] = time();//开团时间
-                $res1 = self::create($pink)->toArray();
-                $res2 = StoreOrder::where('id',$order['id'])->update(['pink_id'=>$res1['id']]);
-                $res = $res1 && $res2;
-            }
-            // 开团成功发送模板消息
-            if($openid){ //公众号模板消息
-                $urlWeChat = Route::buildUrl('order/detail/'.$pink['order_id'],[],true,true);
-                WechatTemplateService::sendTemplate($openid,WechatTemplateService::OPEN_PINK_SUCCESS,[
-                    'first'=> '您好,您已成功开团!赶紧与小伙伴们分享吧!!!',
-                    'keyword1'=> $productTitle,
-                    'keyword2'=> $pink['total_price'],
-                    'keyword3'=> $pink['people'],
-                    'remark'=> '点击查看订单详情'
-                ],$urlWeChat);
-            }else if($routineOpenid){
-                RoutineTemplate::sendOut('OPEN_PINK_SUCCESS',$order['uid'],[
-                    'keyword1'=>date('Y-m-d H:i:s',$pink['add_time']),
-                    'keyword2'=>date('Y-m-d H:i:s',$pink['stop_time']),
-                    'keyword3'=>$productTitle,
-                    'keyword4'=>$pink['order_id'],
-                    'keyword4'=>$pink['total_price'],
-                ],'','/pages/order_details/index?order_id='.$pink['order_id']);
-            }
-            if($res) return true;
-            else return false;
+            Log::error('拼团支付成功读取产品数据失败订单号:'.$order['order_id']);
         }
     }
     /*
@@ -578,7 +581,7 @@ class StorePink extends BaseModel
             $pinkT = $pink;
         }
         $pinkT = $pinkT->hidden(['order_id','total_price','cid','pid','add_time','k_id','is_tpl','is_refund'])->toArray();
-        $pinkAll = $pinkAll->hidden(['order_id','total_price','cid','pid','add_time','k_id','is_tpl','is_refund'])->toArray();
+        $pinkAll = $pinkAll->hidden(['total_price','cid','pid','add_time','k_id','is_tpl','is_refund'])->toArray();
         $count = (int)bcadd(count($pinkAll), 1, 0);
         $count = (int)bcsub($pinkT['people'], $count, 0);
         $idAll = [];
@@ -613,7 +616,7 @@ class StorePink extends BaseModel
         try{
             list($pinkAll,$pinkT,$count,$idAll,$uidAll)=self::getPinkMemberAndPinkK($pinkT);
             if(count($pinkAll)){
-                if(self::getPinkPeople($pink_id,$pinkT->people)){
+                if(self::getPinkPeople($pink_id,$pinkT['people'])){
                     //拼团未完成,拼团有成员取消开团取 紧跟团长后拼团的人
                     if(isset($pinkAll[0])) $nextPinkT=$pinkAll[0];
                 }else{
@@ -627,8 +630,7 @@ class StorePink extends BaseModel
                 $formId = RoutineFormId::getFormIdOne($uid);
                 if($formId) RoutineFormId::delFormIdOne($formId);
                 self::orderPinkAfterNo($pinkT['uid'],$pinkT['id'],$formId,'拼团取消开团',true);
-            }
-            else
+            }else
                 return self::setErrorInfo(['status'=>200,'msg'=>StoreOrder::getErrorInfo()],true);
             //当前团有人的时候
             if(is_array($nextPinkT)){
@@ -639,7 +641,7 @@ class StorePink extends BaseModel
             self::commitTrans();
             return true;
         }catch (\Exception $e){
-            return self::setErrorInfo($e->getLine().':'.$e->getMessage(),true);
+            return self::setErrorInfo($e->getLine().':'.$e->getMessage().':'.$e->getFile(),true);
         }
     }
 
@@ -719,7 +721,7 @@ class StorePink extends BaseModel
             $pink = self::where('id|k_id',$pink)->where('uid',$item)->find();
             if($openid){
                 //公众号模板消息
-                $urlWeChat = Route::buildUrl('order/detail/'.$pink->order_id,[],true,true);
+                $urlWeChat = Route::buildUrl('order/detail/'.$pink->order_id)->suffix('')->domain(true)->build();
                 WechatTemplateService::sendTemplate($openid,WechatTemplateService::ORDER_USER_GROUPS_LOSE,[
                     'first'=>'亲,您的拼团失败',
                     'keyword1'=> $store->title,
@@ -792,7 +794,7 @@ class StorePink extends BaseModel
                 $keyword1WeChat = self::where('id|k_id',$pink)->where('uid',$item)->value('order_id');
                 $keyword2WeChat = self::alias('p')->where('p.id|p.k_id',$pink)->where('p.uid',$item)->join('__store_combination__ c','c.id=p.cid')->value('c.title');
                 $remarkWeChat = '点击查看订单详情';
-                $urlWeChat = Route::buildUrl('order/detail/'.$keyword1WeChat,[],true,true);
+                $urlWeChat = Route::buildUrl('order/detail/'.$keyword1WeChat)->suffix('')->domain(true)->build();
                 WechatTemplateService::sendTemplate($openid,WechatTemplateService::ORDER_USER_GROUPS_SUCCESS,[
                     'first'=> $firstWeChat,
                     'keyword1'=> $keyword1WeChat,

+ 30 - 2
crmeb/app/models/store/StoreProduct.php

@@ -58,6 +58,11 @@ class StoreProduct extends BaseModel
         else return false;
     }
 
+    public static function getGoodList($limit=18,$field='*')
+    {
+        return self::validWhere()->where('is_good',1)->order('sort desc,id desc')->limit($limit)->field($field)->select();
+    }
+
     public static function validWhere()
     {
         return self::where('is_del', 0)->where('is_show', 1)->where('mer_id', 0);
@@ -73,6 +78,7 @@ class StoreProduct extends BaseModel
         $news = $data['news'];
         $page = $data['page'];
         $limit = $data['limit'];
+        $type = $data['type']; // 某些模板需要购物车数量 1 = 需要查询,0 = 不需要
         $model = self::validWhere();
         if ($sId) {
             $product_ids = Db::name('store_product_cate')->where('cate_id', $sId)->column('product_id');
@@ -98,7 +104,14 @@ class StoreProduct extends BaseModel
         if ($salesOrder) $baseOrder = $salesOrder == 'desc' ? 'sales DESC' : 'sales ASC';//虚拟销量
         if ($baseOrder) $baseOrder .= ', ';
         $model->order($baseOrder . 'sort DESC, add_time DESC');
-        $list = $model->page((int)$page, (int)$limit)->field('id,store_name,cate_id,image,IFNULL(sales,0) + IFNULL(ficti,0) as sales,price,stock')->select();
+        $list = $model->page((int)$page, (int)$limit)->field('id,store_name,cate_id,image,IFNULL(sales,0) + IFNULL(ficti,0) as sales,price,stock')->select()->each(function ($item) use($uid,$type){
+            if($type) {
+                $item['is_att'] = StoreProductAttrValueModel::where('product_id', $item['id'])->count() ? true : false;
+                if ($uid) $item['cart_num'] = StoreCart::where('is_pay', 0)->where('is_del', 0)->where('is_new', 0)->where('type', 'product')->where('product_id', $item['id'])->where('uid', $uid)->value('cart_num');
+                else $item['cart_num'] = 0;
+                if (is_null($item['cart_num'])) $item['cart_num'] = 0;
+            }
+        });
         $list = count($list) ? $list->toArray() : [];
         return self::setLevelPrice($list, $uid);
     }
@@ -298,7 +311,9 @@ class StoreProduct extends BaseModel
             $stock = self::where('id', $productId)->value('stock');
             $replenishment_num = SystemConfigService::get('store_stock') ?? 0;//库存预警界限
             if($replenishment_num >= $stock){
-                ChannelService::instance()->send('STORE_STOCK', ['id'=>$productId]);
+                try{
+                    ChannelService::instance()->send('STORE_STOCK', ['id'=>$productId]);
+                }catch (\Exception $e){}
             }
         }
         return $res;
@@ -411,4 +426,17 @@ class StoreProduct extends BaseModel
     {
         return self::whereIn('id', $productIds)->column('store_name,image', 'id');
     }
+    /**
+     * TODO 获取某个字段值
+     * @param $id
+     * @param string $field
+     * @return mixed
+     */
+    public static function getProductField($id,$field = 'store_name'){
+        if(is_array($id))
+            return self::where('id','in',$id)->field($field)->select();
+        else
+            return self::where('id',$id)->value($field);
+    }
+
 }

+ 8 - 1
crmeb/app/models/store/StoreProductAttr.php

@@ -43,12 +43,19 @@ class StoreProductAttr extends BaseModel
      * @param $productId
      * @return array
      */
-    public static function getProductAttrDetail($productId)
+    public static function getProductAttrDetail($productId,$uid=0,$type = 0)
     {
         $attrDetail = self::where('product_id',$productId)->order('attr_values asc')->select()->toArray()?:[];
         $_values = self::storeProductAttrValueDb()->where('product_id',$productId)->select();
         $values = [];
         foreach ($_values as $value){
+            if($type){
+                if ($uid)
+                    $value['cart_num'] = StoreCart::where('product_attr_unique',$value['unique'])->where('is_pay', 0)->where('is_del', 0)->where('is_new', 0)->where('type', 'product')->where('product_id', $productId)->where('uid', $uid)->value('cart_num');
+                else
+                    $value['cart_num'] = 0;
+                if (is_null($value['cart_num'])) $value['cart_num'] = 0;
+            }
             $values[$value['suk']] = $value;
         }
         foreach ($attrDetail as $k=>$v){

+ 73 - 0
crmeb/app/models/system/Cache.php

@@ -0,0 +1,73 @@
+<?php
+namespace app\models\system;
+
+use crmeb\traits\ModelTrait;
+use crmeb\basic\BaseModel;
+
+/**
+ * 数据缓存
+ * Class Express
+ * @package app\models\system
+ */
+class Cache extends BaseModel
+{
+    use ModelTrait;
+
+    const EXPIRE = 0;
+    /**
+     * 模型名称
+     * @var string
+     */
+    protected $name = 'cache';
+
+    /**
+     * 获取数据缓存
+     * @param string $key
+     * @return result
+     */
+    public static function getDbCache(string $key)
+    {
+        self::delectDeOverdueDbCache();
+         $result = self::where('key',$key)->value('result');
+         return json_decode($result,true);
+    }
+
+    /**
+     * 设置数据缓存存在则更新,没有则写入
+     * @param string $key
+     * @param string | array $result
+     * @param int $expire
+     * @return void
+     */
+    public static function setDbCache(string $key,$result,$expire = self::EXPIRE)
+    {
+        self::delectDeOverdueDbCache();
+        $addTime = $expire ? time() + $expire : 0;
+        if(self::be(['key'=>$key])){
+            return self::where(['key'=>$key])->update(['result'=>json_encode($result),'add_time'=>$addTime]);
+        }else{
+            return self::create(['key'=>$key,'result'=>json_encode($result),'add_time'=>$addTime]);
+        }
+    }
+
+    /**
+     * 删除失效缓存
+     */
+    public static function delectDeOverdueDbCache()
+    {
+        return self::where('add_time','<>',0)->where('add_time','<',time())->delete();
+    }
+
+    /**
+     * 删除某个缓存
+     * @param string $key
+     */
+    public static function delectDbCache(string $key = '')
+    {
+        if($key)
+            return self::where('key',$key)->delete();
+        else
+            return self::delete();
+    }
+
+}

+ 62 - 0
crmeb/app/models/system/SystemStore.php

@@ -0,0 +1,62 @@
+<?php
+
+
+namespace app\models\system;
+
+use crmeb\traits\ModelTrait;
+use crmeb\basic\BaseModel;
+
+/**
+ * 门店自提 model
+ * Class SystemStore
+ * @package app\model\system
+ */
+class SystemStore extends BaseModel
+{
+    use ModelTrait;
+
+    /**
+     * 数据表主键
+     * @var string
+     */
+    protected $pk = 'id';
+
+    /**
+     * 模型名称
+     * @var string
+     */
+    protected $name = 'system_store';
+
+
+    public static function getLatlngAttr($value,$data)
+    {
+        return $data['latitude'].','.$data['longitude'];
+    }
+
+    public static function verificWhere()
+    {
+        return self::where('is_show',1)->where('is_del',0);
+    }
+    /*
+     * 获取门店信息
+     * @param int $id
+     * */
+    public static function getStoreDispose($id = 0,$felid='')
+    {
+        if($id)
+            $storeInfo = self::verificWhere()->where('id',$id)->find();
+        else
+            $storeInfo = self::verificWhere()->find();
+        if($storeInfo) {
+            $storeInfo['latlng'] = self::getLatlngAttr(null, $storeInfo);
+            $storeInfo['valid_time'] = $storeInfo['valid_time'] ? explode(' - ', $storeInfo['valid_time']) : [];
+            $storeInfo['_valid_time'] = str_replace('-','/',$storeInfo['valid_time'][0].' ~ '.$storeInfo['valid_time'][1]);
+            $storeInfo['day_time'] = $storeInfo['day_time'] ? str_replace(' - ',' ~ ',$storeInfo['day_time']) : [];
+            $storeInfo['_detailed_address'] = $storeInfo['address'].' '.$storeInfo['detailed_address'];
+            $storeInfo['address'] = $storeInfo['address'] ? explode(',', $storeInfo['address']) : [];
+            if($felid) return $storeInfo[$felid] ?? '';
+        }
+        return $storeInfo;
+    }
+
+}

+ 52 - 31
crmeb/app/models/system/SystemUserLevel.php

@@ -61,12 +61,16 @@ class SystemUserLevel extends BaseModel
         return $model->value('discount');
     }
 
-    /*
+
+    /**
      * 获取用户等级和当前等级
-     * @param int $uid 用户uid
-     * @param Boolean $isArray 是否查找任务列表
-     * @return array
-     * */
+     * @param $uid 用户uid
+     * @param bool $isArray 是否查找任务列表
+     * @return array|bool|mixed|string|\think\Model|null
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\ModelNotFoundException
+     * @throws \think\exception\DbException
+     */
     public static function getLevelInfo($uid,$isArray=false){
         $level = ['id'=>0];
         $task = [];
@@ -78,52 +82,69 @@ class SystemUserLevel extends BaseModel
         else return $level['id'] && $id !== false ? $level : false;
     }
 
-    /*
+    /**
      * 获取会员等级级别
-     * @param int $leval_id 等级id
-     * @return Array
-     * */
+     * @param $leval_id 等级id
+     * @return mixed
+     */
     public static function getLevelGrade($leval_id)
     {
         return self::setWhere()->where('id',$leval_id)->value('grade');
     }
-    /*
+
+    /**
      * 获取会员等级列表
-     * @param int $levael_id 用户等级
-     * @param Boolean $isArray 是否查找任务列表
-     * @return Array
-     * */
-    public static function getLevelListAndGrade($leval_id,$isArray,$expire=1400)
+     * @param $leval_id 用户等级
+     * @param $isArray 是否查找任务列表
+     * @param int $expire
+     * @return array|\think\Collection
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\ModelNotFoundException
+     * @throws \think\exception\DbException
+     */
+    public static function getLevelListAndGrade($leval_id,$isArray)
     {
         $grade = 0;
-        if(!$leval_id) $leval_id = self::setWhere()->where('grade', self::setWhere()->min('grade'))->order('add_time DESC')->value('id');
+        if(!$leval_id && !$isArray) $leval_id = self::setWhere()->where('grade', self::setWhere()->min('grade'))->order('add_time DESC')->value('id');
         $list = self::setWhere()->field('name,discount,image,icon,explain,id,grade')->order('grade asc')->select();
         $list = count($list) ? $list->toArray() : [];
         foreach ($list as $item){
-            if($item['id'] == $leval_id) $grade = $item['grade'];
-            if($isArray) $item['task_list'] = SystemUserTask::getTashList($item['id']);
+            if($item['id'] == $leval_id)
+                $grade = $item['grade'];
+
+            if($isArray)
+                $item['task_list'] = SystemUserTask::getTashList($item['id']);
         }
-        foreach ($list as &$item){
-            if($grade <= $item['grade']) $item['is_clear']=true;
-            else $item['is_clear']=false;
+        foreach ($list as &$item) {
+            if($grade < $item['grade'])
+                $item['is_clear'] = true;
+            else
+                $item['is_clear'] = false;
         }
         return $list;
     }
 
+    /**
+     *
+     * @param $leval_id
+     * @param null $list
+     * @return bool
+     */
     public static function getClear($leval_id,$list=null)
     {
-        $list=$list===null ?  self::getLevelListAndGrade($leval_id,false) : $list;
+        $list= $list === null ?  self::getLevelListAndGrade($leval_id,false) : $list;
         foreach ($list as $item){
-            if($item['id']==$leval_id) return $item['is_clear'];
+            if($item['id'] == $leval_id) return $item['is_clear'];
         }
         return false;
     }
 
-    /*
+
+    /**
      * 获取当前vipid 的下一个会员id
-     * @param int $leval_id 当前用户的会员id
-     * @return int
-     * */
+     * @param $leval_id 当前用户的会员id
+     * @return int|mixed
+     */
     public static function getNextLevelId($leval_id)
     {
         $list=self::getLevelListAndGrade($leval_id,false);
@@ -138,11 +159,11 @@ class SystemUserLevel extends BaseModel
         return isset($leveal[0]) ? $leveal[0] : 0;
     }
 
-    /*
+    /**
      * 获取会员等级列表
-     * @parma int $uid 用户uid
-     * @return Array
-     * */
+     * @param $uid
+     * @return array
+     */
     public static function getLevelList($uid){
         list($list,$task) = self::getLevelInfo($uid,true);
         return ['list'=>$list,'task'=>$task];

+ 18 - 18
crmeb/app/models/system/SystemUserTask.php

@@ -30,7 +30,7 @@ class SystemUserTask extends BaseModel
 
     use ModelTrait;
 
-    /*
+    /**
      * 任务类型
      * type 记录在数据库中用来区分任务
      * name 任务名 (任务名中的{$num}会自动替换成设置的数字 + 单位)
@@ -107,7 +107,7 @@ class SystemUserTask extends BaseModel
         return self::$TaskType;
     }
 
-    /*
+    /**
      * 获取某个任务
      * @param string $type 任务类型
      * @return array
@@ -119,7 +119,7 @@ class SystemUserTask extends BaseModel
         }
     }
 
-    /*
+    /**
      * 设置任务名
      * @param string $type 任务类型
      * @param int $num 预设值
@@ -131,7 +131,7 @@ class SystemUserTask extends BaseModel
         return str_replace('{$num}',$num.$systemType['unit'],$systemType['name']);
     }
 
-    /*
+    /**
      * 累计消费金额
      * @param int $task_id 任务id
      * @param int $uid 用户id
@@ -147,7 +147,7 @@ class SystemUserTask extends BaseModel
         return ['还需消费{$num}元',$SumPayPrice,$isComplete];
     }
 
-    /*
+    /**
      * 累计消费次数
      * @param int $task_id 任务id
      * @param int $uid 用户id
@@ -163,7 +163,7 @@ class SystemUserTask extends BaseModel
         return ['还需消费{$num}次',$countPay,$isComplete];
     }
 
-    /*
+    /**
      * 邀请好友成为会员
      * @param int $task_id 任务id
      * @param int $uid 用户id
@@ -180,7 +180,7 @@ class SystemUserTask extends BaseModel
         return ['还需邀请{$num}人成为会员',$levelCount,$isComplete];
     }
 
-    /*
+    /**
      * 邀请好友成为下线
      * @param int $task_id 任务id
      * @param int $uid 用户id
@@ -195,7 +195,7 @@ class SystemUserTask extends BaseModel
         return ['还需邀请{$num}人成为下线',$spreadCount,$isComplete];
     }
 
-    /*
+    /**
      * 满足积分
      * @param int $task_id 任务id
      * @param int $uid 用户id
@@ -206,12 +206,12 @@ class SystemUserTask extends BaseModel
     public static function SatisfactionIntegral($task_id,$uid=0,$start_time=0,$number=0)
     {
         $isComplete=false;
-        $sumNumber=UserBill::where('uid', $uid)->where('category', 'integral')->where('pm', 1)->where('add_time','>',$start_time)->where('type','in',['system_add','sign'])->sum('number');
+        $sumNumber=UserBill::where('uid', $uid)->where('category', 'integral')->where('pm', 1)->where('add_time','>',$start_time)->where('type','in',['system_add','sign','gain'])->sum('number');
         if($sumNumber >= $number) $isComplete=UserTaskFinish::setFinish($uid,$task_id) ? true : false;
         return ['还需要{$num}经验',$sumNumber,$isComplete];
     }
 
-    /*
+    /**
      * 分享给朋友次数完成情况
      * @param int $task_id 任务id
      * @param int $uid 用户id
@@ -227,7 +227,7 @@ class SystemUserTask extends BaseModel
         return ['还需分享{$num}次',$sumCount,$isComplete];
     }
 
-    /*
+    /**
      * 累计签到
      * @param int $task_id 任务id
      * @param int $uid 用户id
@@ -243,7 +243,7 @@ class SystemUserTask extends BaseModel
         return ['还需签到{$num}天',$sumCount,$isComplete];
     }
 
-    /*
+    /**
      * 设置任务完成情况
      * @param int $task_id 任务id
      * @param int $uid 用户uid
@@ -268,7 +268,7 @@ class SystemUserTask extends BaseModel
         return self::setErrorInfo('没有此任务');
     }
 
-    /*
+    /**
      * 设置任务显示条件
      * @param string $alert 表别名
      * @param object $model 模型实例
@@ -281,7 +281,7 @@ class SystemUserTask extends BaseModel
         $alert=$alert ? $alert.'.': '';
         return $model->where("{$alert}is_show",1);
     }
-    /*
+    /**
      * 获取等级会员任务列表
      * @param int $level_id 会员等级id
      * @param int $uid 用户id
@@ -306,7 +306,7 @@ class SystemUserTask extends BaseModel
        ];
     }
 
-    /*
+    /**
      * 获取未完成任务的详细值
      * @param array $item 任务
      * @param int $uid 用户id
@@ -345,7 +345,7 @@ class SystemUserTask extends BaseModel
     }
 
 
-    /*
+    /**
      * 设置任务完成状态,已被使用
      * @param int $level_id 会员id
      * @param int $uid 用户id
@@ -357,7 +357,7 @@ class SystemUserTask extends BaseModel
         if(!count($taskIds)) return true;
         return UserTaskFinish::where('uid',$uid)->where('task_id','in',$taskIds)->update(['status'=>1]);
     }
-    /*
+    /**
      * 检查当前等级是否完成全部任务
      * @param int $level_id 会员id
      * @param int $uid 用户uid
@@ -385,7 +385,7 @@ class SystemUserTask extends BaseModel
         if(SystemUserLevel::be(['id'=>$level_id,'is_pay'=>0])) return false;
         return true;
     }
-    /*
+    /**
      * 设置任务内容完成情况
      * @param array $task 任务列表
      * @param int $uid 用户id

+ 125 - 15
crmeb/app/models/user/User.php

@@ -4,6 +4,7 @@
 namespace app\models\user;
 
 use app\models\store\StoreOrder;
+use crmeb\services\CacheService;
 use crmeb\services\SystemConfigService;
 use think\facade\Session;
 use crmeb\traits\ModelTrait;
@@ -84,6 +85,15 @@ class User extends BaseModel
         return $user['clean_time'] ? $user['clean_time'] : $user['add_time'];
     }
 
+    /**
+     * 更新用户信息
+     * @param $wechatUser 用户信息
+     * @param $uid 用户uid
+     * @return bool|void
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\ModelNotFoundException
+     * @throws \think\exception\DbException
+     */
     public static function updateWechatUser($wechatUser,$uid)
     {
         $userInfo = self::where('uid',$uid)->find();
@@ -108,7 +118,7 @@ class User extends BaseModel
             //TODO 获取后台分销类型
             $storeBrokerageStatus = SystemConfigService::get('store_brokerage_statu');
             $storeBrokerageStatus = $storeBrokerageStatus ? $storeBrokerageStatus : 1;
-            if(isset($wechatUser['code']) && $wechatUser['code'] && $wechatUser['code'] != $uid){
+            if(isset($wechatUser['code']) && $wechatUser['code'] && $wechatUser['code'] != $uid && $uid != self::where('uid',$wechatUser['code'])->value('spread_uid')){
                 if($storeBrokerageStatus == 1){
                     $spreadCount = self::where('uid',$wechatUser['code'])->count();
                     if($spreadCount){
@@ -145,6 +155,7 @@ class User extends BaseModel
         //没有推广编号直接返回
         if(!$spread)  return true;
         if($spread == $uid) return true;
+        if($uid == self::where('uid',$spread)->value('spread_uid')) return true;
         //TODO 获取后台分销类型
         $storeBrokerageStatus = SystemConfigService::get('store_brokerage_statu');
         $storeBrokerageStatus = $storeBrokerageStatus ? $storeBrokerageStatus : 1;
@@ -173,7 +184,7 @@ class User extends BaseModel
         self::beginTrans();
         $res1 = true;
         if($spread_uid) $res1 = self::where('uid',$spread_uid)->inc('spread_count',1)->update();
-        $storeBrokerageStatu = SystemConfigService::get('store_brokerage_statu') ? : 1;//获取后台分销类型
+//        $storeBrokerageStatu = SystemConfigService::get('store_brokerage_statu') ? : 1;//获取后台分销类型
         $res2 = self::create([
             'account'=>'rt'.$routineUser['uid'].time(),
             'pwd'=>md5(123456),
@@ -354,13 +365,13 @@ class User extends BaseModel
         return $res;
     }
 
-    /*
-     *  获取推荐人
-     * @param int $two_uid
-     * @param int $first
-     * @param int $limit
-     * @return array
-     * */
+    /**
+     * 获取推荐人 暂无使用
+     * @param $uid
+     * @param $page
+     * @param $limit
+     * @return mixed
+     */
     public static function getSpreadList($uid,$page,$limit)
     {
         $list=self::where('spread_uid',$uid)->field('uid,nickname,avatar,add_time')->page($page,$limit)->order('add_time DESC')->select();
@@ -374,19 +385,23 @@ class User extends BaseModel
         return $data;
     }
 
-    /*
+    /**
      * 获取某个用户的下级uid
-     * @param int $uid 用户uid
+     * @param $uid
      * @return array
-     * */
+     */
     public static function getOneSpreadUid($uid)
     {
         return self::where('spread_uid',$uid)->column('uid');
     }
 
-    /*
+    /**
      * 修改个人信息
-     * */
+     * @param $avatar 头像
+     * @param $nickname 昵称
+     * @param $uid 用户uid
+     * @return bool
+     */
     public static function editUser($avatar,$nickname,$uid)
     {
         return self::edit(['avatar'=>$avatar,'nickname'=>$nickname],$uid,'uid');
@@ -401,6 +416,10 @@ class User extends BaseModel
         return self::where('spread_uid',$uid)->count();
     }
 
+    /**
+     * 修改当前用户的推广人数
+     * @param $uid
+     */
     public static function setUserSpreadCount($uid){
         self::where('uid',$uid)->update(['spread_count'=>self::getSpreadCount($uid)]);
     }
@@ -453,7 +472,7 @@ class User extends BaseModel
         if($orderBy==='') $orderBy='u.add_time desc';
         $model = $model->alias(' u');
         $model = $model->join('StoreOrder o','u.uid=o.uid','LEFT');
-        $model = $model->where('u.uid','IN',$uid);
+        $model = $model->where('u.uid','IN',$uid)->where('o.is_del',0)->where('o.is_system_del',0);
         $model = $model->field("u.uid,u.nickname,u.avatar,from_unixtime(u.add_time,'%Y/%m/%d') as time,u.spread_count as childCount,COUNT(o.id) as orderCount,SUM(o.pay_price) as numberCount");
         if(strlen(trim($keyword))) $model = $model->where('u.nickname|u.phone','like',"%$keyword%");
         $model = $model->group('u.uid');
@@ -464,6 +483,15 @@ class User extends BaseModel
         else return [];
     }
 
+    /**
+     * 设置用户的上级关系
+     * @param $uid 用户uid
+     * @param $spreadUid 上级用户uid
+     * @return User|bool
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\ModelNotFoundException
+     * @throws \think\exception\DbException
+     */
     public static function setSpreadUid($uid,$spreadUid)
     {
         // 自己不能绑定自己为上级
@@ -561,4 +589,86 @@ class User extends BaseModel
     {
         return self::be(['account'=>$phone]);
     }
+
+
+    /**
+     * 获取推广人
+     * @param $data 查询条件
+     * @return array
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\ModelNotFoundException
+     * @throws \think\exception\DbException
+     */
+    public static function getRankList($data)
+    {
+        switch ($data['type']){
+            case 'week':
+                $startTime = strtotime('this week');
+                $endTime = time();
+                break;
+            case 'month':
+                $startTime = strtotime('last month');
+                $endTime = time();
+                break;
+        }
+        $t4Sql = self::alias('t0')
+            ->field('t0.uid,t0.spread_uid,count(t1.spread_uid) AS count,t0.add_time,t0.nickname,t0.avatar')
+            ->join('user t1','t0.uid = t1.spread_uid','LEFT')
+            ->group('t0.uid')
+            ->fetchSql(true)
+            ->select();
+        $t5Sql = self::alias('t2')
+            ->field('t2.uid,t2.spread_uid,count(t3.spread_uid) AS count,t2.add_time,t2.nickname,t2.avatar')
+            ->join('user t3','t2.uid = t3.spread_uid','LEFT')
+            ->group('t2.uid')
+            ->fetchSql(true)
+            ->select();
+        $list = self::table("($t4Sql)")
+            ->alias('t4')
+            ->join('('.$t5Sql.') t5','t4.uid = t5.spread_uid')
+            ->field('t4.uid, t4.count,t4.nickname,t4.avatar')
+            ->where('t4.count','>',0)
+            ->where('t4.add_time','BETWEEN',[$startTime,$endTime])
+            ->group('t4.uid')
+            ->page($data['page'],$data['limit'])
+            ->order('t4.count,t4.add_time desc')
+            ->select();
+        return count($list) ? $list->toArray() : [];
+    }
+
+    /**
+     * 获取佣金排行
+     * @param $data
+     * @return array
+     */
+    public static  function brokerageRank($data){
+        $model = self::where('status',1);
+        switch ($data['type']){
+            case 'week':
+                $model = $model->whereIn('uid',function ($query){
+                    $query->name('user_bill')->where('category','now_money')->where('type','brokerage')
+                        ->whereWeek('add_time')->field('uid');
+                });
+                break;
+            case 'month':
+                $model = $model->whereIn('uid',function ($query){
+                    $query->name('user_bill')->where('category','now_money')->where('type','brokerage')
+                        ->whereMonth('add_time')->field('uid');
+                });
+                break;
+        }
+        $users= $model->field('uid,nickname,avatar,brokerage_price')->order('brokerage_price desc')
+            ->page((int)$data['page'],(int)$data['limit'])->select();
+        return  count($users) ? $users->toArray() : [];
+    }
+
+    /**
+     * 获取当前用户的佣金排行位置
+     * @param $uid
+     * @return int
+     */
+    public static function currentUserRank($brokerage_price)
+    {
+        return  self::where('brokerage_price','>',$brokerage_price)->count('uid');
+    }
 }

+ 32 - 0
crmeb/app/models/user/UserAddress.php

@@ -40,6 +40,12 @@ class UserAddress extends BaseModel
         return time();
     }
 
+    /**
+     * 设置默认收货地址
+     * @param $id 地址id
+     * @param $uid 用户uid
+     * @return bool
+     */
     public static function setDefaultAddress($id,$uid)
     {
         self::beginTrans();
@@ -50,6 +56,12 @@ class UserAddress extends BaseModel
         return $res;
     }
 
+    /**
+     * 设置用户地址查询初始条件
+     * @param null $model
+     * @param string $prefix
+     * @return \think\Model
+     */
     public static function userValidAddressWhere($model=null,$prefix = '')
     {
         if($prefix) $prefix .='.';
@@ -57,12 +69,32 @@ class UserAddress extends BaseModel
         return $model->where("{$prefix}is_del",0);
     }
 
+    /**
+     * 获取用户收货地址并分页
+     * @param $uid 用户uid
+     * @param int $page 页码
+     * @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 getUserValidAddressList($uid,$page=1,$limit=8,$field = '*')
     {
         if($page) return self::userValidAddressWhere()->where('uid',$uid)->order('add_time DESC')->field($field)->page((int)$page,(int)$limit)->select()->toArray()?:[];
         else return self::userValidAddressWhere()->where('uid',$uid)->order('add_time DESC')->field($field)->select()->toArray()?:[];
     }
 
+    /**
+     * 获取用户默认收货地址
+     * @param $uid 用户uid
+     * @param string $field 展示字段
+     * @return array|\think\Model|null
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\ModelNotFoundException
+     * @throws \think\exception\DbException
+     */
     public static function getUserDefaultAddress($uid,$field = '*')
     {
         return self::userValidAddressWhere()->where('uid',$uid)->where('is_default',1)->field($field)->find();

+ 14 - 11
crmeb/app/models/user/UserExtract.php

@@ -50,12 +50,12 @@ class UserExtract extends BaseModel
         1 =>'已提现'
     );
 
-    /*
+    /**
      * 用户自主提现记录提现记录,后台执行审核
      * @param array $userInfo 用户个人信息
      * @param array $data 提现详细信息
-     * @return boolean
-     * */
+     * @return bool
+     */
     public static function userExtract($userInfo,$data){
         if(!in_array($data['extract_type'],self::$extractType))
             return self::setErrorInfo('提现方式不存在');
@@ -135,13 +135,16 @@ class UserExtract extends BaseModel
         return self::where('uid',$uid)->where('status',$status)->value('SUM(extract_price)')?:0;
     }
 
-    /*
+    /**
      * 用户提现记录列表
      * @param int $uid 用户uid
      * @param int $first 截取行数
      * @param int $limit 截取数
-     * @return array
-     * */
+     * @return \think\Collection
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\ModelNotFoundException
+     * @throws \think\exception\DbException
+     */
     public static function extractList($uid,$first = 0,$limit = 8)
     {
         $list=UserExtract::where('uid',$uid)->order('add_time desc')->limit($first,$limit)->select();
@@ -151,11 +154,11 @@ class UserExtract extends BaseModel
         return $list;
     }
 
-    /*
-   * 获取累计已提现佣金
-   * @param int $uid
-   * @return float
-   * */
+    /**
+     * 获取累计已提现佣金
+     * @param $uid
+     * @return float
+     */
     public static function extractSum($uid)
     {
         return self::where('uid',$uid)->where('status',1)->sum('extract_price');

+ 45 - 27
crmeb/app/models/user/UserLevel.php

@@ -27,9 +27,11 @@ class UserLevel extends BaseModel
 
     use ModelTrait;
 
-    /*
-    * 获取用户等级人数
-    * */
+    /**
+     * 获取用户等级人数
+     * @param $uids
+     * @return int
+     */
     public static function setUserLevelCount($uids)
     {
         $model=new self();
@@ -38,12 +40,12 @@ class UserLevel extends BaseModel
         return $model->count();
     }
 
-    /*
+    /**
      * 设置查询初始化条件
      * @param string $alias 表别名
-     * @param object $model 模型实例化对象
-     * @return object
-     * */
+     * @param null $model 模型实例化对象
+     * @return UserLevel
+     */
     public static function valiWhere($alias='',$model=null)
     {
         $model=is_null($model) ? new self() : $model;
@@ -53,12 +55,16 @@ class UserLevel extends BaseModel
         }
         return $model->where("{$alias}status", 1)->where("{$alias}is_del", 0);
     }
-    /*
+
+    /**
      * 设置会员等级
-     * @param int $uid 用户uid
-     * @param int $level_id 等级id
-     * @return boolean | array
-     * */
+     * @param $uid 用户uid
+     * @param $level_id 等级id
+     * @return UserLevel|bool|\think\Model
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\ModelNotFoundException
+     * @throws \think\exception\DbException
+     */
     public static function setUserLevel($uid,$level_id){
         $vipinfo=SystemUserLevel::get($level_id);
         if(!$vipinfo) return false;
@@ -101,11 +107,15 @@ class UserLevel extends BaseModel
         }
     }
 
-    /*
+    /**
      * 获取当前用户会员等级返回当前用户等级id
-     * @param int $uid 用户uid
-     * @return int 会员id
-     * */
+     * @param $uid 用户uid
+     * @param int $grade 会员id
+     * @return bool|mixed
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\ModelNotFoundException
+     * @throws \think\exception\DbException
+     */
     public static function getUserLevel($uid,$grade=0)
     {
         $model = self::valiWhere();
@@ -125,12 +135,15 @@ class UserLevel extends BaseModel
             return $level->id;
     }
 
-    /*
+    /**
      * 获取会员详细信息
-     * @param int $id 会员记录id
+     * @param $id 会员记录id
      * @param string $keyName 字段名
-     * @return array
-     * */
+     * @return array|mixed|string|\think\Model|null
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\ModelNotFoundException
+     * @throws \think\exception\DbException
+     */
     public static function getUserLevelInfo($id,$keyName=''){
         $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();
@@ -138,20 +151,25 @@ class UserLevel extends BaseModel
         return $vipinfo;
     }
 
-    /*
+    /**
      * 获取当前用户已成为的vip id
-     * @param int $uid 用户id
+     * @param $uid 用户id
      * @return array
-     * */
+     */
     public static function getUserLevelIds($uid)
     {
        return self::valiWhere()->group('level_id')->where('uid',$uid)->order('grade asc')->column('level_id','level_id');
     }
-
-    /*
+    
+    /**
      * 检查是否能成为会员
-     * @param int $uid 用户
-     * */
+     * @param $uid 用户uid
+     * @param bool $leveNowId
+     * @return UserLevel|bool|\think\Model
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\ModelNotFoundException
+     * @throws \think\exception\DbException
+     */
     public static function setLevelComplete($uid,$leveNowId=false)
     {
         $user=User::where('uid',$uid)->find();

+ 29 - 4
crmeb/app/models/user/UserRecharge.php

@@ -40,13 +40,27 @@ class UserRecharge extends BaseModel
         return time();
     }
 
+    /**
+     * 创建充值订单
+     * @param $uid
+     * @param $price
+     * @param string $recharge_type
+     * @param int $paid
+     * @return UserRecharge|bool|\think\Model
+     */
     public static function addRecharge($uid,$price,$recharge_type = 'weixin',$paid = 0)
     {
         $order_id = self::getNewOrderId($uid);
+        if(!$order_id) return self::setErrorInfo('订单生成失败!');
         $add_time = time();
         return self::create(compact('order_id','uid','price','recharge_type','paid','add_time'));
     }
 
+    /**
+     * 生成充值订单号
+     * @param int $uid
+     * @return bool|string
+     */
     public static function getNewOrderId($uid = 0)
     {
         if(!$uid) return false;
@@ -54,6 +68,12 @@ class UserRecharge extends BaseModel
         return 'wx' . date('YmdHis', time()) . (10000 + $count + $uid);
     }
 
+    /**
+     * 充值js支付
+     * @param $orderInfo
+     * @return array|string
+     * @throws \Exception
+     */
     public static function jsPay($orderInfo)
     {
         return MiniProgramService::jsPay(WechatUser::uidToOpenid($orderInfo['uid']),$orderInfo['order_id'],$orderInfo['price'],'user_recharge','用户充值');
@@ -99,11 +119,16 @@ class UserRecharge extends BaseModel
         return $res;
     }
 
-    /*
+    /**
      * 导入佣金到余额
-     * @param int uid 用户uid
-     * @param string $price 导入金额
-     * */
+     * @param $uid 用户uid
+     * @param $price 导入金额
+     * @return bool
+     * @throws \think\Exception
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\ModelNotFoundException
+     * @throws \think\exception\DbException
+     */
     public static function importNowMoney($uid,$price){
         $user = User::getUserInfo($uid);
         self::beginTrans();

+ 47 - 61
crmeb/app/models/user/UserSign.php

@@ -25,96 +25,83 @@ class UserSign extends BaseModel
     protected $name = 'user_sign';
 
     use ModelTrait;
-    /*
+
+    /**
      * 设置签到数据
-     * @param int $uid 用户uid
+     * @param $uid 用户uid
      * @param string $title 签到说明
      * @param int $number 签到获得积分
      * @param int $balance 签到前剩余积分
-     * @return object
-     * */
+     * @return bool
+     */
     public static function setSignData($uid,$title='',$number=0,$balance=0)
     {
         $add_time=time();
         return self::create(compact('uid','title','number','balance','add_time')) && UserBill::income($title,$uid,'integral','sign',$number,0,$balance,$title);
     }
 
-    /*
+    /**
      * 分页获取用户签到数据
-     * @param int $uid 用户uid
-     * @param int $page 页码
-     * @param int $limit 显示多少条
-     * @return array
-     * */
+     * @param $uid 用户uid
+     * @param $page 页码
+     * @param $limit 展示条数
+     * @return array|\think\Collection
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\ModelNotFoundException
+     * @throws \think\exception\DbException
+     */
     public static function getSignList($uid,$page,$limit)
     {
         if(!$limit) return [];
-        if($page){
-            return UserBill::where('a.category','integral')
-                ->where('a.type','sign')
-                ->where('a.status',1)
-                ->where('a.uid',$uid)
-                ->alias('a')
-                ->join("__user__ u",'u.uid=a.uid')
-                ->order('a.add_time desc')
-                ->field('FROM_UNIXTIME(a.add_time,"%Y-%m-%d") as add_time,a.title,a.number')
-                ->page((int)$page,(int)$limit)
-                ->select();
-        }else{
-            return UserBill::where('a.category','integral')
-                ->where('a.type','sign')
-                ->where('a.status',1)
-                ->where('a.uid',$uid)
-                ->alias('a')
-                ->join("__user__ u",'u.uid=a.uid')
-                ->order('a.add_time desc')
-                ->field('FROM_UNIXTIME(a.add_time,"%Y-%m-%d") as add_time,a.title,a.number')
-                ->select();
-        }
+        $billModel = UserBill::where('a.category','integral')->where('a.type','sign')
+            ->where('a.status',1)->where('a.uid',$uid)->alias('a')
+            ->join("__user__ u",'u.uid=a.uid')
+            ->order('a.add_time desc')->field('FROM_UNIXTIME(a.add_time,"%Y-%m-%d") as add_time,a.title,a.number');
+        if($page) $billModel = $billModel->page((int)$page,(int)$limit);
+        return $billModel->select();
     }
 
-    /*
+    /**
      * 获取用户累计签到次数
-     * @Parma int $uid 用户id
+     * @param $uid
      * @return int
-     * */
+     */
     public static function getSignSumDay($uid)
     {
         return self::where('uid', $uid)->count();
     }
 
-    /*
-     * 获取用户今天是否签到
-     * @param int $uid
-     * */
-    public static function getToDayIsSign($uid)
-    {
-        return self::where('uid', $uid)->whereTime('add_time','today')->count() ? true : false;
-    }
-
-    /*
-     * 获取用户昨天是否签到
-     * @param int $uid
-     * */
-    public static function getYesterDayIsSign($uid)
+    /**
+     * 获取用户是否签到
+     * @param $uid
+     * @return bool
+     */
+    public static function getIsSign($uid,string $type = 'today')
     {
-        return self::where('uid', $uid)->whereTime('add_time','yesterday')->count() ? true : false;
+        return self::where('uid', $uid)->whereTime('add_time',$type)->count() ? true : false;
     }
 
-    /*
+    /**
      * 获取签到配置
-     * @param string
-     * */
+     * @param string $key
+     * @return array
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\ModelNotFoundException
+     * @throws \think\exception\DbException
+     */
     public static function getSignSystemList($key='sign_day_num')
     {
         return \crmeb\services\GroupDataService::getData($key) ? : [];
     }
 
-    /*
+    /**
      * 用户签到
-     * @param int $uid 用户uid
-     * @return boolean
-     * */
+     * @param $uid
+     * @return bool|int
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\ModelNotFoundException
+     * @throws \think\exception\DbException
+     */
     public static function sign($uid)
     {
         $sign_list=self::getSignSystemList();
@@ -122,7 +109,7 @@ class UserSign extends BaseModel
         $user=User::where('uid',$uid)->find();
         $sign_num=0;
         //检测昨天是否签到
-        if(self::getYesterDayIsSign($uid)){
+        if(self::getIsSign($uid,'yesterday')){
             if($user->sign_num > (count($sign_list) -1)) $user->sign_num=0;
         }else{
             //如果昨天没签到,回退到第一天
@@ -138,11 +125,10 @@ class UserSign extends BaseModel
         if($user->sign_num == count($sign_list))
             $res1 = self::setSignData($uid,'连续签到奖励',$sign_num,$user->integral);
         else
-//            $res1 = self::setSignData($uid,'用户连续签到第'.(self::getSignSumDay($uid)+1).'天',$sign_num,$user->integral);
             $res1 = self::setSignData($uid,'签到奖励',$sign_num,$user->integral);
         $res2= User::bcInc($uid,'integral',$sign_num,'uid');
-        $res3=$user->save();
-        $res = $res1 && $res2 && $res3!==false;
+        $res3= $user->save();
+        $res = $res1 && $res2 && $res3 !== false;
         BaseModel::checkTrans($res);
         event('UserLevelAfter',[$user]);
         if($res)

+ 6 - 5
crmeb/app/models/user/UserTaskFinish.php

@@ -31,12 +31,13 @@ class UserTaskFinish extends BaseModel
     protected $name = 'user_task_finish';
 
     use ModelTrait;
-    /*
+
+    /**
      * 设置任务完成情况
-     * @param int $uid 用户uid
-     * @param int $task_id 任务id
-     * @return Boolean
-     * */
+     * @param $uid 用户uid
+     * @param $task_id 任务id
+     * @return UserTaskFinish|bool|\think\Model
+     */
     public static function setFinish($uid,$task_id)
     {
         $add_time=time();

+ 6 - 0
crmeb/app/models/user/UserToken.php

@@ -25,6 +25,12 @@ class UserToken extends Model
             $token['login_ip'] = app()->request->ip();
     }
 
+    /**
+     * 创建token并且保存
+     * @param User $user
+     * @param $type
+     * @return UserToken
+     */
     public static function createToken(User $user, $type): self
     {
         $tokenInfo = $user->getToken($type);

+ 29 - 25
crmeb/app/models/user/WechatUser.php

@@ -35,6 +35,11 @@ class WechatUser extends BaseModel
 
     use ModelTrait;
 
+    /**
+     * uid获取小程序Openid
+     * @param string $uid
+     * @return bool|mixed
+     */
     public static function getOpenId($uid = ''){
         if($uid == '') return false;
         return self::where('uid',$uid)->value('routine_openid');
@@ -71,43 +76,40 @@ class WechatUser extends BaseModel
      * @return mixed
      */
     public static function routineOauth($routine){
-        $routineInfo['nickname'] = filterEmoji($routine['nickName']);//姓名
-        $routineInfo['sex'] = $routine['gender'];//性别
-        $routineInfo['language'] = $routine['language'];//语言
-        $routineInfo['city'] = $routine['city'];//城市
-        $routineInfo['province'] = $routine['province'];//省份
-        $routineInfo['country'] = $routine['country'];//国家
-        $routineInfo['headimgurl'] = $routine['avatarUrl'];//头像
-//        $routineInfo[''] = $routine['code'];//临时登录凭证  是获取用户openid和session_key(会话密匙)
+        $routineInfo['nickname']    = filterEmoji($routine['nickName']);//姓名
+        $routineInfo['sex']         = $routine['gender'];//性别
+        $routineInfo['language']    = $routine['language'];//语言
+        $routineInfo['city']        = $routine['city'];//城市
+        $routineInfo['province']    = $routine['province'];//省份
+        $routineInfo['country']     = $routine['country'];//国家
+        $routineInfo['headimgurl']  = $routine['avatarUrl'];//头像
         $routineInfo['routine_openid'] = $routine['openId'];//openid
         $routineInfo['session_key'] = $routine['session_key'];//会话密匙
-        $routineInfo['unionid'] = $routine['unionId'];//用户在开放平台的唯一标识符
-        $routineInfo['user_type'] = 'routine';//用户类型
-        $page = '';//跳转小程序的页面
+        $routineInfo['unionid']     = $routine['unionId'];//用户在开放平台的唯一标识符
+        $routineInfo['user_type']   = 'routine';//用户类型
         $spid = 0;//绑定关系uid
-        $isCOde=false;
+        $isCOde = false;
         //获取是否有扫码进小程序
         if($routine['code']){
-            $info = RoutineQrcode::getRoutineQrcodeFindType($routine['code']);
-            if($info){
+            if($info = RoutineQrcode::getRoutineQrcodeFindType($routine['code'])){
                 $spid = $info['third_id'];
-                $page = $info['page'];
                 $isCOde=true;
-            }else{
+            }else
                 $spid = $routine['spid'];
-            }
-        }else if($routine['spid']) $spid = $routine['spid'];
+        }else if($routine['spid'])
+            $spid = $routine['spid'];
+
         //  判断unionid  存在根据unionid判断
         if($routineInfo['unionid'] != '' && ($uid=self::where(['unionid'=>$routineInfo['unionid']])->where('user_type','<>','h5')->value('uid'))){
             self::edit($routineInfo,$uid,'uid');
-            $routineInfo['code']=$spid;
-            $routineInfo['isPromoter']=$isCOde;
+            $routineInfo['code']        = $spid;
+            $routineInfo['isPromoter']  = $isCOde;
             if($routine['login_type']) $routineInfo['login_type'] = $routine['login_type'];
             User::updateWechatUser($routineInfo,$uid);
         }else if($uid = self::where(['routine_openid'=>$routineInfo['routine_openid']])->where('user_type','<>','h5')->value('uid')){ //根据小程序openid判断
             self::edit($routineInfo,$uid,'uid');
-            $routineInfo['code']=$spid;
-            $routineInfo['isPromoter']=$isCOde;
+            $routineInfo['code']        = $spid;
+            $routineInfo['isPromoter']  = $isCOde;
             if($routine['login_type']) $routineInfo['login_type'] = $routine['login_type'];
             User::updateWechatUser($routineInfo,$uid);
         }else{
@@ -116,9 +118,7 @@ class WechatUser extends BaseModel
             $res = User::setRoutineUser($routineInfo,$spid);
             $uid = $res->uid;
         }
-        $data['page'] = $page;
-        $data['uid'] = $uid;
-        return $data;
+        return $uid;
     }
     /**
      * 判断是否是小程序用户
@@ -183,6 +183,10 @@ class WechatUser extends BaseModel
         if($couponId) StoreCouponUser::addUserCoupon(self::openidToUid($openid),$couponId);
     }
 
+    /**
+     * 订单金额达到预设金额赠送优惠卷
+     * @param $uid
+     */
     public static function userTakeOrderGiveCoupon($uid)
     {
         $couponId = SystemConfigService::get('store_order_give_coupon');

+ 1 - 1
crmeb/config/app.php

@@ -38,7 +38,7 @@ return [
     'default_timezone' => 'Asia/Shanghai',
 
     // 异常页面的模板文件
-    'exception_tmpl'   => app()->getThinkPath() . 'tpl/think_exception.tpl',
+    'exception_tmpl'   => app()->getRootPath() . 'public/static/exception.tpl',
 
     // 错误显示信息,非调试模式有效
     'error_message'    => '页面错误!请稍后再试~',

+ 1 - 1
crmeb/config/cache.php

@@ -28,7 +28,7 @@ return [
             // 缓存前缀
             'prefix'     => '',
             // 缓存有效期 0表示永久缓存
-            'expire'     => 0,
+            'expire'  => 0,
             // 缓存标签前缀
             'tag_prefix' => 'tag:',
             // 序列化机制 例如 ['serialize', 'unserialize']

+ 1 - 1
crmeb/config/session.php

@@ -21,7 +21,7 @@ return [
     // 驱动方式 支持file redis memcache memcached
     'type'           => 'file',
     // 过期时间
-    'expire'         => 0,
+    'expire'         => 10800,
     // 前缀
     'prefix'         => '',
 ];

+ 14 - 1
crmeb/crmeb/exceptions/AuthException.php

@@ -6,7 +6,20 @@ namespace crmeb\exceptions;
 
 use Throwable;
 
-class AuthException extends \Exception
+/**
+ * Class AuthException
+ * @package crmeb\exceptions
+ */
+class AuthException extends \RuntimeException
 {
+    public function __construct($message = "", $code = 0, Throwable $previous = null)
+    {
+        if(is_array($message)){
+            $errInfo = $message;
+            $message = $errInfo[0] ?? '未知错误';
+            $code    = $errInfo[1] ?? 400;
+        }
 
+        parent::__construct($message, $code, $previous);
+    }
 }

+ 1 - 12
crmeb/crmeb/interfaces/ProviderInterface.php

@@ -1,22 +1,11 @@
 <?php
-/**
- * Created by CRMEB.
- * User: 136327134@qq.com
- * Date: 2019/4/9
- * Time: 14:18
- */
+
 
 namespace crmeb\interfaces;
 
-/*
- * 工厂模式服务注册接口类
- *
- * */
 
 interface ProviderInterface
 {
-
     public function register($config);
-
 }
 

+ 26 - 0
crmeb/crmeb/services/ApiErrorCode.php

@@ -0,0 +1,26 @@
+<?php
+/**
+ * Created by CRMEB.
+ * User: 136327134@qq.com
+ * Date: 2019/4/12 11:19
+ */
+
+namespace crmeb\services;
+
+
+
+/**
+ * 错误码统一存放类
+ * Class ApiErrorCode
+ * @package crmeb\services
+ */
+class ApiErrorCode
+{
+
+    const SUCCESS = [200,'SUCCESS'];
+    const ERROR   = [400,'操作失败'];
+
+    const ERR_LOGIN = [40010,'登陆过期'];
+
+
+}

+ 0 - 2
crmeb/crmeb/services/CustomerService.php

@@ -78,8 +78,6 @@ class CustomerService
                     }
                 }
 
-
-
             }
         }
     }

+ 1 - 1
crmeb/crmeb/services/FileService.php

@@ -732,7 +732,7 @@ class FileService
     {
         $dir = array();
         $dir['filename']   = basename($file);//返回路径中的文件名部分。
-        $dir['pathname']   = realpath($file);//返回绝对路径名。
+        $dir['pathname']   = strstr(php_uname('s'),'Windows') ? str_replace('\\','\\\\',realpath($file)) : realpath($file);//返回绝对路径名。
         $dir['owner']      = fileowner($file);//文件的 user ID (所有者)。
         $dir['perms']      = fileperms($file);//返回文件的 inode 编号。
         $dir['inode']      = fileinode($file);//返回文件的 inode 编号。

+ 24 - 2
crmeb/crmeb/services/SMSService.php

@@ -22,14 +22,36 @@ class SMSService
 
     //短信支付回调地址
     private static $payNotify;
-
-    const VERIFICATION_CODE = 518076;
+    //验证码
+    const VERIFICATION_CODE         = 518076;
+    //支付成功
+    const PAY_SUCCESS_CODE          = 520268;
+    //发货提醒
+    const DELIVER_GOODS_CODE        = 520269;
+    //确认收货提醒
+    const TAKE_DELIVERY_CODE        = 520271;
+    //管理员下单提醒
+    const ADMIN_PLACE_ORDER_CODE    = 520272;
+    //管理员退货提醒
+    const ADMIN_RETURN_GOODS_CODE   = 520274;
+    //管理员支付成功提醒
+    const ADMIN_PAY_SUCCESS_CODE    = 520273;
+    //管理员确认收货
+    const ADMIN_TAKE_DELIVERY_CODE  = 520422;
 
     public function __construct()
     {
         self::$status = strlen(SystemConfigService::get('sms_account')) != 0 ?? false && strlen(SystemConfigService::get('sms_token')) != 0  ?? false;
     }
 
+    public static function getConstants($code = '')
+    {
+        $oClass = new \ReflectionClass(__CLASS__);
+        $stants = $oClass->getConstants();
+        if ($code) return isset($stants[$code]) ? $stants[$code] : '';
+        else return $stants;
+    }
+
     private static function auto()
    {
        self::$SMSAccount = SystemConfigService::get('sms_account');

+ 292 - 176
crmeb/crmeb/services/UploadService.php

@@ -17,11 +17,130 @@ use think\File;
 
 class UploadService
 {
+    /**
+     * 文件校验
+     * @var bool
+     */
+    protected $autoValidate = false;
+
+    /**
+     * 上传路径
+     * @var string
+     */
+    protected $uploadPath;
+
+    /**
+     * 上传类型
+     * @var int
+     */
+    protected $uploadType;
 
+    /**
+     * 发生错误时是否返回错误信息
+     * @var bool
+     */
+    protected $returnErr = false;
+
+    /**
+     * 上传文件返回数组初始值
+     * @var array
+     */
+    protected $uploadInfo = [
+        'name'      => '',
+        'size'      => 0,
+        'type'      => 'image/jpeg',
+        'dir'       => '',
+        'thumb_path'=> '',
+        'image_type'=> '',
+        'time'      => 0,
+    ];
+
+    /**
+     * 上传信息
+     * @var object
+     */
     private static $uploadStatus;
 
-    //上传图片的大小 2MB 单位字节
-    private static $imageValidate = 'filesize:2097152|fileExt:jpg,jpeg,png,gif|fileMime:image/jpeg,image/gif,image/png';
+    /**
+     * 本类实例化
+     * @var
+     */
+    protected static $instance;
+
+    /**
+     * 上传图片的大小 2MB 单位字节
+     * @var string
+     */
+    protected $imageValidate = 'filesize:2097152|fileExt:jpg,jpeg,png,gif,pem|fileMime:image/jpeg,image/gif,image/png,text/plain';
+
+    protected function __construct()
+    {
+        self::init();
+    }
+
+    /**
+     * @return UploadService
+     */
+    public static function getInstance()
+    {
+        if(is_null(self::$instance)) self::$instance = new self();
+        return self::$instance;
+    }
+
+    /**
+     * 设置上传图片大小等验证信息
+     * @param string $imageValidate
+     * @return $this
+     */
+    public function setImageValidate(string $imageValidate)
+    {
+        $this->imageValidate = $imageValidate;
+        return $this;
+    }
+
+    /**
+     * 设置是否校验上传文件
+     * @param bool $autoValidate
+     * @return $this
+     */
+    public function setAutoValidate(bool $autoValidate)
+    {
+        $this->autoValidate = $autoValidate;
+        return $this;
+    }
+
+    /**
+     * 设置上传路径
+     * @param string $uploadPath
+     * @return $this
+     */
+    public function setUploadPath(string $uploadPath)
+    {
+        $this->uploadPath = $uploadPath;
+        return $this;
+    }
+
+    /**
+     * 设置上传类型
+     * @param int $uploadType
+     * @return $this
+     */
+    public function setUploadType(int $uploadType)
+    {
+        $this->uploadType = $uploadType;
+        return $this;
+    }
+
+    /**
+     * 设置发生错误时是否返回错误信息
+     * @param bool $returnErr
+     * @return $this
+     */
+    public function serReturnErr(bool $returnErr)
+    {
+        $this->returnErr = $returnErr;
+        return $this;
+    }
 
     /**
      * 初始化
@@ -51,16 +170,7 @@ class UploadService
     protected static function successful($path)
     {
         self::$uploadStatus->status = true;
-//        $filePath = DS . $path . DS . $fileInfo->getSaveName();
         self::$uploadStatus->filePath = '/uploads/' . $path;
-//        self::$uploadStatus->fileInfo = $fileInfo;
-//        self::$uploadStatus->uploadPath = $path;
-//        if(strpos(app()->getRootPath().'public'.DS,'public') !== false){
-//        self::$uploadStatus->dir = $filePath;
-//        }else{
-//            self::$uploadStatus->dir = str_replace('/public','',$filePath);
-//        }
-//        self::$uploadStatus->status = true;
         return self::$uploadStatus;
     }
 
@@ -74,15 +184,6 @@ class UploadService
         return is_dir($dir) == true || mkdir($dir, 0777, true) == true;
     }
 
-    /**
-     * 开启/关闭上出文件验证
-     * @param bool $bool
-     */
-    protected static function autoValidate($bool = false)
-    {
-        self::$autoValidate = $bool;
-    }
-
     /**
      * 生成上传文件目录
      * @param $path
@@ -98,144 +199,151 @@ class UploadService
     /**
      * 单图上传
      * @param string $fileName 上传文件名
-     * @param string $path 上传路径
-     * @param bool $moveName 生成文件名
-     * @param bool $autoValidate 是否开启文件验证
-     * @param null $root 上传根目录路径
-     * @param string $rule 文件名自动生成规则
-     * @param int $type
      * @return mixed
      */
-    public static function image($fileName, $path, $moveName = true, $autoValidate = true, $root = null, $rule = 'uniqid',$uploadType = null)
+    public function image($fileName)
     {
-        $uploadType = $uploadType ? $uploadType : SystemConfigService::get('upload_type');
-        //TODO 没有选择默认使用本地上传
-        if (!$uploadType) $uploadType = 1;
         $info = [];
+        try{
+            $uploadType = $this->uploadType ? : SystemConfigService::get('upload_type');
+            //TODO 没有选择默认使用本地上传
+            if (!$uploadType) $uploadType = 1;
+            switch ($uploadType) {
+                case 1 :
+                    $info = $this->uploadLocaFile($fileName);
+                    if(is_string($info)) return $info;
+                    break;
+                case 2 :
+                    $keys = Qiniu::uploadImage($fileName);
+                    if (is_array($keys)) {
+                        foreach ($keys as $key => &$item) {
+                            if (is_array($item)) {
+                                $info = Qiniu::imageUrl($item['key']);
+                                $info = $this->setUploadInfo($info['dir'],2,$item['key'],UtilService::setHttpType($info['thumb_path']));
+                            }
+                        }
+                    } else return $keys;
+                    break;
+                case 3 :
+                    $serverImageInfo = OSS::uploadImage($fileName);
+                    if (!is_array($serverImageInfo)) return $serverImageInfo;
+                    $info = $this->setUploadInfo(UtilService::setHttpType($serverImageInfo['info']['url']),3,substr(strrchr($serverImageInfo['info']['url'], '/'), 1));
+                    break;
+                case 4 :
+                    list($imageUrl,$serverImageInfo) = COS::uploadImage($fileName);
+                    if (!is_array($serverImageInfo) && !is_object($serverImageInfo)) return $serverImageInfo;
+                    $info = $this->setUploadInfo($imageUrl,4,substr(strrchr($imageUrl, '/'), 1));
+                    break;
+                default:
+                    $info = $this->uploadLocaFile($fileName);
+                    if(is_string($info)) return $info;
+                    break;
+            }
+            $this->uploadPath = '';
+            $this->autoValidate = true;
+        }catch (\Exception $e){
+            return $e->getMessage();
+        }
+        return $info;
+    }
+
+    /**
+     * 获取图片类型和大小
+     * @param string $url 图片地址
+     * @param int $type 类型
+     * @param bool $isData 是否真实获取图片信息
+     * @return array
+     */
+    public static function getImageHeaders(string $url,$type = 1,$isData = true){
         stream_context_set_default( [
             'ssl' => [
                 'verify_peer' => false,
                 'verify_peer_name' => false,
             ],
         ]);
-        switch ($uploadType) {
-            case 1 :
-                self::init();
-//                $path = self::uploadDir($path, $root);
-//                $dir = app()->getRootPath() . $path;
-//                if (!self::validDir($dir)) return '生成上传目录失败,请检查权限!';
-//                if (!isset($_FILES[$fileName])) return '上传文件不存在!';
-                $file = request()->file($fileName);
-                if (!$file) return '上传文件不存在!';
-                if ($autoValidate) {
-                    try {
-                        validate([$fileName => self::$imageValidate])->check([$fileName => $file]);
-                    } catch (ValidateException $e) {
-                        return $e->getMessage();
-                    }
-                }
-                $fileName = Filesystem::putFile($path, $file);
-                if (!$fileName)
-                    return '图片上传失败!';
-                $filePath = Filesystem::path($fileName);
-                $fileInfo = new File($filePath);
-                $info["code"] = 200;
-                $info["name"] = $fileInfo->getFilename();
-                $info["dir"] = str_replace('\\','/', '/uploads/' . $fileName);
-                $info["time"] = time();
-                $info["size"] = $fileInfo->getSize();
-                $info["type"] = $fileInfo->getMime();
-                $info["image_type"] = 1;
-                $info['thumb_path'] = str_replace('\\','/',self::thumb('.'.$info["dir"]));
-                break;
-            case 2 :
-                $keys = Qiniu::uploadImage($fileName);
-                if (is_array($keys)) {
-                    foreach ($keys as $key => &$item) {
-                        if (is_array($item)) {
-                            $info = Qiniu::imageUrl($item['key']);
-                            $info['dir'] = UtilService::setHttpType($info['dir']);
-                            $info['thumb_path'] = UtilService::setHttpType($info['thumb_path']);
-                            $headerArray = get_headers(UtilService::setHttpType($info['dir'], 1), true);
-                            $info['size'] = is_array($headerArray['Content-Type']) && count($headerArray['Content-Length']) == 2 ? $headerArray['Content-Length'][1] : (string)$headerArray['Content-Length'];
-                            $info['type'] = is_array($headerArray['Content-Type']) && count($headerArray['Content-Type']) == 2 ? $headerArray['Content-Type'][1] : (string)$headerArray['Content-Type'];
-                            $info['image_type'] = 2;
-                        }
-                    }
-                } else return $keys;
-                break;
-            case 3 :
-                $serverImageInfo = OSS::uploadImage($fileName);
-                if (!is_array($serverImageInfo)) return $serverImageInfo;
-                $info['code'] = 200;
-                $info['name'] = substr(strrchr($serverImageInfo['info']['url'], '/'), 1);
-                $serverImageInfo['info']['url'] = UtilService::setHttpType($serverImageInfo['info']['url']);
-                $info['dir'] = $serverImageInfo['info']['url'];
-                $info['thumb_path'] = $serverImageInfo['info']['url'];
-                $headerArray = get_headers(UtilService::setHttpType($serverImageInfo['info']['url'], 1), true);
-                $info['size'] = $headerArray['Content-Length'];
-                $info['type'] = $headerArray['Content-Type'];
-                $info['time'] = time();
-                $info['image_type'] = 3;
-                break;
-            case 4 :
-                list($imageUrl,$serverImageInfo) = COS::uploadImage($fileName);
-                if (!is_array($serverImageInfo) && !is_object($serverImageInfo)) return $serverImageInfo;
-                if (is_object($serverImageInfo)) $serverImageInfo = $serverImageInfo->toArray();
-                $serverImageInfo['ObjectURL'] = $imageUrl;
-                $info['code'] = 200;
-                $info['name'] = substr(strrchr($serverImageInfo['ObjectURL'], '/'), 1);
-                $info['dir'] = $serverImageInfo['ObjectURL'];
-                $info['thumb_path'] = $serverImageInfo['ObjectURL'];
-                $headerArray = get_headers(UtilService::setHttpType($serverImageInfo['ObjectURL'], 1), true);
-                $info['size'] = $headerArray['Content-Length'];
-                $info['type'] = $headerArray['Content-Type'];
-                $info['time'] = time();
-                $info['image_type'] = 4;
-                break;
-            default:
-                return '上传类型错误,请先选择文件上传类型';
+        $header['Content-Length'] = 0;
+        $header['Content-Type'] = 'image/jpeg';
+        if(!$isData) return $header;
+        try{
+            $header = get_headers(str_replace('\\', '/', UtilService::setHttpType($url, $type)), true);
+            if(!isset($header['Content-Length'])) $header['Content-Length'] = 0;
+            if(!isset($header['Content-Type'])) $header['Content-Type'] = 'image/jpeg';
+        }catch (\Exception $e){
+            $header['Content-Length'] = 0;
+            $header['Content-Type'] = 'image/jpeg';
         }
-        return $info;
+        return $header;
     }
 
     /**
-     * TODO 单图上传 内容
+     * 本地文件上传
+     * @param $fileName
+     * @return array|string
+     */
+    public function uploadLocaFile($fileName)
+    {
+        $file = request()->file($fileName);
+        if (!$file) return '上传文件不存在!';
+        if ($this->autoValidate)
+        {
+            try {
+                validate([$fileName => $this->imageValidate])->check([$fileName => $file]);
+            } catch (ValidateException $e) {
+                return $e->getMessage();
+            }
+        }
+        $fileName = Filesystem::putFile($this->uploadPath, $file);
+        if (!$fileName) return '图片上传失败!';
+        $filePath = Filesystem::path($fileName);
+        $fileInfo = new File($filePath);
+        $url = '/uploads/' . $fileName;
+        return $this->setUploadInfo($url,1,$fileInfo->getFilename(),self::thumb('.'.$url),[
+            'Content-Length'=>$fileInfo->getSize(),
+            'Content-Type'=>$fileInfo->getMime()
+        ]);
+    }
+
+    /**
+     * 本地文件流上传
+     * @param $key
+     * @param $content
+     * @param string $root
+     * @return array|string
+     */
+    public function uploadLocalStream($key, $content,$root='')
+    {
+        $siteUrl = SystemConfigService::get('site_url') . '/';
+        $path = self::uploadDir($this->uploadPath, $root);
+        $path = str_replace('\\', DS, $path);
+        $path = str_replace('/', DS, $path);
+        $dir = $path;
+        if (!self::validDir($dir)) return '生成上传目录失败,请检查权限!';
+        $name = $path . DS . $key;
+        file_put_contents($name, $content);
+        $path = str_replace('\\', '/', $path);
+        $headerArray = self::getImageHeaders($siteUrl .  $path . '/' .$key);
+        $url = '/'.$path . '/' .$key;
+        return $this->setUploadInfo($url,1,$key,$url,$headerArray);
+    }
+
+    /**
+     * TODO 文件流上传
      * @param $key
      * @param $content
-     * @param $path
      * @param null $root
      * @return array|string
      * @throws \Exception
      */
-    public static function imageStream($key, $content, $path, $root = '')
+    public function imageStream($key, $content,$root='')
     {
         $uploadType = SystemConfigService::get('upload_type');
         //TODO 没有选择默认使用本地上传
         if (!$uploadType) $uploadType = 1;
-        $siteUrl = SystemConfigService::get('site_url') . '/';
         $info = [];
         switch ($uploadType) {
             case 1 :
-                self::init();
-                $path = self::uploadDir($path, $root);
-                $path = str_replace('\\', DS, $path);
-                $path = str_replace('/', DS, $path);
-                $dir = $path;
-                if (!self::validDir($dir)) return '生成上传目录失败,请检查权限!';
-                $name = $path . DS . $key;
-                file_put_contents($name, $content);
-                $info["code"] = 200;
-                $info["name"] = $key;
-                $path = str_replace('\\', '/', $path);
-                $info["dir"] = $path . '/' .$key;
-                $info["time"] = time();
-                $headerArray = get_headers(str_replace('\\', '/', UtilService::setHttpType($siteUrl, 1) . $info['dir']), true);
-                $info['size'] = $headerArray['Content-Length'];
-                $info['type'] = $headerArray['Content-Type'];
-                $info["image_type"] = 1;
-                $info['thumb_path'] = '/' . $info['dir'];
-                $info['dir'] = '/' . $info['dir'];
+                $info = $this->uploadLocalStream($key, $content,$root);
+                if(is_string($info)) return $info;
                 break;
             case 2 :
                 $keys = Qiniu::uploadImageStream($key, $content);
@@ -244,10 +352,7 @@ class UploadService
                         if (is_array($item)) {
                             $info = Qiniu::imageUrl($item['key']);
                             $info['dir'] = UtilService::setHttpType($info['dir']);
-                            $headerArray = get_headers(UtilService::setHttpType(str_replace('\\', '/', $info['dir']), 1), true);
-                            $info['size'] = $headerArray['Content-Length'];
-                            $info['type'] = $headerArray['Content-Type'];
-                            $info['image_type'] = 2;
+                            $info = $this->setUploadInfo($info['dir'],2,$item['key'],$info['thumb_path']);
                         }
                     }
                     if (!count($info)) return '七牛云文件上传失败';
@@ -257,70 +362,76 @@ class UploadService
                 $content = COS::resourceStream($content);
                 $serverImageInfo = OSS::uploadImageStream($key, $content);
                 if (!is_array($serverImageInfo)) return $serverImageInfo;
-                $info['code'] = 200;
-                $info['name'] = substr(strrchr($serverImageInfo['info']['url'], '/'), 1);
-                $serverImageInfo['info']['url'] = UtilService::setHttpType($serverImageInfo['info']['url']);
-                $info['dir'] = $serverImageInfo['info']['url'];
-                $info['thumb_path'] = $serverImageInfo['info']['url'];
-                $headerArray = get_headers(UtilService::setHttpType(str_replace('\\', '/', $serverImageInfo['info']['url']), 1), true);
-                $info['size'] = $headerArray['Content-Length'];
-                $info['type'] = $headerArray['Content-Type'];
-                $info['time'] = time();
-                $info['image_type'] = 3;
+                $info = $this->setUploadInfo(UtilService::setHttpType($serverImageInfo['info']['url']),3,substr(strrchr($serverImageInfo['info']['url'], '/'), 1));
                 break;
             case 4 :
                 list($imageUrl,$serverImageInfo) = COS::uploadImageStream($key, $content);
                 if (!is_array($serverImageInfo) && !is_object($serverImageInfo)) return $serverImageInfo;
-                if (is_object($serverImageInfo)) $serverImageInfo = $serverImageInfo->toArray();
-                $serverImageInfo['ObjectURL'] = $imageUrl;
-                $info['code'] = 200;
-                $info['name'] = substr(strrchr($serverImageInfo['ObjectURL'], '/'), 1);
-                $info['dir'] = $serverImageInfo['ObjectURL'];
-                $info['thumb_path'] = $serverImageInfo['ObjectURL'];
-                $headerArray = get_headers(UtilService::setHttpType(str_replace('\\', '/', $serverImageInfo['ObjectURL']), 1), true);
-                $info['size'] = $headerArray['Content-Length'];
-                $info['type'] = $headerArray['Content-Type'];
-                $info['time'] = time();
-                $info['image_type'] = 4;
+                $info = $this->setUploadInfo($imageUrl,4,substr(strrchr($imageUrl, '/'), 1));
                 break;
             default:
-                return '上传类型错误,请先选择文件上传类型';
+                $info = $this->uploadLocalStream($key, $content,$root);
+                if(is_string($info)) return $info;
+                break;
         }
+        $this->uploadPath = '';
+        $this->autoValidate = true;
         return $info;
     }
 
+    /**
+     * 设置返回的数据信息
+     * @param string $url
+     * @param int $imageType
+     * @param string $name
+     * @param string $thumbPath
+     * @return array
+     */
+    protected function setUploadInfo(string $url,int $imageType,string $name = '',string $thumbPath = '',array $headerArray = [])
+    {
+        $headerArray = count($headerArray) ? $headerArray : self::getImageHeaders($url);
+        if(is_array($headerArray['Content-Type']) && count($headerArray['Content-Length']) == 2){
+            $headerArray['Content-Length'] = $headerArray['Content-Length'][1];
+        }
+        if(is_array($headerArray['Content-Type']) && count($headerArray['Content-Type']) == 2){
+            $headerArray['Content-Type'] = $headerArray['Content-Type'][1];
+        }
+        $info = [
+            'name' => str_replace('\\','/',$name ? : $url),
+            'dir'  => str_replace('\\','/',$url),
+            'size' => $headerArray['Content-Length'],
+            'type' => $headerArray['Content-Type'],
+            'time' => time(),
+            'thumb_path' => str_replace('\\','/',$thumbPath ? : $url),
+            'image_type' => $imageType,
+        ];
+        $uploadInfo = array_merge($this->uploadInfo,$info);
+        return $uploadInfo;
+    }
+
     /**
      * 文件上传
      * @param string $fileName 上传文件名
-     * @param string $path 上传路径
-     * @param bool $moveName 生成文件名
-     * @param string $autoValidate 验证规则 [size:1024,ext:[],type:[]]
-     * @param null $root 上传根目录路径
-     * @param string $rule 文件名自动生成规则
      * @return mixed
      */
-    public static function file($fileName, $path, $moveName = true, $autoValidate = '', $root = null, $rule = 'uniqid')
+    public function file($fileName)
     {
-        self::init();
-//        $path = self::uploadDir($path, $root);
-//        $dir = $path;
-//        if (!self::validDir($dir)) return self::setError('生成上传目录失败,请检查权限!');
         if (!isset($_FILES[$fileName])) return self::setError('上传文件不存在!');
         $extension = strtolower(pathinfo($_FILES[$fileName]['name'], PATHINFO_EXTENSION));
         if (strtolower($extension) == 'php' || !$extension)
             return self::setError('上传文件非法!');
         $file = request()->file($fileName);
-        if ($autoValidate) {
+        if ($this->autoValidate)
+        {
             try {
-                validate([$fileName => self::$imageValidate])->check([$fileName => $file]);
+                validate([$fileName => $this->imageValidate])->check([$fileName => $file]);
             } catch (ValidateException $e) {
                 return self::setError($e->getMessage());
             }
         };
-        $fileName = Filesystem::putFile($path, $file);
-        if (!$fileName)
-            return self::setError('图片上传失败!');
-        return self::successful($fileName);
+        $fileName = Filesystem::putFile($this->uploadPath, $file);
+        if (!$fileName) return self::setError('图片上传失败!');
+        return self::successful(str_replace('\\','/',$fileName));
     }
 
     public static function pathToUrl($path)
@@ -328,7 +439,7 @@ class UploadService
         return trim(str_replace(DS, '/', $path), '.');
     }
 
-    public static function openImage($filePath)
+    public function openImage($filePath)
     {
         return \think\Image::open($filePath);
     }
@@ -342,9 +453,9 @@ class UploadService
      * @param string $pre 前缀
      * @return string 压缩图片路径
      */
-    public static function thumb($filePath, $ratio = 5, $pre = 's_')
+    public function thumb($filePath, $ratio = 5, $pre = 's_')
     {
-        $img = self::openImage($filePath);
+        $img = $this->openImage($filePath);
         $width = $img->width() * $ratio / 10;
         $height = $img->height() * $ratio / 10;
         $dir = dirname($filePath);
@@ -354,4 +465,9 @@ class UploadService
         if(substr($savePath, 0, 2) == './') return substr($savePath, 1, strlen($savePath));
         return DS . $savePath;
     }
+
+    protected function __clone()
+    {
+        // TODO: Implement __clone() method.
+    }
 }

+ 112 - 80
crmeb/crmeb/services/UtilService.php

@@ -10,12 +10,20 @@ namespace crmeb\services;
 use crmeb\services\storage\COS;
 use crmeb\services\storage\OSS;
 use crmeb\services\storage\Qiniu;
+use think\Exception;
 use think\facade\Config;
 use dh2y\qrcode\QRcode;
 
 class UtilService
 {
 
+    /**
+     * 获取POST请求的数据
+     * @param $params
+     * @param null $request
+     * @param bool $suffix
+     * @return array
+     */
     public static function postMore($params,$request = null,$suffix = false)
     {
         if($request === null) $request = app('request');
@@ -34,6 +42,13 @@ class UtilService
         return $p;
     }
 
+    /**
+     * 获取请求的数据
+     * @param $params
+     * @param null $request
+     * @param bool $suffix
+     * @return array
+     */
     public static function getMore($params,$request=null,$suffix = false)
     {
         if($request === null) $request = app('request');
@@ -138,6 +153,11 @@ class UtilService
         return app()->getRootPath().$path;
     }
 
+    /**
+     * 时间戳人性化转化
+     * @param $time
+     * @return string
+     */
     public static function timeTran($time)
     {
         $t = time() - $time;
@@ -486,7 +506,7 @@ class UtilService
         $res = ob_get_contents();
         ob_end_clean();
         $key = substr(md5(rand(0, 9999)) , 0, 5). date('YmdHis') . rand(0, 999999) . '.jpg';
-        return UploadService::imageStream($key,$res,$path);
+        return UploadService::getInstance()->setUploadPath($path)->imageStream($key,$res);
     }
 
     /*
@@ -538,11 +558,11 @@ class UtilService
         return $siteUrl.$image;
     }
 
-
-    /*
+    /**
      * CURL 检测远程文件是否在
-     *
-     * */
+     * @param $url
+     * @return bool
+     */
     public static function CurlFileExist($url)
     {
         $ch = curl_init();
@@ -569,78 +589,83 @@ class UtilService
     public static function getQRCodePath($url, $name)
     {
         if(!strlen(trim($url)) || !strlen(trim($name))) return false;
-        $uploadType = SystemConfigService::get('upload_type');
-        //TODO 没有选择默认使用本地上传
-        if (!$uploadType) $uploadType = 1;
-        $siteUrl = SystemConfigService::get('site_url') ?: '.';
-        $info = [];
-        $outfile = Config::get('qrcode.cache_dir');
-
-        $code = new QRcode();
-        $wapCodePath = $code->png($url, $outfile.'/'.$name)->getPath(); //获取二维码生成的地址
-        $content = file_get_contents('.'.$wapCodePath);
-        switch ($uploadType) {
-            case 1 :
-                $info["code"] = 200;
-                $info["name"] = $name;
-                $info["dir"] = $wapCodePath;
-                $info["time"] = time();
-                $headerArray = get_headers(UtilService::setHttpType($siteUrl, 1) . $info['dir'],true);
-                $info['size'] = $headerArray['Content-Length'];
-                $info['type'] = $headerArray['Content-Type'];
-                $info["image_type"] = 1;
-                $info['thumb_path'] = $wapCodePath;
-                break;
-            case 2 :
-                $keys = Qiniu::uploadImageStream($name, $content);
-                if (is_array($keys)) {
-                    foreach ($keys as $key => &$item) {
-                        if (is_array($item)) {
-                            $info = Qiniu::imageUrl($item['key']);
-                            $info['dir'] = UtilService::setHttpType($info['dir']);
-                            $headerArray = get_headers(UtilService::setHttpType(str_replace('\\', '/', $info['dir']), 1), true);
-                            $info['size'] = $headerArray['Content-Length'];
-                            $info['type'] = $headerArray['Content-Type'];
-                            $info['image_type'] = 2;
+        try{
+            $uploadType = SystemConfigService::get('upload_type');
+            //TODO 没有选择默认使用本地上传
+            if (!$uploadType) $uploadType = 1;
+            $siteUrl = SystemConfigService::get('site_url');
+            if(!$siteUrl) return '请前往后台设置->系统设置->网站域名 填写您的域名格式为:http://域名';
+            $info = [];
+            $outfile = Config::get('qrcode.cache_dir');
+
+            $code = new QRcode();
+            $wapCodePath = $code->png($url, $outfile.'/'.$name)->getPath(); //获取二维码生成的地址
+            $content = file_get_contents('.'.$wapCodePath);
+            switch ($uploadType) {
+                case 1 :
+                    $info["code"] = 200;
+                    $info["name"] = $name;
+                    $info["dir"] = $wapCodePath;
+                    $info["time"] = time();
+                    $headerArray=UploadService::getImageHeaders($siteUrl.$info['dir'],1,false);
+                    $info['size'] = $headerArray['Content-Length'];
+                    $info['type'] = $headerArray['Content-Type'];
+                    $info["image_type"] = 1;
+                    $info['thumb_path'] = $wapCodePath;
+                    break;
+                case 2 :
+                    $keys = Qiniu::uploadImageStream($name, $content);
+                    if (is_array($keys)) {
+                        foreach ($keys as $key => &$item) {
+                            if (is_array($item)) {
+                                $info = Qiniu::imageUrl($item['key']);
+                                $info['dir'] = UtilService::setHttpType($info['dir']);
+                                $headerArray = UploadService::getImageHeaders( $info['dir']);
+                                $info['size'] = $headerArray['Content-Length'];
+                                $info['type'] = $headerArray['Content-Type'];
+                                $info['image_type'] = 2;
+                            }
                         }
-                    }
-                    if (!count($info)) return '七牛云文件上传失败';
-                } else return $keys;
-                break;
-            case 3 :
-                $content = COS::resourceStream($content);
-                $serverImageInfo = OSS::uploadImageStream($name, $content);
-                if (!is_array($serverImageInfo)) return $serverImageInfo;
-                $info['code'] = 200;
-                $info['name'] = substr(strrchr($serverImageInfo['info']['url'], '/'), 1);
-                $serverImageInfo['info']['url'] = UtilService::setHttpType($serverImageInfo['info']['url']);
-                $info['dir'] = $serverImageInfo['info']['url'];
-                $info['thumb_path'] = $serverImageInfo['info']['url'];
-                $headerArray = get_headers(UtilService::setHttpType(str_replace('\\', '/', $serverImageInfo['info']['url']), 1), true);
-                $info['size'] = $headerArray['Content-Length'];
-                $info['type'] = $headerArray['Content-Type'];
-                $info['time'] = time();
-                $info['image_type'] = 3;
-                break;
-            case 4 :
-                list($imageUrl,$serverImageInfo) = COS::uploadImageStream($name, $content);
-                if (!is_array($serverImageInfo) && !is_object($serverImageInfo)) return $serverImageInfo;
-                if (is_object($serverImageInfo)) $serverImageInfo = $serverImageInfo->toArray();
-                $serverImageInfo['ObjectURL'] = $imageUrl;
-                $info['code'] = 200;
-                $info['name'] = substr(strrchr($serverImageInfo['ObjectURL'], '/'), 1);
-                $info['dir'] = $serverImageInfo['ObjectURL'];
-                $info['thumb_path'] = $serverImageInfo['ObjectURL'];
-                $headerArray = get_headers(UtilService::setHttpType(str_replace('\\', '/', $serverImageInfo['ObjectURL']), 1), true);
-                $info['size'] = $headerArray['Content-Length'];
-                $info['type'] = $headerArray['Content-Type'];
-                $info['time'] = time();
-                $info['image_type'] = 4;
-                break;
-            default:
-                return '上传类型错误,请先选择文件上传类型';
+                        if (!count($info)) return '七牛云文件上传失败';
+                    } else return $keys;
+                    break;
+                case 3 :
+                    $content = COS::resourceStream($content);
+                    $serverImageInfo = OSS::uploadImageStream($name, $content);
+                    if (!is_array($serverImageInfo)) return $serverImageInfo;
+                    $info['code'] = 200;
+                    $info['name'] = substr(strrchr($serverImageInfo['info']['url'], '/'), 1);
+                    $serverImageInfo['info']['url'] = UtilService::setHttpType($serverImageInfo['info']['url']);
+                    $info['dir'] = $serverImageInfo['info']['url'];
+                    $info['thumb_path'] = $serverImageInfo['info']['url'];
+                    $headerArray = UploadService::getImageHeaders($serverImageInfo['info']['url'],1,true);
+                    $info['size'] = $headerArray['Content-Length'];
+                    $info['type'] = $headerArray['Content-Type'];
+                    $info['time'] = time();
+                    $info['image_type'] = 3;
+                    break;
+                case 4 :
+                    list($imageUrl,$serverImageInfo) = COS::uploadImageStream($name, $content);
+                    if (!is_array($serverImageInfo) && !is_object($serverImageInfo)) return $serverImageInfo;
+                    if (is_object($serverImageInfo)) $serverImageInfo = $serverImageInfo->toArray();
+                    $serverImageInfo['ObjectURL'] = $imageUrl;
+                    $info['code'] = 200;
+                    $info['name'] = substr(strrchr($serverImageInfo['ObjectURL'], '/'), 1);
+                    $info['dir'] = $serverImageInfo['ObjectURL'];
+                    $info['thumb_path'] = $serverImageInfo['ObjectURL'];
+                    $headerArray = UploadService::getImageHeaders( $serverImageInfo['ObjectURL'],true);
+                    $info['size'] = $headerArray['Content-Length'];
+                    $info['type'] = $headerArray['Content-Type'];
+                    $info['time'] = time();
+                    $info['image_type'] = 4;
+                    break;
+                default:
+                    return '上传类型错误,请先选择文件上传类型';
+            }
+            return $info;
+        }catch (\Exception $e){
+            return $e->getMessage();
         }
-        return $info;
     }
 
     /**
@@ -648,18 +673,26 @@ class UtilService
      * @param string $avatar
      * @return bool|string
      */
-    public static function setImageBase64($avatar = '',$timeout=15){
+    public static function setImageBase64($avatar = '',$timeout=9){
         try{
-            $header = array(
+            $url=parse_url($avatar);
+            $url=$url['host'];
+            $header = [
                 'User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:45.0) Gecko/20100101 Firefox/45.0',
                 'Accept-Language: zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3',
-                'Accept-Encoding: gzip, deflate',);
+                'Accept-Encoding: gzip, deflate',
+                'Host:'.$url
+            ];
+            $dir= pathinfo($url);
+            $host = $dir['dirname'];
+            $refer= $host.'/';
             $curl = curl_init();
+            curl_setopt($curl, CURLOPT_REFERER, $refer);
             curl_setopt($curl, CURLOPT_URL, $avatar);
             curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
             curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true);
             curl_setopt($curl, CURLOPT_ENCODING, 'gzip');
-            curl_setopt($curl, CURLOPT_TIMEOUT, $timeout);
+            curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, $timeout);
             curl_setopt($curl, CURLOPT_HTTPHEADER, $header);
             $data = curl_exec($curl);
             $code = curl_getinfo($curl, CURLINFO_HTTP_CODE);
@@ -669,7 +702,6 @@ class UtilService
         }catch (\Exception $e){
             return false;
         }
-
     }
 
 

+ 0 - 0
crmeb/crmeb/services/WechatService.php


이 변경점에서 너무 많은 파일들이 변경되어 몇몇 파일들은 표시되지 않았습니다.